Maven的三种打包方式(jar、shade、assembly)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: Maven的三种打包方式(jar、shade、assembly)

01 引言

Maven有三种打包方式,分别为:

  • assembly:自定义的打包结构,也可以定制依赖项等;
  • jar:默认的打包方式,用来打普通的project JAR包;
  • shade:用来打可执行jar包,也就是所谓的fat JAR包。

下面来讲解下这三种的打包方式。

02 assembly打包

2.1 介绍

插件:使用maven-assembly-plugin插件 。

我们日常使用比较多的是maven-assembly-plugin插件,例如:大数据项目中往往有很多shell脚本、SQL脚本、.properties.xml配置项等,采用assembly插件可以让输出的结构清晰而标准化。

2.2 使用

首先在pom文件添加以下内容:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>${maven-assembly-plugin.version}<version>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <!-- 绑定到package生命周期 -->
                    <phase>package</phase>
                    <goals>
                        <!-- 只运行一次 -->
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <!-- 配置描述符文件 -->
                <descriptor>src/main/assembly/assembly.xml</descriptor>
                <!-- 也可以使用Maven预配置的描述符
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs> -->
            </configuration>
        </plugin>
    </plugins>
</build>

然后编写描述符文件:

<assembly>
    <id>assembly</id>
    <formats>
        <format>tar.gz</format>
    </formats>
    <includeBaseDirectory>true</includeBaseDirectory>
    <fileSets>
        <fileSet>
            <directory>src/main/bin</directory>
            <includes>
                <include>*.sh</include>
            </includes>
            <outputDirectory>bin</outputDirectory>
            <fileMode>0755</fileMode>
        </fileSet>
        <fileSet>
            <directory>src/main/conf</directory>
            <outputDirectory>conf</outputDirectory>
        </fileSet>
        <fileSet>
            <directory>src/main/sql</directory>
            <includes>
                <include>*.sql</include>
            </includes>
            <outputDirectory>sql</outputDirectory>
        </fileSet>
        <fileSet>
            <directory>target/classes/</directory>
            <includes>
                <include>*.properties</include>
                <include>*.xml</include>
                <include>*.txt</include>
            </includes>
            <outputDirectory>conf</outputDirectory>
        </fileSet>
    </fileSets>
    <files>
        <file>
            <source>target/${project.artifactId}-${project.version}.jar</source>
            <outputDirectory>.</outputDirectory>
        </file>
    </files>
    <dependencySets>
        <dependencySet>
            <unpack>false</unpack>
            <scope>runtime</scope>
            <outputDirectory>lib</outputDirectory>
        </dependencySet>
    </dependencySets>
</assembly>

2.3 字段解析

字段 解析
formats 是assembly插件支持的打包文件格式,有zip、tar、tar.gz、tar.bz2、jar、war。可以同时定义多个forma
id 是添加到打包文件名的标识符,用来做后缀。也就是说,如果按上面的配置,生成的文件就是artifactId − {artifactId}-artifactId−{version}-assembly.tar.gz
fileSets/fileSet 用来设置一组文件在打包时的属性
directory 源目录的路径
includes/excludes 设定包含或排除哪些文件,支持通配符
fileMode 指定该目录下的文件属性,采用Unix八进制描述法,默认值是064
outputDirectory 生成目录的路径
files/file 与fileSets大致相同,不过是指定单个文件,并且还可以通过destName属性来设置与源文件不同的名称
dependencySets/dependencySet 用来设置工程依赖文件在打包时的属性,也与fileSets大致相同
dependencySet-unpack 布尔值,false表示将依赖以原来的JAR形式打包,true则表示将依赖解成*.class文件的目录结构打包
dependencySet-scope 表示符合哪个作用范围的依赖会被打包进去。compile与provided都不用管,一般是写runtime

按照以上配置打包好后,将.tar.gz文件上传到服务器,解压之后就会得到bin、conf、lib等规范化的目录结构,十分方便。

03 jar打包

3.1 介绍

插件:使用maven-jar-plugin插件

默认的打包方式,用来打普通的project JAR

3.2 使用

