ZetCode

Maven 编译器插件

最后修改于 2025 年 6 月 9 日

在本文中,我们将展示如何使用 Maven Compiler Plugin 配置 Java 编译。此插件控制 Maven 如何编译您的 Java 源代码。

Maven Compiler Plugin 用于编译项目的源代码。它同时处理主源文件编译和测试源文件编译,允许您指定不同的 Java 版本、编译器参数和其他编译设置。

基本配置

让我们从一个基本示例开始,演示如何使用特定的 Java 版本和编码设置来配置 Compiler 插件。

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>compiler-example</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.12.1</version>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

此基本配置使用 UTF-8 编码设置 Java 17 编译。插件将使用这些设置编译您的主源代码和测试源代码。

<source>17</source>
<target>17</target>

指定源代码兼容性和目标字节码版本的 Java 版本。Source 定义了可以使用哪些 Java 语言功能,而 Target 定义了运行编译后的代码所需的最低 JVM 版本。

<encoding>UTF-8</encoding>

设置源文件的字符编码。这可确保在不同的平台和环境之间进行一致的编译。

示例应用程序

让我们创建一个简单的应用程序,该应用程序使用现代 Java 功能来演示编译器配置

src/main/java/com/example/ModernJavaApp.java
package com.example;

import java.util.List;
import java.util.stream.Collectors;

public class ModernJavaApp {
    
    public static void main(String[] args) {
        System.out.println("Maven Compiler Plugin Example");
        
        // Using modern Java features (Java 8+)
        var numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        
        var evenNumbers = numbers.stream()
            .filter(n -> n % 2 == 0)
            .map(n -> "Number: " + n)
            .collect(Collectors.toList());
        
        System.out.println("Even numbers:");
        evenNumbers.forEach(System.out::println);
        
        // Using text blocks (Java 15+)
        var jsonTemplate = """
            {
                "name": "Maven Compiler Example",
                "version": "1.0.0",
                "features": ["compilation", "java17", "modern-syntax"]
            }
            """;
        
        System.out.println("JSON Template:");
        System.out.println(jsonTemplate);
    }
}

构建项目

要编译项目,请运行以下 Maven 命令

$ mvn clean compile

这会使用配置的 Java 版本和设置编译您的主源代码。您也可以运行应用程序

$ mvn exec:java -Dexec.mainClass="com.example.ModernJavaApp"
Maven Compiler Plugin Example
Even numbers:
Number: 2
Number: 4
Number: 6
Number: 8
Number: 10
JSON Template:
{
    "name": "Maven Compiler Example",
    "version": "1.0.0",
    "features": ["compilation", "java17", "modern-syntax"]
}

高级编译器选项

Compiler 插件支持许多高级选项,用于微调编译过程。这是一个全面的配置示例

pom.xml (高级配置)
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.12.1</version>
    <configuration>
        <source>17</source>
        <target>17</target>
        <encoding>UTF-8</encoding>
        
        <!-- Show deprecation warnings -->
        <showDeprecation>true</showDeprecation>
        
        <!-- Show unchecked warnings -->
        <showWarnings>true</showWarnings>
        
        <!-- Fail on warning -->
        <failOnWarning>false</failOnWarning>
        
        <!-- Verbose compilation output -->
        <verbose>false</verbose>
        
        <!-- Optimize compiled code -->
        <optimize>true</optimize>
        
        <!-- Generate debugging information -->
        <debug>true</debug>
        
        <!-- Include debug symbols -->
        <debuglevel>lines,vars,source</debuglevel>
        
        <!-- Custom compiler arguments -->
        <compilerArgs>
            <arg>-Xlint:all</arg>
            <arg>-Xlint:-processing</arg>
            <arg>-Werror</arg>
        </compilerArgs>
        
        <!-- Annotation processing -->
        <annotationProcessorPaths>
            <path>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.30</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>

此高级配置包含几个重要的编译器选项

<showDeprecation>true</showDeprecation>
<showWarnings>true</showWarnings>

在编译期间启用弃用警告和通用编译器警告的显示,有助于识别代码中的潜在问题。

<compilerArgs>
    <arg>-Xlint:all</arg>
    <arg>-Xlint:-processing</arg>
</compilerArgs>

将其他参数传递给 Java 编译器。此示例启用了除注解处理警告之外的所有 lint 警告。

<debuglevel>lines,vars,source</debuglevel>

指定要包含在编译类中的调试信息。这对于调试和开发环境很有用。

主源文件和测试源文件的不同配置

有时您需要为主源文件和测试源文件设置不同的编译设置。以下是配置单独设置的方法

pom.xml (主文件和测试文件的单独配置)
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.12.1</version>
    <executions>
        <execution>
            <id>default-compile</id>
            <phase>compile</phase>
            <goals>
                <goal>compile</goal>
            </goals>
            <configuration>
                <source>17</source>
                <target>17</target>
                <encoding>UTF-8</encoding>
                <showDeprecation>true</showDeprecation>
                <showWarnings>true</showWarnings>
                <compilerArgs>
                    <arg>-Xlint:all</arg>
                    <arg>-Werror</arg>
                </compilerArgs>
            </configuration>
        </execution>
        <execution>
            <id>default-testCompile</id>
            <phase>test-compile</phase>
            <goals>
                <goal>testCompile</goal>
            </goals>
            <configuration>
                <source>17</source>
                <target>17</target>
                <encoding>UTF-8</encoding>
                <showDeprecation>false</showDeprecation>
                <showWarnings>false</showWarnings>
                <compilerArgs>
                    <arg>-Xlint:none</arg>
                </compilerArgs>
            </configuration>
        </execution>
    </executions>
