在Java中是否有可能强制执行包依赖关系层次结构?

3
基本上我有一些包...
com.me.application
com.me.application.thing
com.me.library

我希望强制执行一个规则,即 com.me.application 中的任何内容都不能包含 com.me.library,除了在 com.me.application.thing 中的内容。

在Java代码、Maven、类路径或其他与C语言中链接大致相当的Java层面上,是否可能实现这一点?


4个回答

4

不要试图强制编译器这样做,为什么不使用源代码分析呢?

我建议使用现在嵌入在Sonar中的架构规则引擎。结合构建破坏者插件,您可以触发构建失败,如果开发人员违反了您的层次结构规则。


3

2
我能想到的唯一方法是通过AspectJ
AspectJ是一种面向方面的语言,可通过单独的编译过程将交叉关注点添加到应用程序中。 AspectJ的经典用途之一是策略执行,这符合您的情况。
基本上,您声明规则,决定哪个包可以调用哪个代码,并在遇到违反这些规则的方法调用(或在您的情况下变量声明)时抛出编译错误。您可以在优秀的书籍AspectJ in Action中了解详细信息。
通过AspectJ插件,可以将AspectJ很好地集成到Maven构建中。
如果仅将AspectJ用于策略执行,则不会有任何附加的运行时依赖项,因为您的字节码不会被修改。

0

您需要通过单独的Maven项目构建com.me.application、com.me.application.thing和com.me.library,每个项目都会构建一个jar文件。com.me.application的pom文件不会包含对com.me.library的依赖,而com.me.application.thing的pom文件将包含对com.me.library的依赖。

但这是一种奇怪的包结构。为什么要防止这种情况发生呢?


1
这并不是一个奇怪的结构,它确保库的使用被隔离在应用程序的一小部分中,而不是散布在整个代码中。肯定希望有一个解决方案,不需要深入到物理构建结构中去。 - djechlin
1
我觉得这很奇怪,因为其中一个是另一个的子包。请注意,Maven解决方案仅防止构建时依赖关系。如果你的团队中有一些不守规矩的开发人员,在运行时使用反射仍然是可能的。 - jalynn2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接