mvn 打包jar,排除第三方依赖包,maven常用插件

问题背景
maven-历史版本下载
https://archive.apache.org/dist/maven/maven-3/

Spring Boot 项目一般会依赖较多的包括 Spring 在内的第三方 jar 包,直接打可运行 jar 包,文件大小往往会达到100M甚至更大;

在重复部署测试或者生产环境的时候,每次都要上传包含所有依赖 jar 包的可运行 jar 文件,效率比较低;

期望目标
maven 配置,Spring Boot 项目打包时,只包含自己开发的代码,大小仅100kb,所依赖的第三方 jar 则复制到指定的目录下;

这样我们可以只需要上传一次第三方 jar,每次修改代码重新部署时,只上传仅包含我们开发代码的 jar 文件,大大提高了部署效率。

解决方法
maven 的 pom 配置如下,${} 变量根据自己的项目进行替换,第三方 jar 指定到 target/lib 目录下:

<plugins>
    <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
            <source>${java.version}</source>
            <target>${java.version}</target>
            <encoding>UTF-8</encoding>
        </configuration>
    </plugin>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
            <!-- 跳过单元测试 -->
            <skipTests>true</skipTests>
        </configuration>
    </plugin>

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <executions>
            <!-- 复制第三方 jar 到项目目录下的 target/lib/ 下 -->
            <execution>
                <goals>
                    <goal>copy-dependencies</goal>
                </goals>
                <configuration>
                    <outputDirectory>${project.build.directory}/lib</outputDirectory>
                    <excludeScope>provided</excludeScope>
                </configuration>
            </execution>
        </executions>
    </plugin>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
            <archive>
                <manifest>
                    <!-- 指定 Spring Boot 启动类,实际测试中必须 -->
                    <mainClass>${project.main.class}</mainClass>
                    <!-- 将所有第三方 jar 添加到项目 jar 的 MANIFEST.MF 文件中,这样运行 jar 时依赖包才能被加载 -->
                    <addClasspath>true</addClasspath>
                    <!-- 指定复制第三方 jar 的目标目录为 target/lib/-->
                    <classpathPrefix>./lib/</classpathPrefix>
                </manifest>
            </archive>
        </configuration>
    </plugin>
    <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <!-- repackage 时排除掉 第三方依赖 jar 文件,我们的可运行 Spring Boot 的 jar 文件瞬间变小 ^_^ -->
        <executions>
            <execution>
                <goals>
                    <goal>repackage</goal>
                </goals>
            </execution>
        </executions>
        <configuration>
            <includes>
                <include>
                    <groupId>nothing</groupId>
                    <artifactId>nothing</artifactId>
                </include>
            </includes>
        </configuration>
    </plugin>
</plugins>

附录: Maven几个常用的maven插件

简介
我们使用maven做一些日常的工作开发的时候,无非是想利用这个工具带来的一些便利。比如依赖管理,方便我们打包和部署运行。这里几个常见的插件就是和这些工程中常用的步骤相关。
  1. maven-compile-plugin
    这个插件就如同名字所显示的这样,用来编译源代码的。最开始碰到这个插件是在于有的时候我们下载了一些工程需要编译的时候,比如我们输入命令:mvn install ,但是系统编译的时候报错了,错误的信息如下:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.0.2:compile (default-compile) on project springJMS: Compilation failure: Compilation failure:  
[ERROR] /home/frank/programcode/SpringJMSSample/src/main/java/huangbowen/net/jms/MessageSender.java:[6,1] error: annotations are not supported in -source 1.3  
[ERROR]   
[ERROR] (use -source 5 or higher to enable annotations)  
[ERROR] /home/frank/programcode/SpringJMSSample/src/main/java/net/EmbedBrokerApp.java:[5,7] error: static import declarations are not supported in -source 1.3  
[ERROR] -> [Help 1]  
[ERROR]   
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.  
[ERROR] Re-run Maven using the -X switch to enable full debug logging.  
[ERROR]   
[ERROR] For more information about the errors and possible solutions, please read the following articles:  

从错误显示的信息我们就可以看出,这是因为编译的时候是默认用的javac 1.3版本的,太老了不支持代码里的特性。为了修改这个问题,我们需要设置编译器的版本。解决这个问题的办法也比较简单,就是直接在后面的插件部分增加如下的插件,比如如下部分,将编译器的版本设定为1.6:

