使用Maven编译简单的Java 10 / Java 11项目时出现问题,无法编译。

181

我有一个简单的Maven项目:

src
└── main
    └── java
        └── module-info.java
pom.xml

pom.xml:

<groupId>org.example</groupId>
<artifactId>example</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>example</name>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.7.0</version>
            <configuration>
                <release>10</release>
            </configuration>
        </plugin>
    </plugins>
</build>

当我通过mvn -X install -DskipTests=true构建项目时,它会失败:
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.7.0:testCompile (default-testCompile) on project example: Execution default-testCompile of goal org.apache.maven.plugins:maven-compiler-plugin:3.7.0:testCompile failed.
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:213)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:154)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:146)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81)
        at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
        at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:309)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:194)
        at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:107)
        at org.apache.maven.cli.MavenCli.execute(MavenCli.java:993)
        at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:345)
        at org.apache.maven.cli.MavenCli.main(MavenCli.java:191)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:564)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
        at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
        at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
Caused by: org.apache.maven.plugin.PluginExecutionException: Execution default-testCompile of goal org.apache.maven.plugins:maven-compiler-plugin:3.7.0:testCompile failed.
        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:145)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
        ... 20 more
Caused by: java.lang.IllegalArgumentException
        at org.objectweb.asm.ClassReader.<init>(Unknown Source)
        at org.objectweb.asm.ClassReader.<init>(Unknown Source)
        at org.objectweb.asm.ClassReader.<init>(Unknown Source)
        at org.codehaus.plexus.languages.java.jpms.AsmModuleInfoParser.parse(AsmModuleInfoParser.java:80)
        at org.codehaus.plexus.languages.java.jpms.AsmModuleInfoParser.getModuleDescriptor(AsmModuleInfoParser.java:54)
        at org.codehaus.plexus.languages.java.jpms.LocationManager.resolvePaths(LocationManager.java:83)
        at org.apache.maven.plugin.compiler.TestCompilerMojo.preparePaths(TestCompilerMojo.java:281)
        at org.apache.maven.plugin.compiler.AbstractCompilerMojo.execute(AbstractCompilerMojo.java:762)
        at org.apache.maven.plugin.compiler.TestCompilerMojo.execute(TestCompilerMojo.java:176)
        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
        ... 21 more

有方法可以解决这个问题吗?


