全面理解Maven Compiler Plugin-Maven编译插件

本文涉及的产品
NLP 自学习平台,3个模型定制额度 1个月
NLP自然语言处理_高级版,每接口累计50万次
视觉智能开放平台,视频资源包5000点
简介: 【10月更文挑战第16天】

0 前言

编译插件用于编译项目的源代码。3.0 版本起,默认编译器是 javax.tools.JavaCompiler(适用于 Java 1.6 及以上版本),用于编译 Java 源文件。如果希望强制插件使用 javac,可以配置插件选项 forceJavacCompilerUse

目前默认 source 设置为 1.8target 设置也为 1.8,无论运行 Maven 的 JDK 版本如何。这些默认值强烈建议通过设置 sourcetarget 修改,具体方法请参考设置 Java 编译器的 -source 和 -target

除了 javac,还可以使用其他编译器,开发团队已经开始在 AspectJ、.NET 和 C# 上进行相应的工作。

有关 JDK javac 的更多信息,请访问:https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javac.html。

1 目标

编译插件包含两个目标,这两个目标都已绑定到 Maven 生命周期中的相应阶段,因此会在其各自的阶段自动执行。

  • compiler:绑定到编译阶段,用于编译主要源文件
  • compiler:绑定到测试编译阶段,用于编译测试源文件

2 用法

有关如何使用编译插件的基本说明可以在用法页面中找到。下方列出了几个具体的使用案例示例。

如果您对插件的使用有疑问,请查阅常见问题解答,也可以随时联系用户邮件列表。邮件列表中的内容会被存档,可能已经包含了您问题的答案,因此浏览或搜索邮件存档也是不错的选择。

如果您认为插件缺少某个功能或存在缺陷,可以在我们的问题跟踪器中提交功能请求或错误报告。创建新问题时,请提供详细的描述,尤其是修复错误时,开发人员能够重现您的问题尤为重要。因此,附加完整的调试日志、POM 文件或小型示例项目将非常有帮助。当然,我们也欢迎补丁贡献,贡献者可以从我们的源代码库中获取项目,并在帮助 Maven 的指南中找到补充信息。

为帮助您更好地理解编译插件的一些用法,请参考以下示例:

3 使用不同的 JDK 进行编译

使用 Maven 工具链

使用不同 JDK 的最佳方式是通过工具链机制。若不使用工具链,在项目构建过程中,Maven 将使用 JDK 执行多个步骤,如编译 Java 源代码、生成 Javadoc、运行单元测试或签署 JAR 文件。每个插件都需要 JDK 工具来操作:如 javacjavadocjarsigner 等。工具链可以集中指定用于所有这些插件的 JDK 路径,而与运行 Maven 本身的 JDK 无关。

置此功能,参阅工具链使用指南,该指南介绍 Maven 工具链插件 的使用方法。

通过 maven-toolchains-plugin,您可以为所有相关的 Maven 插件配置一个默认的 JDK 工具链。从 maven-compiler-plugin 3.6.0 版本起,使用 Maven 3.3.1 及更高版本时,插件还可以单独使用其自己的工具链配置,这在不同的执行块需要使用不同的 JDK(例如测试源代码需要不同的编译器)时非常有用。

配置编译插件

不使用工具链情况,仍可为编译插件指定要使用的 JDK。这种配置仅适用于编译插件,不会影响其他插件。

可用 compilerVersion 参数指定插件使用的编译器版本,不过要使其生效,还需要将 fork 设置为 true。例如:

<project>
  [...]
  <build>
    [...]
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.13.0</version>
        <configuration>
          <verbose>true</verbose>
          <fork>true</fork>
          <executable><!-- path-to-javac --></executable>
          <compilerVersion>1.3</compilerVersion>
        </configuration>
      </plugin>
    </plugins>
    [...]
  </build>
  [...]
</project>

为避免硬编码 executable 的文件系统路径,可用属性。如:

<executable>${JAVA_1_4_HOME}/bin/javac</executable>

每位开发者可在 settings.xml 中定义该属性或通过设置环境变量,确保构建的可移植性。