<build>  
      <plugins>  
        <plugin>  
            <groupId>org.apache.maven.plugins</groupId>  
            <artifactId>maven-compiler-plugin</artifactId>  
            <version>2.3.2</version>  
            <configuration>  
                <source>1.6</source>  
                <target>1.6</target>  
            </configuration>  
        </plugin>  
      </plugins>  
    </build>  
  1. exec-maven-plugin
    我们写一些java console相关的程序时,比较头疼的一点就是真正要通过命令行将打包后的程序执行起来还是比较麻烦的。我们需要在命令行里敲如下的命令:java -cp .jar:.jar:/*/ 。因为要将classpath目录以及引用的类库都加入进来,并指定运行的入口,这样子每次用手工的方式来处理实在是太繁琐也比较容易出错。所以一种办法就是利用这个插件,通过一些基本的配置,我们可以执行起代码来的时候很方便。一个典型的配置如下:
<plugin>  
   <groupId>org.codehaus.mojo</groupId>  
   <artifactId>exec-maven-plugin</artifactId>  
   <version>1.2.1</version>  
   <executions>  
     <execution>  
       <goals>  
         <goal>java</goal>  
       </goals>  
     </execution>  
   </executions>  
   <configuration>  
     <mainClass>com.yunzero.App</mainClass>  
   </configuration>  
 </plugin>  

如果我们运行的时候需要提供一些输入的参数,也可以通过configuration的元素里添加。这样后续要执行这个程序时,我们只需要在命令行执行如下命令:mvn exec:java ,然后程序就可以运行起来了。

  1. maven-dependency-plugin
    这个插件可以做什么事情呢?由goal标签指定
copy:将指定坐标对应的jar包拷贝到指定目录
unpack:将指定坐标对应的jar包解压到指定目录

3.1 copy
下述配置在打包阶段会将junit包拷贝到项目的target/alternateLocation目录下

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>3.2.0</version>
            <executions>
                <execution>
                    <id>copy</id>
                    <phase>package</phase>
                    <goals>
                        <goal>copy</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <artifactItems>
                    <artifactItem>
                        <groupId>junit</groupId>
                        <artifactId>junit</artifactId>
                        <version>3.8.1</version>
                        <type>jar</type>
                        <overWrite>false</overWrite>
                        <outputDirectory>${project.build.directory}/alternateLocation</outputDirectory>
                    </artifactItem>
                </artifactItems>
            </configuration>
        </plugin>
————————————————

3.2 copy-dependencies
和copy命令的区别是,copy是拷贝指定坐标的jar包,而copy-dependencies则是拷贝项目依赖的所有jar包,具体用法如下

<plugin>   
    <artifactId>maven-dependency-plugin</artifactId>   
        <executions>   
        <execution>   
            <phase>install</phase>   
            <goals>   
                <goal>copy-dependencies</goal>   
            </goals>   
            <configuration>   
                <outputDirectory>${project.build.directory}/lib</outputDirectory>   
            </configuration>   
        </execution>   
    </executions>   
</plugin>  

从上面的配置里我们可以看到,插件的执行被配置到install这个阶段,当然也可以是 package 阶段
这样,当我们执行命令:mvn clean install 的时候,会发现对应的target目录里生成了对应的jar包和依赖包。

3.3 unpack
unpack命令可以将指定的jar包解压到指定的目录,需要注意的是,如果指定的触发阶段为compile,那么解压之后的内容会一起打包到当前项目中,而如果是package则不会,它只会打包自己项目内容

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>3.2.0</version>
    <executions>
        <execution>
            <!-- 为该操作定义一个名字 -->
            <id>unpack</id>
            <!-- 该操作在生命周期的那个阶段触发 -->
            <phase>compile</phase>
            <goals>
                <!-- 插件的具体操作,这里只介绍4种-->
                <goal>unpack</goal>
            </goals>
            <!-- 操作的配置 -->
            <configuration>
                <!-- 配置 -->
                <artifactItems>
                    <!-- 具体配置,此处一般是针对某个坐标的具体配置 -->
                    <artifactItem>
                        <!-- 指定坐标 -->
                        <groupId>org.example.it</groupId>
                        <artifactId>po.webresource</artifactId>
                        <version>1.0-SNAPSHOT</version>
                        <type>jar</type>
                        <overWrite>true</overWrite>
                        <!-- 输出路径 -->
                        <outputDirectory>${project.build.directory}/classes</outputDirectory>
                        <!-- 坐标对应的jar包的名称 -->
                        <destFileName>po.webresource-1.0-SNAPSHOT.jar</destFileName>
                        <!-- 操作的内容 -->
                        <includes>**/*.html,**/*.js</includes>
                        <!-- 排除的内容 -->
                        <excludes>**/*test.html</excludes>
                    </artifactItem>
                </artifactItems>
            </configuration>
        </execution>
    </executions>
</plugin>

