当前位置: 首页 > 知识库问答 >
问题:

在maven中指定Java版本-属性和编译器插件之间的区别

秦凯定
2023-03-14

我对maven不是很有经验,在尝试多模块项目的时候,我开始想如何在父maven POM中为所有子模块指定Java版本。直到今天我一直在用:

<properties>
    <java.version>1.8</java.version>
</properties>

但是在研究的时候我发现你也可以在maven编译器插件中指定Java版本,像这样:

<plugins>
    <plugin>    
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
            <source>1.8</source>
            <target>1.8</target>
        </configuration>
    </plugin>
</plugins>

然后将其包装到插件管理标记中,以启用子poms对其的使用。所以第一个问题是在属性和maven编译器插件中设置Java版本有什么区别?

我找不到明确的答案,但在研究的过程中,我发现你也可以这样指定Java版本:

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

这表明即使我没有显式声明编译器插件也存在。运行mvn包输出

maven-compiler-plugin:3.1:compile (default-compile) @ testproj ---

和其他一些我没有声明的插件。那么这些插件是maven POM的默认隐藏部分吗?在属性中设置源/目标和在maven插件配置元素中设置源/目标有什么区别吗?

其他一些问题是--应该使用哪种方式(如果它们不相等的话,什么时候使用)?哪个最适合多模块项目,如果pom中指定的Java版本与JAVA_HOME中指定的版本不同,会发生什么?

共有1个答案

昌招
2023-03-14

如何指定JDK版本?

使用以下三种方法:(1)spring boot特性,或使用Maven编译器插件(2)目标或(3)发布

