java - 多模块项目中的奇怪编译器行为

标签 java maven multi-module

我有以下项目结构(在 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 编译有什么不同?依赖项可能是个问题还是更有可能是我自己的代码中的问题?

最佳答案

执行一项附加测试以确认问题。从根目录运行 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

关于java - 多模块项目中的奇怪编译器行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51731485/

相关文章:

java - Wicket 标记继承不适用于 wicket :child tags within MarkupContainers

Maven - 将某些资源文件从默认的 src/main/resources 位置排除到 WAR 中

java - 在 gradle 中构建具有两个或多个根的多模块项目

scala - 为什么 sbt 构建失败并显示 "MissingRequirementError: object scala.runtime in compiler mirror not found."?

java - 从 ActiveAndroid 切换到 GreenDao

javascript - 如何从java读取Bookmarklet?

java - 使用 Hibernate envers 查找最近删除的实体

java - 将父版本外部化为 POM 中的变量

java - 从头开始构建Eclipse IDE-如何通过JDT选择CDT?

java - Spring Boot api、接口(interface)和实现的独立模块