3.4 unpack-dependencies
和unpack命令的区别是,unpack是解压指定坐标的jar包,而unpack-dependencies则是解压项目依赖的所有jar包,具体用法如下

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>3.2.0</version>
    <executions>
        <execution>
            <id>unpack-dependencies</id>
            <phase>package</phase>
            <goals>
                <goal>unpack-dependencies</goal>
            </goals>
            <configuration>
                <includes>**/*.class</includes>
                <excludes>**/*.properties</excludes>
                <outputDirectory>${project.build.directory}/alternateLocation</outputDirectory>
                <overWriteReleases>false</overWriteReleases>
                <overWriteSnapshots>true</overWriteSnapshots>
            </configuration>
        </execution>
    </executions>
</plugin>

4-1. maven-surefire-plugin 打包时跳过单元测试

<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.6</version>
    <configuration>
        <skip>true</skip>
    </configuration>
</plugin>
同: mvn package -Dmaven.test.skip=true

4-2. 如果单元测试中有输出中文,eclipse的控制台里中文可能会变成乱码输出,也可以通过这个插件解决,参考配置:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.16</version>
    <configuration>
        <forkMode>once</forkMode>
        <argLine>-Dfile.encoding=UTF-8</argLine>
</plugin>
  1. maven-resource-plugin 设置资源文件的编码方式
<plugin>  
    <groupId>org.apache.maven.plugins</groupId>  
    <artifactId>maven-resources-plugin</artifactId>  
    <version>2.4.3</version>  
    <executions>  
        <execution>  
            <phase>compile</phase>  
        </execution>  
    </executions>  
    <configuration>  
        <encoding>${project.build.sourceEncoding}</encoding>  
    </configuration>  
</plugin>  
  1. maven-assembly-plugin
    有时候我们需要将项目依赖抽出来单独打包,或者将项目里面的html、js等静态资源抽取出来打包,就需要用到这个插件了。插件的使用如下
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>3.1.0</version>
    <executions>
        <execution>
            <!-- 操作名,自己指定 -->
            <id>assembly</id>
            <!-- 操作触发的阶段 -->
            <phase>package</phase>
            <goals>
                <!-- 只执行一次-->
                <goal>single</goal>
            </goals>
            <configuration>
                <!-- 自己指定的名字,和assemblies.xml配置文件中的id标签对应 -->
                <finalName>html</finalName>
                <!-- 配置文件的位置和名字(与pom.xml)的相对路径-->
                <descriptors>assemblies.xml</descriptors>
            </configuration>
        </execution>
    </executions>
</plugin>

除了需要在pom中配置上述内容外,还需要引入一个配置文件assemblies.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>html</id>
    <formats>
        <!-- 生成一个zip文件 -->
        <format>zip</format>
    </formats>
    <fileSets>
        <fileSet>
            <!-- 从编译后的文件中拷贝 -->
            <directory>${project.build.directory}/classes</directory>
            <!-- 拷贝到的文件存放的路径 -->
            <outputDirectory></outputDirectory>
            <useDefaultExcludes>true</useDefaultExcludes>
            <excludes>
                <!-- 哪些文件不拷贝 -->
                <exclude>**/*.log</exclude>
                <exclude>**/${project.build.directory}/**</exclude>
            </excludes>
        </fileSet>
    </fileSets>
</assembly>
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Maven 是一个非常常用Java 项目构建工具,使用 Maven 打包 jar 可以方便地将项目打包成一个可执行的 Jar ,使得项目的发布、部署等工作变得轻松快捷。下面我将详细介绍如何使用 Maven 打包 jar。 首先,需要确保电脑上已经安装了 Maven。在安装好 Maven 之后,可以使用 Maven 的命令行工具进行操作。进入到要打包的项目的根目录下,执行以下命令: ```bash mvn clean package ``` 其中 `clean` 表示删除之前编译的类和 jar 文件,`package` 表示将项目打包成一个 jar 文件。 在执行命令之后,Maven 会自动编译项目代码,将编译好的类文件和依赖的库文件打包成一个 jar 文件,并将其放置在项目的 `target` 文件夹下。 在这个过程中,如果项目依赖的库没有被安装到本地仓库或中央仓库中,Maven 会自动从中央仓库或其他配置好的仓库下载并安装这些依赖库。 如果需要指定 jar 文件的名称和路径,可以在 `pom.xml` 文件中进行配置。在 `build` 标签中添加以下代码: ```xml <finalName>${project.artifactId}-${project.version}</finalName> <outputDirectory>./target</outputDirectory> ``` 其中 `finalName` 指定了 jar 文件的名称,`${project.artifactId}` 表示项目的名称,`${project.version}` 表示项目的版本号;`outputDirectory` 指定了 jar 文件输出的目录。 除了使用命令行打包 jar,也可以在 Maven 的开发工具中(如 Eclipse、IntelliJ IDEA 等)直接使用打包插件进行操作。 总之,使用 Maven 打包 jar 是一个非常便捷的操作,可以方便地将项目打包成一个可执行的 Jar ,并将其部署到不同的环境中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值