<settings>
  [...]
  <profiles>
    [...]
    <profile>
      <id>compiler</id>
        <properties>
          <JAVA_1_4_HOME>C:\Program Files\Java\j2sdk1.4.2_09</JAVA_1_4_HOME>
        </properties>
    </profile>
  </profiles>
  [...]
  <activeProfiles>
    <activeProfile>compiler</activeProfile>
  </activeProfiles>
</settings>

如用不同 JDK 进行构建,可能希望自定义 jar 文件的 manifest 文件。

4 使用 -source 和 -target javac 选项进行编译

设置 Java 编译器的 -source-target

有时需要将项目编译为与当前 JDK 不同的版本。javac 可接受 -source-target 命令,编译插件也可以配置这些选项以便在编译时使用。

如若希望使用 Java 8 语言特性(-source 1.8),并希望编译后的类与 JVM 1.8 兼容(-target 1.8),可以添加以下两个属性(这些是插件参数的默认属性名称):

<project>
  [...]
  <properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>
  [...]
</project>

或直接配置插件:

<project>
  [...]
  <build>
    [...]
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.13.0</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
    </plugins>
    [...]
  </build>
  [...]
</project>

仅设置 target 选项并不能保证代码能在指定版本的 JRE 上运行。问题在于可能无意中使用了较新 JRE 才有的 API,这会导致代码在运行时出现链接错误。为避免此问题,可以配置编译器的引导类路径来匹配目标 JRE,或使用 Animal Sniffer Maven 插件 验证代码不会使用不兼容的 API,更好的方法是使用自 JDK 9 起支持的 release 选项。此外,设置 source 选项并不保证代码能在指定版本的 JDK 上成功编译。如需使用与运行 Maven 不同的 JDK 编译代码,请参考使用不同 JDK 进行编译示例。

5 使用 --release javac 选项进行编译(自 JDK 9 支持)

从 JDK 9 开始,javac 可接受 --release 选项来指定构建项目所需的 Java SE 版本。例如,您已安装并在 Maven 中使用 JDK 11,但希望项目针对 Java 8 进行构建。--release 选项确保代码按照指定版本的编程语言规则进行编译,生成的类文件符合该版本的公共 API。与 -source-target 选项 不同,编译器会检测并在使用不支持的 API 时生成错误。

自编译插件 3.6 版本起,可以通过属性来设置此选项:

<project>
  [...]
  <properties>
    <maven.compiler.release>8</maven.compiler.release>
  </properties>
  [...]
</project>

或者直接配置插件:

<project>
  [...]
  <build>
    [...]
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.13.0</version>
        <configuration>
          <release>8</release>
        </configuration>
      </plugin>
    </plugins>
    [...]
  </build>
  [...]
</project>

注意release 参数的值遵循 Java 9 起采用的新版本命名方案,因此版本号不再以 1.x 开头。此外,支持的 release 目标包括当前 JDK 版本及少量较早版本。

在 JDK 8 上的使用

在 JDK 8 上不支持 --release 选项。为了在 JDK 8 和 JDK 9 或更高版本中构建面向 Java 8 的项目,需有条件地使用 --release 选项。

若编译插件版本低于 3.13.0 或编译器 ID 不为 javac 时则需要条件参数化。

可以通过配置文件实现:

<project>
  [...]
  <profiles>
    [...]
    <profile>
      <id>set-compiler-release</id>
      <activation>
        <jdk>[9,)</jdk>
      </activation>
      <properties>
        <maven.compiler.release>8</maven.compiler.release>
      </properties>
    </profile>
    [...]
  </profiles>
  [...]
</project>

自编译插件 3.13.0 版本及默认 javac 编译器 ID 开始,不再需要条件参数化。release 参数仅在 Java 9 或更高版本中有效,否则将传递 sourcetarget 参数给编译器。

因此,可以直接配置为:

<project>
 [...]
 <build>
   [...]
   <plugins>
     <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-compiler-plugin</artifactId>
       <version>3.13.0</version>
       <configuration>
         <release>8</release>
         <source>8</source>
         <target>8</target>
       </configuration>
     </plugin>
   </plugins>
   [...]
 </build>
 [...]
</project>