<build>
   <plugins>
       <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>3.1.0</version>
            <configuration>
                <archive>
                    <manifest>
                        <!-- 指定入口函数 -->                             <mainClass>com.xx.main.HelloMavenJar</mainClass>
                        <!-- 是否添加依赖的jar路径配置 -->
                        <addClasspath>true</addClasspath>
                        <!-- 依赖的jar包存放未知,和生成的jar放在同一级目录下 -->
                        <classpathPrefix>lib/</classpathPrefix>
                    </manifest>
                </archive>
                <!-- 不打包com.yh.excludes下面的所有类 -->
                <excludes>com/xx/excludes/*</excludes>
            </configuration>
        </plugin>
    </plugins>
</build>

3.3 字段解析

上面3.2的配置使用这个 jar包的时候就需要在它同一级的创建一个lib目录来存放。

可以使用includesexcludes选择的打包某些内容。

04 shade打包

4.1 介绍

插件:使用maven-shade-plugin插件

maven-shade-plugin提供了两大基本功能:

  • 将依赖的jar包打包到当前jar包(常规打包是不会将所依赖jar包打进来的);
  • 对依赖的jar包进行重命名(用于类的隔离);

4.2 使用

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-shade-plugin</artifactId>
      <version>3.1.1</version>
      <configuration>
        <!-- put your configurations here -->
      </configuration>
      <executions>
        <execution>
          <phase>package</phase>
          <goals>
            <goal>shade</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

4.3 字段解析

参考:https://blog.csdn.net/yangguosb/article/details/80619481

可以使用excludes排除部分jar包,例如:

<excludes>
  <exclude>jmock:*</exclude>
  <exclude>*:xml-apis</exclude>
  <exclude>org.apache.maven:lib:tests</exclude>
  <exclude>log4j:log4j:jar:</exclude>
</excludes>

将依赖jar包内部资源添加或排除,例如:

<excludes>
  <exclude>META-INF/*.SF</exclude>
  <exclude>META-INF/*.DSA</exclude>
  <exclude>META-INF/*.RSA</exclude>
</excludes>

自动将所有不使用的类排除,例如:

<configuration>
  <minimizeJar>true</minimizeJar>
</configuration>

将依赖的类重命名并打包进来 (隔离方案),例如将“org.codehaus.plexus.util”重命名为“org.shaded.plexus.util":

<relocations>
  <relocation>
    <pattern>org.codehaus.plexus.util</pattern>
    <shadedPattern>org.shaded.plexus.util</shadedPattern>
    <excludes>
      <exclude>org.codehaus.plexus.util.xml.Xpp3Dom</exclude>
      <exclude>org.codehaus.plexus.util.xml.pull.*</exclude>
    </excludes>
  </relocation>
</relocations>

修改包的后缀名:

<configuration>
   <shadedArtifactAttached>true</shadedArtifactAttached>
   <shadedClassifierName>jackofall</shadedClassifierName> <!-- Any name that makes sense -->
 </configuration>

05 文末

具体细节可以参考:

目录
相关文章
|
4月前
|
Java Maven 容器
java依赖冲突解决问题之Maven在编译打包过程中对依赖的jar包如何解决
java依赖冲突解决问题之Maven在编译打包过程中对依赖的jar包如何解决
|
1月前
|
Java 应用服务中间件 Maven
Maven的三种项目打包方式——pom,jar,war的区别
Maven 提供了多种打包方式,分别适用于不同类型的项目。pom 用于父项目或聚合项目,便于项目的结构和依赖管理;jar 用于Java类库或可执行的Java应用程序;war 则专用于Java Web应用程序的部署。理解这些打包方式的用途和特点,可以帮助开发者更好地配置和管理Maven项目,确保构建和部署过程的顺利进行。无论是单模块项目还是多模块项目,选择合适的打包方式对于项目的成功至关重要。
93 3
|
1月前
|
Java Maven Android开发
【Azure Developer】VS Code打包Java maven Project 遇见 BUILD FAILURE
Unknown lifecycle phase "lean". You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>
|
2月前
|
缓存 IDE Java
idea的maven项目打包时没有source下的文件
【10月更文挑战第21天】idea的maven项目打包时没有source下的文件
85 1
|
2月前
|
Java 测试技术 Maven
maven 打包命令
maven 打包命令
36 6
|
2月前
|
Java Linux Maven
IDEA如何用maven打包(界面和命令两种方式)
【10月更文挑战第14天】本文介绍了两种Maven项目打包方法:命令行与IDEA界面。首先确保已安装Maven并配置环境变量,通过`mvn -v`检查安装。命令行打包需进入项目目录,执行`mvn package`,之后在`target`目录查看结果。IDEA打包则需配置Maven路径,打开Maven Projects窗口,双击Lifecycle下的`package`阶段,同样在`target`目录查找生成文件,并在Build窗口查看日志以排查问题。
1207 1
|
2月前
|
Java Shell Maven
Flink-11 Flink Java 3分钟上手 打包Flink 提交任务至服务器执行 JobSubmit Maven打包Ja配置 maven-shade-plugin
Flink-11 Flink Java 3分钟上手 打包Flink 提交任务至服务器执行 JobSubmit Maven打包Ja配置 maven-shade-plugin
131 4
|
2月前
|
Java Maven
用graalvm将maven项目打包成可执行文件
本文介绍了如何使用GraalVM将Maven项目打包成可执行文件,包括引入依赖和插件、编写代码、执行打包命令以及运行查看结果的完整过程。
183 0
用graalvm将maven项目打包成可执行文件
|
2月前
|
Java Maven
maven打包出现没有主类的原因,详细分析并解决
本文分析了使用Maven打包Java应用时找不到或无法加载主类的问题,通常是由于未配置主类或打包时未包含依赖,并通过添加Maven插件解决了依赖问题,同时指出了JavaFX应用可能遇到的运行时组件缺失的错误。
179 0
maven打包出现没有主类的原因,详细分析并解决
|
2月前
|
Java 应用服务中间件 Maven
SpringBoot Maven 项目打包的艺术--主清单属性缺失与NoClassDefFoundError的优雅解决方案
SpringBoot Maven 项目打包的艺术--主清单属性缺失与NoClassDefFoundError的优雅解决方案
364 0