【问题标题】:Strange compiler behaviour in multi module project多模块项目中的奇怪编译器行为
【发布时间】:2018-08-07 16:29:08
【问题描述】:

我有以下项目结构(在 Windows 10 x64 上):

root-folder: containing parent pom, defining 1.8 for build and group/version, listing sub1, sub2, sub3 as modules
sub1: first module (jar), refering to parent pom
sub2: second module (jar), refering to parent pom, sub1 as dependency
sub3: third module (jar), refering to parent pom, sub2 as dependency

现在,当我按照上面声明的顺序在每个模块中分别执行mvn clean install 时,一切正常。

但是,当我在父 pom 上执行 mvn clean install 时,sub1 和 sub2 构建良好,而在 sub3 中,我得到了不祥的构建错误

An exception has occurred in the compiler (1.8.0_181). Please file a bug against the Java compiler via the Java bug reporting page [..]
java.lang.IllegalAccessError: tried to access class com.sun.tools.javac.tree.JCTree$1 from class com.sun.tools.javac.tree.JCTree$JCLiteral
        at com.sun.tools.javac.tree.JCTree$JCLiteral.getValue(JCTree.java:2044)
        at com.sun.tools.javac.parser.JavacParser.merge(JavacParser.java:1034)
[..]

我更新到最新的 JDK 8 和 Maven,但仍然是同样的错误。我确认 JAVA_HOME 和 PATH 设置正确(因为系统上确实有更新的 JDK)。我还通过 MAVEN_OPTS 增加了 Maven 的内存,但也没有变化。

有没有人有过类似的行为并且可以向我展示一个解决方案或至少提出一个想法是什么可能导致这种情况?手动编译每一个或让maven编译有什么不同?依赖关系可能是一个问题,还是我自己的代码中更有可能出现问题?

【问题讨论】:

标签: java maven multi-module


【解决方案1】:

执行一项额外的测试以确认问题。从根目录运行mvn clean install -pl :sub3 -am。如果构建失败并出现相同的编译器错误,那么您确认它的行为与根目录和 sub3 模块不同。

根据https://github.com/ztellman/virgil/issues/16 和一些类似的问题,这可能是由依赖关系引起的,例如Lombok 在不受支持的版本中生成字节码。

通过以两种不同的方式运行mvn dependency:tree 来比较已解析的 Maven 依赖项:

  1. 从项目根目录查看编译失败的sub3模块的依赖树。

  2. 直接在sub3模块中。

如果它们不同,请确定不同的库或依赖版本。

如果这不起作用,请隔离在每个 Maven 模块中执行的编译器任务。这可以通过设置Maven Compiler Plugin compile:compile properties

 maven.compiler.compilerReuseStrategy=alwaysNew
 maven.compiler.fork=true

【讨论】:

  • 感谢您的建议。我确认,如您首先所说,使用离散模块列表从根目录构建它会导致相同的编译错误。关于依赖树,这两种方法都是一样的。那么现在这意味着什么?
  • @AlexanderRühl 你能用maven.compiler.compilerReuseStrategy=alwaysNewmaven.compiler.fork=true 属性集进行测试吗?尝试隔离javac 编译器的任何其他选项。
  • 好的,我想我可以识别问题,我偶然发现了它,在尝试使用 JDK 9 的建议时,然后显示,我在 sub2 中有一个分析字节码的插件是问题.不过,我不明白在构建 sub2 时这会以何种方式影响 sub3,知道吗?
  • @AlexanderRühl 很可能会污染运行 Maven 的 JVM,因此sub2 之后的每个模块都会失败。尝试使用我建议的选项来防止编译器重用和分叉,这样每个模块都会以构建时间为代价获得新的编译器。
  • 您对编译器隔离属性的建议有效,因此即使使用插件,它现在也可以从父级工作。非常感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多