3

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?

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
djechlin
  • 59,258
  • 35
  • 162
  • 290
  • similar question: [Restrict dependencies between Java packages](https://stackoverflow.com/questions/149294) – ESV Aug 22 '20 at 13:29

4 Answers4

4

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.

Mark O'Connor
  • 76,015
  • 10
  • 139
  • 185
3

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.

Saish
  • 1,518
  • 1
  • 12
  • 21
2

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.

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
0

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?

jalynn2
  • 6,397
  • 2
  • 16
  • 15
  • 1
    It's not a strange structure at all, it's ensuring that use of library is isolated in a small part of application instead of being glittered throughout the code. Definitely hoping for a solution that doesn't go that deep into the physical build structure. – djechlin Sep 27 '12 at 14:51
  • 1
    I guess i found it to be strange because one is a subpackage of the other. Note that The Maven solution is only preventing build-time dependencies. It won't stop someone from using reflection at run-time if you have some scofflaw developers in your midst. – jalynn2 Sep 27 '12 at 15:07