1
@MikhailKholodkov,该漏洞已得到解决,现在可以使用maven-compiler-plugin:3.8.0来修复上述错误(https://dev59.com/MlUM5IYBdhLWcg3wCs1Z#51586202)。 - Naman
11个回答

263
截至2018年7月30日,为了解决上述问题,可以在maven中配置使用任何JDK/11版本的java,并使用maven-compiler-plugin:3.8.0指定9、10、11版本的发布,而不需要明确的依赖关系。
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.0</version>
    <configuration>
        <release>11</release>  <!--or <release>10</release>-->
    </configuration>
</plugin>

注意:本版本将源/目标的默认值从1.5提高到了1.6。 -- 发布说明。


编辑 [2018年12月30日]

实际上,您可以在使用JDK/12编译代码时,仍然利用同一版本的maven-compiler-plugin

有关如何使用Maven编译和执行JDK预览功能的更多详细信息和示例配置。


8
只有在使用Java 11执行maven时,才能直接运行此操作。如果您的平台Java版本是例如Java 8(因此maven是使用Java 8执行的),则需要定义一个工具链 https://maven.apache.org/guides/mini/guide-using-toolchains.html - Franz Deschler
9
请注意,相关属性为maven.compiler.release:<properties><maven.compiler.release>11</maven.compiler.release></properties> - Olivier Grégoire
@OlivierGrégoire - 所以,我们可以用你提供的代码替换这段代码吗?<properties> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.source>1.8</maven.compiler.source> </properties> - MasterJoe
1
@MasterJoe2 如果你升级到Java-11,那么你应该能够做到这一点。 - Naman
1
请注意:您必须使用与发布目标版本和源目标版本相等或更高的Java版本来运行Maven。 - MiguelMunoz

144

更新

现在的答案已经过时,请参阅此回答


maven-compiler-plugin 依赖于旧版本的ASM,该版本尚不支持Java 10(和Java 11)。但是,可以明确指定正确的ASM版本:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.7.0</version>
    <configuration>
        <release>10</release>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>org.ow2.asm</groupId>
            <artifactId>asm</artifactId>
            <version>6.2</version> <!-- Use newer version of ASM -->
        </dependency>
    </dependencies>
</plugin>
您可以在https://search.maven.org/search?q=g:org.ow2.asm%20AND%20a:asm&core=gav找到最新版本。

38

可能不是完全相同的错误,但我遇到了类似的错误。

检查Maven Java版本

由于Maven也是使用Java运行的,请首先检查Maven正在运行的Java版本:

mvn --version | grep -i java 

它返回:

Java版本1.8.0_151,厂商:Oracle Corporation,运行时:C:\tools\jdk\openjdk1.8

不兼容的版本

在这里,我的Maven正在使用 Java版本1.8.0_151。 因此,即使我指定Maven使用 Java 11 进行编译:

<properties>
    <java.version>11</java.version>
    <maven.compiler.source>${java.version}</maven.compiler.source>
    <maven.compiler.target>${java.version}</maven.compiler.target>
</properties>

它将逻辑地打印出以下错误:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project efa-example-commons-task: Fatal error compiling: invalid target release: 11 -> [Help 1]

如何为 Maven 设置特定的 Java 版本

逻辑上应该将 Maven 的 Java 版本设为较高版本(例如,Java 11 而非 1.8)。

Maven 使用环境变量 JAVA_HOME 来查找要运行的 Java 版本。因此,请将此变量更改为您想要编译的 JDK(例如,OpenJDK 11)。

检查配置是否正确

然后再次运行mvn --version,以确保已处理好配置:

mvn --version | grep -i java

产生

Java版本:11.0.2,供应商:Oracle Corporation,运行时:C:\tools\jdk\openjdk11

这对于编译使用Java 11规范编写的代码来说更好且正确。


2
这对我有用,即使使用maven-assembly-plugin版本3.2.0也是如此。 - Gérard Binkhorst

31

指定maven.compiler.source和target版本。

1)使用您所使用的jdk支持的Maven版本。在我的情况下,是JDK 11和maven 3.6.0。

2)pom.xml

<properties>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
</properties>

作为一种替代方案,您可以完全指定maven编译器插件。请参阅以前的答案。在我的例子中它更短 :)

作为替代,您可以完全指定Maven编译器插件。请参见之前的回答。在我的示例中,这样做更简短 :)

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.0</version>
            <configuration>
                <release>11</release>
            </configuration>
        </plugin>
    </plugins>
</build>

3) 重建项目以避免IDE编译错误。

4) 如果仍无法工作。在Intellij Idea中,我更喜欢使用终端而不是来自操作系统的终端。然后在Idea中转到文件 ->设置 ->构建工具 ->Maven。我使用了从Apache下载的maven(默认情况下,Idea使用捆绑的maven)。然后重新启动Idea并再次运行mvn clean install。还要确保您有正确的 Path MAVEN_HOME JAVA_HOME 环境变量。

我还看到了这个一行代码,但它不起作用。

<maven.compiler.release>11</maven.compiler.release>

我创建了一些快速启动项目,我在其他项目中重复使用它们,随时可以查看:


27

将您的 maven-compiler-plugin 提升至 3.8.0 似乎是必要的,但并不足够。如果您仍然遇到问题,则还需要确保您的 JAVA_HOME 环境变量设置为 Java 10(或11),如果您是从命令行运行,则需要这样做。(您收到的错误消息不会告诉您这一点。)或者,如果您正在从IDE运行,则需要确保它设置为使用当前JDK运行maven。


