Maven打包插件
2025/7/17...大约 7 分钟
Maven打包插件
Maven提供了丰富的打包功能,通过各种插件可以将Java项目打包成不同格式,如JAR、WAR、EAR等。本文将详细介绍Maven的打包机制和常用打包插件的配置与使用。
Maven打包基础
Maven的打包过程是构建生命周期的一部分,主要在package
阶段执行。默认情况下,Maven根据项目的packaging
类型选择相应的打包插件:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 打包类型:jar, war, ear, pom等 -->
<packaging>jar</packaging>
<!-- ... -->
</project>
常见的打包类型包括:
jar
:Java归档文件,适用于大多数Java项目war
:Web应用归档文件,用于Web应用ear
:企业应用归档文件,包含多个模块pom
:不生成构件,通常用于父项目或聚合项目
常用打包插件
1. maven-jar-plugin
用于创建JAR文件,是最基本的打包插件。
基本配置
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<!-- JAR文件配置 -->
<archive>
<!-- 生成MANIFEST.MF -->
<manifest>
<!-- 添加依赖的JAR包路径 -->
<addClasspath>true</addClasspath>
<!-- 依赖JAR包的前缀 -->
<classpathPrefix>lib/</classpathPrefix>
<!-- 指定主类 -->
<mainClass>com.example.MainApp</mainClass>
</manifest>
<manifestEntries>
<!-- 自定义清单条目 -->
<Built-By>${user.name}</Built-By>
<Build-Time>${maven.build.timestamp}</Build-Time>
<Implementation-Version>${project.version}</Implementation-Version>
</manifestEntries>
</archive>
<!-- 排除文件 -->
<excludes>
<exclude>**/config.properties</exclude>
</excludes>
</configuration>
</plugin>
创建可执行JAR
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.example.MainApp</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<!-- 复制依赖到lib目录 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
2. maven-war-plugin
用于创建WAR文件,适用于Web应用。
基本配置
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
<configuration>
<!-- Web应用上下文路径 -->
<warName>${project.artifactId}</warName>
<!-- web.xml位置 -->
<webXml>src/main/webapp/WEB-INF/web.xml</webXml>
<!-- 排除文件 -->
<packagingExcludes>
WEB-INF/classes/config.properties,
**/*.log
</packagingExcludes>
<!-- 归档配置 -->
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
<manifestEntries>
<Implementation-Build>${buildNumber}</Implementation-Build>
</manifestEntries>
</archive>
<!-- 资源目录 -->
<webResources>
<resource>
<directory>src/main/resources/config</directory>
<targetPath>WEB-INF/classes</targetPath>
<filtering>true</filtering>
</resource>
</webResources>
<!-- 是否失败时中止WAR创建 -->
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
创建覆盖层WAR
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
<configuration>
<overlays>
<overlay>
<!-- 基础WAR -->
<groupId>com.example</groupId>
<artifactId>base-webapp</artifactId>
<!-- 排除基础WAR中的文件 -->
<excludes>
<exclude>WEB-INF/web.xml</exclude>
<exclude>WEB-INF/classes/application.properties</exclude>
</excludes>
</overlay>
</overlays>
</configuration>
</plugin>
3. maven-assembly-plugin
用于创建自定义打包格式,可以将项目及其依赖、模块、文档等打包成一个分发包。
基本配置
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.4.2</version>
<configuration>
<!-- 描述符文件 -->
<descriptors>
<descriptor>src/assembly/distribution.xml</descriptor>
</descriptors>
<!-- 最终生成的文件名 -->
<finalName>${project.artifactId}-${project.version}</finalName>
<!-- 打包格式:zip, tar.gz, tar.bz2等 -->
<formats>
<format>zip</format>
<format>tar.gz</format>
</formats>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
描述符文件示例 (src/assembly/distribution.xml)
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0
http://maven.apache.org/xsd/assembly-2.1.0.xsd">
<id>distribution</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>true</includeBaseDirectory>
<!-- 复制项目JAR -->
<files>
<file>
<source>${project.build.directory}/${project.build.finalName}.jar</source>
<outputDirectory>/</outputDirectory>
</file>
<file>
<source>README.md</source>
<outputDirectory>/</outputDirectory>
</file>
<file>
<source>LICENSE</source>
<outputDirectory>/</outputDirectory>
</file>
</files>
<!-- 复制依赖 -->
<dependencySets>
<dependencySet>
<outputDirectory>/lib</outputDirectory>
<useProjectArtifact>false</useProjectArtifact>
<unpack>false</unpack>
<scope>runtime</scope>
</dependencySet>
</dependencySets>
<!-- 复制配置文件 -->
<fileSets>
<fileSet>
<directory>src/main/resources</directory>
<outputDirectory>/config</outputDirectory>
<includes>
<include>*.properties</include>
<include>*.xml</include>
</includes>
<filtered>true</filtered>
</fileSet>
<fileSet>
<directory>src/main/scripts</directory>
<outputDirectory>/bin</outputDirectory>
<includes>
<include>*.sh</include>
<include>*.bat</include>
</includes>
<fileMode>0755</fileMode>
<filtered>true</filtered>
</fileSet>
</fileSets>
</assembly>
4. maven-shade-plugin
用于创建"uber-jar"或"fat-jar",将所有依赖打包到一个JAR中。
基本配置
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<!-- 创建可执行JAR -->
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.example.MainApp</mainClass>
</transformer>
<!-- 合并服务 -->
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<!-- 合并Spring配置 -->
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
</transformers>
<!-- 排除签名文件 -->
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<!-- 重定位包,避免冲突 -->
<relocations>
<relocation>
<pattern>org.apache.commons</pattern>
<shadedPattern>com.example.shaded.commons</shadedPattern>
</relocation>
</relocations>
<!-- 最小化JAR -->
<minimizeJar>false</minimizeJar>
<!-- 输出文件名 -->
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>with-dependencies</shadedClassifierName>
</configuration>
</execution>
</executions>
</plugin>
5. spring-boot-maven-plugin
用于打包Spring Boot应用,创建可执行JAR或WAR。
基本配置
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.7.3</version>
<configuration>
<!-- 排除开发工具 -->
<excludeDevtools>true</excludeDevtools>
<!-- 分层JAR -->
<layers>
<enabled>true</enabled>
</layers>
<!-- 构建信息 -->
<build-info>
<additionalProperties>
<encoding>${project.build.sourceEncoding}</encoding>
<java.version>${java.version}</java.version>
</additionalProperties>
</build-info>
<!-- 排除依赖 -->
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
创建原生镜像
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.7.3</version>
<configuration>
<image>
<name>${project.artifactId}:${project.version}</name>
<env>
<BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE>
</env>
</image>
</configuration>
</plugin>
6. maven-source-plugin
用于创建源码JAR包。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>verify</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
7. maven-javadoc-plugin
用于创建JavaDoc文档JAR包。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<id>attach-javadocs</id>
<phase>verify</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- 跳过错误 -->
<failOnError>false</failOnError>
<!-- 添加额外选项 -->
<additionalOptions>
<additionalOption>-Xdoclint:none</additionalOption>
</additionalOptions>
</configuration>
</plugin>
打包实践案例
1. 创建包含依赖的可执行JAR
<build>
<plugins>
<!-- 打包JAR -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.example.MainApp</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<!-- 复制依赖 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
2. 创建完整的分发包
<build>
<plugins>
<!-- 打包JAR -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<!-- 创建分发包 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.4.2</version>
<configuration>
<descriptors>
<descriptor>src/assembly/distribution.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
3. 创建多环境打包配置
<profiles>
<!-- 开发环境 -->
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<env>dev</env>
</properties>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources-${env}</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
</profile>
<!-- 生产环境 -->
<profile>
<id>prod</id>
<properties>
<env>prod</env>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.example.MainApp</mainClass>
</transformer>
</transformers>
<minimizeJar>true</minimizeJar>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources-${env}</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
</profile>
</profiles>
打包最佳实践
- 选择合适的打包插件:根据项目类型和需求选择合适的打包插件
- 管理依赖范围:合理设置依赖的scope,避免将不必要的依赖打包
- 使用资源过滤:利用Maven的资源过滤功能,为不同环境生成不同配置
- 排除不必要的文件:使用excludes配置排除不需要的文件
- 合理组织模块:将大型项目拆分为多个模块,分别打包
- 自动化版本管理:使用Maven的版本管理功能,自动更新版本号
- 创建源码和文档包:为库项目生成源码和JavaDoc包,方便使用者
- 使用配置文件:利用Maven的profile功能,为不同环境创建不同的打包配置
常见问题与解决方案
依赖冲突
问题:打包时出现依赖冲突。
解决:使用maven-shade-plugin
的relocations功能重定位冲突包,或使用<exclusions>
排除冲突依赖。
包过大
问题:生成的JAR包过大。
解决:使用maven-shade-plugin
的minimizeJar功能,或者使用maven-dependency-plugin
的analyze
目标分析并移除不必要的依赖。
资源文件编码问题
问题:打包后的资源文件出现乱码。
解决:在maven-resources-plugin
中指定正确的编码:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
打包速度慢
问题:打包过程耗时长。
解决:使用并行构建、增量构建或跳过不必要的步骤:
# 并行构建
mvn -T 4 package
# 跳过测试
mvn package -DskipTests
总结
Maven提供了强大而灵活的打包功能,通过各种插件可以满足不同项目的打包需求。本文介绍了常用的打包插件及其配置方法,希望能帮助你更好地使用Maven进行项目打包。
选择合适的打包插件和配置,可以简化部署流程,提高项目质量,并为用户提供更好的使用体验。