>

  • 在Maven文档中没有引用。
    这是spring boot特有的特性。
    它允许将源和目标Java版本设置为相同的版本,例如这个版本,从而为两者指定Java 1.8:

    如果你用的是spring boot,那就随便用吧。

    这的确是:

    <plugins>
        <plugin>    
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
    

    相当于:

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

    根据编译器插件的Maven文档,编译器配置中的 元素使用属性Maven.compiler.sourceMaven.compiler.target(如果已定义)。

    来源

    Java编译器的-source参数。
    默认值为:1.6
    用户属性为:maven.compiler.source

    目标

    Java编译器的-target参数。
    默认值为:1.6
    用户属性为:maven.compiler.target

    关于sourcetarget的默认值,请注意,自从maven编译器的3.8.0以来,默认值已从1.5更改为1.6

    maven-compiler-plugin3.6和更高版本提供了一种新的方法:

    您还可以声明:

    <properties>
        <maven.compiler.release>9</maven.compiler.release>
    </properties>
    

    但此时它将无法工作,因为您使用的maven-compiler-plugin默认版本不依赖于足够新的版本。

    Mavenrelease参数传达了release:一个新的JVM标准选项,我们可以从Java 9:

    针对特定VM版本的公共的、支持的和文档化的API进行编译。

    这种方法提供了一种为目标引导JVM选项指定相同版本的标准方法。
    注意,指定引导是交叉编译的好方法,如果您不进行交叉编译,也不会有坏处。

    哪种方法是指定JDK版本的最佳方法?

    第一种方式( )只有在使用spring boot时才允许使用。

    对于Java 8级及以下级别:

    关于其他两种方法:为maven.compiler.source/maven.compiler.target属性赋值或使用maven-compiler-plugin,您可以使用其中之一。这没有改变事实,因为这两个解决方案最终都依赖于相同的属性和相同的机制:maven核心编译器插件。

    如果您不需要在编译器插件中指定Java版本以外的其他属性或行为,那么使用这种方式会更有意义,因为它更简洁:

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

    从Java 9:

    如果希望对源和目标使用相同的版本,则release参数(第三点)是一个需要认真考虑的方法。

    如果JAVA_HOME中的JDK与pom.xml中指定的版本不同,会发生什么情况?

    如果java_home引用的JDK与pom中指定的版本兼容,这不是问题,但是为了确保更好的交叉编译兼容性,可以考虑添加bootstrapJVM选项,并将target版本的rt.jar路径作为值。

    需要考虑的一个重要问题是,Maven配置中的sourcetarget版本不应优于java_home引用的JDK版本。
    旧版本的JDK不能用新版本进行编译,因为它不知道它的规范。

    要根据使用的JDK获取有关源、目标和发布支持的版本的信息,请参考Java编译:源、目标和发布支持的版本。

    如何处理JAVA_HOME引用的JDK与POM中指定的Java目标和/或源版本不兼容的情况?

    例如,如果您的java_home引用了JDK 1.7,并且您在pom.xml的编译器配置中指定了JDK 1.8作为源和目标,这将是一个问题,因为正如所解释的,JDK 1.7不知道如何进行编译。
    从它的角度来看,它是一个未知的JDK版本,因为它是在它之后发布的。
    在这种情况下,您应该配置Maven编译器插件以这样的方式指定JDK:

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
            <source>1.8</source>
            <target>1.8</target>
            <compilerVersion>1.8</compilerVersion>      
            <fork>true</fork>
            <executable>D:\jdk1.8\bin\javac</executable>                
        </configuration>
    </plugin>
    

    您可以在使用maven编译器插件的示例中获得更多细节。

    它不是询问的,但可能更复杂的情况是当您指定源而不是目标时。它可能会根据源版本在target中使用不同的版本。规则是特别的:您可以在交叉编译选项部分中了解它们。

    为什么即使没有在pom.xml中指定编译器插件,在执行Mavenpackage目标时也会在输出中跟踪它?

    要编译您的代码,更广泛地说,要执行maven目标所需的所有任务,maven需要工具。因此,它使用核心Maven插件(通过其groupid:org.apache.Maven.plugins)来识别核心Maven插件)来执行所需的任务:编译类的编译器插件,执行测试的测试插件,等等。因此,即使您没有声明这些插件,它们也与Maven生命周期的执行绑定在一起。
    在Maven项目的根目录下,您可以运行命令:mvn help:effective-pom以有效地使用最终的pom。在其他信息中,您可以看到Maven附带的插件(在pom.xml中指定或没有指定)、使用的版本、它们的配置以及生命周期每个阶段执行的目标。

    mvn help:effective-pom命令的输出中,您可以在 元素中看到这些核心插件的声明,例如:

    ...
    <plugin>
       <artifactId>maven-clean-plugin</artifactId>
       <version>2.5</version>
       <executions>
         <execution>
           <id>default-clean</id>
           <phase>clean</phase>
           <goals>
             <goal>clean</goal>
           </goals>
         </execution>
       </executions>
     </plugin>
     <plugin>
       <artifactId>maven-resources-plugin</artifactId>
       <version>2.6</version>
       <executions>
         <execution>
           <id>default-testResources</id>
           <phase>process-test-resources</phase>
           <goals>
             <goal>testResources</goal>
           </goals>
         </execution>
         <execution>
           <id>default-resources</id>
           <phase>process-resources</phase>
           <goals>
             <goal>resources</goal>
           </goals>
         </execution>
       </executions>
     </plugin>
     <plugin>
       <artifactId>maven-compiler-plugin</artifactId>
       <version>3.1</version>
       <executions>
         <execution>
           <id>default-compile</id>
           <phase>compile</phase>
           <goals>
             <goal>compile</goal>
           </goals>
         </execution>
         <execution>
           <id>default-testCompile</id>
           <phase>test-compile</phase>
           <goals>
             <goal>testCompile</goal>
           </goals>
         </execution>
       </executions>
     </plugin>
      ...
    

    您可以在Maven文档中的Maven生命周期介绍中获得有关它的更多信息。

    然而,当您想要用其他值作为默认值来配置这些插件时(例如,当您在pom.xml中声明maven-compiler插件以调整要使用的JDK版本时就这样做了),或者当您想要添加一些在Maven生命周期中默认情况下不使用的插件执行时,您可以声明这些插件。

  •  类似资料:
    • 我在maven-compiler-plugin的pom.xml中有以下配置。 JDK的源版本和目标版本应该是什么?它如何依赖于安装在我的计算机上的jdk版本?他们可能不一样吗?例如,安装的jdk是1.8,在源参数-1.6,目标-1.7中。

    • 问题内容: 我在netbeans上编写了一个Maven代码,大约有2000多行。当我在netbeans上编译它时,一切都很好,但是如果我想在命令行上运行它,则会出现以下错误: 我尝试使用Java 1.3.1,编译器错误,但出现了更多错误。我从其他帖子中发现我应该修改pom.xml,但我不知道如何。这是我的pom.xml 如果您能帮助我,那就太好了。 问题答案: 请参阅配置页面以获取Maven编译器

    • 我用Netbeans编写了一些Maven代码,大约有2000多行。当我在Netbeans上编译它时,一切都很好,但如果我想在命令行上运行它,我会得到这些错误: 我尝试使用Java 1.3.1,编译器错误,但我得到更多的错误。我从其他帖子中发现我应该修改,但我不知道如何修改。下面是我的 如果你能帮我就太好了!

    • 我编写了一个没有父级的简单pom.xml来尝试这个方法,因此不涉及pluginManagement。我还检查了maven-model-builder中的super super pom-4.0.0.xml以确认maven-bundle-plugin不存在。此插件版本没有指定在任何地方。 maven如何确定采用哪个版本?

    • 本文向大家介绍编译器和汇编器之间的区别,包括了编译器和汇编器之间的区别的使用技巧和注意事项,需要的朋友参考一下 编译器 编译器用于将高级编程语言代码转换为机器级代码并创建可执行程序。编译器检查程序中的错误并报告它们。所有错误都将被清除,否则将不会编译和执行代码。 组装工 汇编程序用于将汇编级代码转换为机器可读代码。汇编程序也会检查每条指令的正确性并报告诊断报告。 以下是编译器和汇编器之间的重要区别

    • 作为Maven的新手,我试图用Maven和maven-shade-plugin编译一个项目(因为它似乎是构建一个胖罐子的最佳插件)。我试图指定我的主类来创建一个可运行的jar文件和一些。包含翻译字符串的属性文件。 根据netbean的输出,编译和构建似乎通过了,但我无法按以下方式运行它(假设Maven构建的jar更名为“程序”): 这是我的项目文件结构: 这是我的pom.xml文件: 资源是否正确