</plugin>

此配置使用严格的编译设置(将警告视为错误)为主源文件,而对测试源文件使用更宽松的设置。

多版本 JAR 支持

Java 9 引入了多版本 JAR,其中可以包含不同 Java 版本的类的不同版本。以下是配置方法

pom.xml (多版本 JAR 配置)
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.12.1</version>
    <configuration>
        <source>11</source>
        <target>11</target>
        <encoding>UTF-8</encoding>
    </configuration>
    <executions>
        <execution>
            <id>compile-java-17</id>
            <phase>compile</phase>
            <goals>
                <goal>compile</goal>
            </goals>
            <configuration>
                <release>17</release>
                <compileSourceRoots>
                    <compileSourceRoot>${project.basedir}/src/main/java17</compileSourceRoot>
                </compileSourceRoots>
                <outputDirectory>${project.build.outputDirectory}/META-INF/versions/17</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

这将创建一个多版本 JAR,以 Java 11 作为基础版本,并在适当的 META-INF/versions 目录中提供 Java 17 特定实现。

src/main/java/com/example/VersionSpecificCode.java
package com.example;

public class VersionSpecificCode {
    
    public static String getJavaVersion() {
        return "Running on Java " + System.getProperty("java.version");
    }
    
    public static String getFeatureInfo() {
        return "Base Java 11 implementation";
    }
}
src/main/java17/com/example/VersionSpecificCode.java
package com.example;

public class VersionSpecificCode {
    
    public static String getJavaVersion() {
        return "Running on Java " + System.getProperty("java.version");
    }
    
    public static String getFeatureInfo() {
        // Using Java 17 specific features
        var features = """
            Java 17 enhanced implementation with:
            - Text blocks
            - Pattern matching
            - Records
            - Sealed classes
            """;
        return features.strip();
    }
}

注解处理器配置

Compiler 插件可以配置为与 Lombok、MapStruct 或自定义处理器等注解处理器一起使用

pom.xml (注解处理器配置)
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.12.1</version>
    <configuration>
        <source>17</source>
        <target>17</target>
        <encoding>UTF-8</encoding>
        
        <!-- Annotation processor configuration -->
        <annotationProcessorPaths>
            <path>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.30</version>
            </path>
            <path>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct-processor</artifactId>
                <version>1.5.5.Final</version>
            </path>
        </annotationProcessorPaths>
        
        <!-- Annotation processor options -->
        <compilerArgs>
            <arg>-Amapstruct.defaultComponentModel=spring</arg>
            <arg>-Amapstruct.unmappedTargetPolicy=ERROR</arg>
        </compilerArgs>
        
        <!-- Generate source files for annotation processors -->
        <generatedSourcesDirectory>${project.build.directory}/generated-sources/annotations</generatedSourcesDirectory>
    </configuration>
</plugin>

此配置设置了 Lombok 和 MapStruct 注解处理器,并带有特定选项以及用于生成源的自定义目录。

<annotationProcessorPaths>

指定注解处理器的类路径,允许它们在编译期间运行,而无需包含在项目依赖项中。

<compilerArgs>
    <arg>-Amapstruct.defaultComponentModel=spring</arg>
</compilerArgs>

使用 -A 标志后跟选项键和值,将特定选项传递给注解处理器。

编译器插件属性

您还可以使用 Maven 属性来配置 Compiler 插件,这对于简单的配置通常更方便

pom.xml (基于属性的配置)
<properties>
    <!-- Java version properties -->
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <maven.compiler.release>17</maven.compiler.release>
    
    <!-- Encoding -->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
    
    <!-- Compiler options -->
    <maven.compiler.showDeprecation>true</maven.compiler.showDeprecation>
    <maven.compiler.showWarnings>true</maven.compiler.showWarnings>
    <maven.compiler.optimize>true</maven.compiler.optimize>
    <maven.compiler.debug>true</maven.compiler.debug>
    
    <!-- Plugin version -->
    <maven.compiler.plugin.version>3.12.1</maven.compiler.plugin.version>
</properties>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>${maven.compiler.plugin.version}</version>
        </plugin>
    </plugins>
</build>

这种方法使用 Maven 属性来配置 Compiler 插件,从而更容易从命令行或父 POM 管理和覆盖设置。

<maven.compiler.release>17</maven.compiler.release>

当使用 Java 9+ 时,release 参数比单独的 source 和 target 参数更受欢迎,因为它确保了与指定版本的完全兼容性。

常见的编译器插件用例

以下是一些常见场景及其配置

混合 Java 版本的旧项目
<!-- For projects that need to maintain Java 8 compatibility -->
<properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    <maven.compiler.testSource>17</maven.compiler.testSource>
    <maven.compiler.testTarget>17</maven.compiler.testTarget>
</properties>
生产环境的严格编译
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.12.1</version>
    <configuration>
        <release>17</release>
        <showDeprecation>true</showDeprecation>
        <showWarnings>true</showWarnings>
        <failOnWarning>true</failOnWarning>
        <compilerArgs>
            <arg>-Xlint:all</arg>
            <arg>-Werror</arg>
        </compilerArgs>
    </configuration>
</plugin>

来源

Maven 编译器插件 - 参考

在本文中,我们展示了如何使用 Maven Compiler Plugin 通过各种选项和场景来配置 Java 编译。

作者

我叫 Jan Bodnar,是一位充满激情的程序员,拥有丰富的编程经验。我自 2007 年以来一直撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出所有Java教程