6 使用内存分配增强功能进行编译

编译器插件接受 meminitialmaxmem 的配置。您可以按照以下示例将初始内存大小设置为 128MB,并将最大内存使用量设置为 512MB:

<project>
  [...]
  <build>
    [...]
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.13.0</version>
        <configuration>
          <fork>true</fork>
          <meminitial>128m</meminitial>
          <maxmem>512m</maxmem>
        </configuration>
      </plugin>
    </plugins>
    [...]
  </build>
  [...]
</project>

7 传递编译器参数

有时,您需要传递编译器参数,这些参数并不被编译器插件本身处理,但被所选的 compilerId 支持。对于此类参数,请使用编译器插件的 compilerArgs 参数。以下示例向 javac 编译器传递编译器参数:

<project>
  [...]
  <build>
    [...]
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.13.0</version>
        <configuration>
          <compilerArgs>
            <arg>-verbose</arg>
            <arg>-Xlint:all,-options,-path</arg>
          </compilerArgs>
        </configuration>
      </plugin>
    </plugins>
    [...]
  </build>
  [...]
</project>

参考:

目录
相关文章
|
3月前
|
Java Maven
Maven编译报错
Maven编译报错
69 1
|
5月前
|
XML Java Maven
maven总结三: 常用插件
maven总结三: 常用插件
51 3
|
28天前
|
Java 测试技术 项目管理
maven编译本地代码的命令是什么?
【10月更文挑战第26天】maven编译本地代码的命令是什么?
48 0
|
4月前
|
Java Maven Spring
Maven重打包问题之maven-shade-plugin插件对于重复的class文件会如何处理
Maven重打包问题之maven-shade-plugin插件对于重复的class文件会如何处理
|
4月前
|
Java jenkins 持续交付
jenkins学习笔记之十七:使用插件及maven上传制品到nexus
jenkins学习笔记之十七:使用插件及maven上传制品到nexus
|
5月前
|
Java Maven
idea安装并使用maven依赖分析插件:Maven Helper
idea安装并使用maven依赖分析插件:Maven Helper
2614 7
|
4月前
|
Java Maven 开发者
"揭秘IDEA的神奇助手:Maven Helper插件,让你轻松驾驭复杂依赖,告别冲突噩梦!"
【8月更文挑战第20天】Maven Helper是一款提升Java开发者工作效率的IDEA插件,它能直观展示项目依赖关系并协助管理。主要功能包括依赖树视图、冲突检测与解决及依赖排除。安装简便,重启IDEA后即用。借助其“Dependencies”面板,开发者可以清晰了解依赖详情,快速定位并解决冲突问题,有效优化项目结构,提升开发效率。
250 0
|
20天前
|
Java Maven
maven项目的pom.xml文件常用标签使用介绍
第四届人文,智慧教育与服务管理国际学术会议(HWESM 2025) 2025 4th International Conference on Humanities, Wisdom Education and Service Management
74 8
|
17天前
|
Java 应用服务中间件 Maven
Maven的三种项目打包方式——pom,jar,war的区别
Maven 提供了多种打包方式,分别适用于不同类型的项目。pom 用于父项目或聚合项目,便于项目的结构和依赖管理;jar 用于Java类库或可执行的Java应用程序;war 则专用于Java Web应用程序的部署。理解这些打包方式的用途和特点,可以帮助开发者更好地配置和管理Maven项目,确保构建和部署过程的顺利进行。无论是单模块项目还是多模块项目,选择合适的打包方式对于项目的成功至关重要。
50 3
|
2月前
|
Java 关系型数据库 MySQL
Maven——创建 Spring Boot项目
Maven 是一个项目管理工具,通过配置 `pom.xml` 文件自动获取所需的 jar 包,简化了项目的构建和管理过程。其核心功能包括项目构建和依赖管理,支持创建、编译、测试、打包和发布项目。Maven 仓库分为本地仓库和远程仓库,远程仓库包括中央仓库、私服和其他公共库。此外,文档还介绍了如何创建第一个 SpringBoot 项目并实现简单的 HTTP 请求响应。
132 1
Maven——创建 Spring Boot项目

推荐镜像

更多