5
如果您正在使用Spring Boot,则需要在pom.xml文件中添加以下标签。
<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
</plugin>

并且
<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    `<maven.compiler.release>`10</maven.compiler.release>
</properties>

您可以通过更改 <maven.compiler.release> 标签中的 Java 版本为 11 或者 13。

只需在 pom.xml 文件中添加以下标签即可。

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <maven.compiler.release>11</maven.compiler.release>
</properties>

你可以将11和13改为10来更改Java版本。我正在使用最新的Java 13,它适合我。


1

mvn可能正在使用JAVA_HOME,但如果设置它不起作用,则实际的mvn脚本中可能会有覆盖。

例如,在我的系统(mac)上,mvn指向/usr/local/bin/mvn,实际上指向/usr/local/Cellar/maven/3.8.6/bin/mvn,这是一个bash脚本,指向/usr/local/Cellar/maven/3.8.6/libexec/bin/mvn,该脚本在顶部读取如下:

if [ -z "$MAVEN_SKIP_RC" ] ; then

  if [ -f /usr/local/etc/mavenrc ] ; then
    . /usr/local/etc/mavenrc
  fi

  if [ -f /etc/mavenrc ] ; then
    . /etc/mavenrc
  fi

  if [ -f "$HOME/.mavenrc" ] ; then
    . "$HOME/.mavenrc"
  fi

fi

因此,它显示正在寻找3个不同的位置的环境变量,除非设置了MAVEN_SKIP_RC

如果运行MAVEN_SKIP_RC=1 mvn -version,现在会考虑到JAVA_HOME。

但真正的解决方法是找出mavenrc文件中的罪魁祸首。

在我的情况下,唯一存在的文件是/etc/mavenrc,它的内容为:

JAVA_HOME=$(/usr/libexec/java_home -v 1.8)

所以它将java 1.8设置为默认值,覆盖了原始的JAVA_HOME。

将其更改为-v 11,它将按预期工作。 或者完全删除/etc/mavenrc,以恢复默认值为JAVA_HOME值。


1
在我的情况下,尽管终端显示 Java 11 版本,但我还是需要在脚本中明确设置 JAVA_HOME 为 JDK-11。
这是因为,我通过 shell 脚本执行 mvn,而且 mvn 使用的是我的机器上默认的 JDK8。
我确认了在脚本中使用的 mvn 的 JDK 版本,并将其设置为 JDK-11,如下所示:
#!/bin/bash
echo $(java -version)
echo $(mvn --version | grep -i java )

export JAVA_HOME="/opt/jdk11/"
export PATH=$JAVA_HOME/bin:$PATH

echo $(java -version)
echo $(mvn --version | grep -i java )

0
在我的情況中,
  • 「echo $JAVA_HOME」顯示版本為11
  • 「java -version」顯示版本為11
  • 然而,「mvn -version」顯示「Java version」不是11
我將這段貼在 .bash_profile 的頂部並執行 source,這樣就可以了。
export JAVA_8_HOME=$(/usr/libexec/java_home -v1.8)
export JAVA_11_HOME=$(/usr/libexec/java_home -v11)

alias java8='export JAVA_HOME=$JAVA_8_HOME;export PATH=$HOME/bin:$JAVA_HOME/bin:$PATH'
alias java11='export JAVA_HOME=$JAVA_11_HOME;export PATH=$HOME/bin:$JAVA_HOME/bin:$PATH'

java11


0

好的,对我来说没有什么起作用的方式。

我正在使用带有Hibernate的Spring Boot。 Spring Boot版本为~2.0.1,在编译时我会遇到错误和空指针异常。问题出在Hibernate需要升级版本。但升级后,我还有其他问题,似乎注释处理器未被识别,所以我决定将Spring从2.0.1升级到了2.1.7-release,一切都按预期运行。

你仍然需要添加上述插件。
希望能帮到你!


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