Basically I have packages...
com.me.application
com.me.application.thing
com.me.library
I want to enforce the rule that nothing in com.me.application
can include com.me.library
, except things in com.me.application.thing
.
Is this possible at the level of Java code, Maven, classpath, or any other layer of Java that would be roughly equivalent to linking in C?
You can enforce the checks with Checkstyle's import control rule. Configure the Maven Checkstyle plugin into your pom.xml, and any violations can be set to cause the build to fail.
The only way that I can think of is through AspectJ.
AspectJ is an aspect oriented language, that is used to add cross-cutting concerns into your application through a separate compile process. One of the classical uses of AspectJ is policy enforcement, which fits your scenario.
Basically you declare rules that decide from which package which code may be called and throw a compile error whenever you encounter a method call (or in your case a variable declaration) that violates these rules. You can learn the details in the excellent book AspectJ in Action
AspectJ can nicely be integrated into a Maven build through the AspectJ plugin
And if you use AspectJ only for policy enforcement, you won't have any additional runtime dependencies, as your byte code won't be modified.
Instead of trying to force the compiler to do it, why not use source code analysis instead?
I would recommend using the architecture rules engine that is now embedded in Sonar. Combine this with the build breaker plugin and you can trigger a build failure, if developers breach your hierarchy rules.
You would need to build com.me.application, com.me.application.thing and com.me.library via separate maven projects that each build a jar file. the pom for com.me.application would not include a dependency to com.me.library, and the pom for com.me.application.thing would include a dependency for com.me.library.
But this is a strange package structure. Why do you want to prevent this?