当前位置: 首页 > article >正文

maven的打包插件如何使用

默认的情况下,当直接执行maven项目的编译命令时,对于结果来说是不打第三方包的,只有一个单独的代码jar,想要打一个包含其他资源的完整包就需要用到maven编译插件,使用时分以下几种情况

第一种:当只是想单纯的开发一个maven项目,不涉及其他复杂的项目结构,最后只需要一个全部资源可执行jar,就用如下插件pom

<build>
        <plugins>
            <!-- Maven Assembly Plugin 是maven官方的编译打包插件-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.3.0</version>
                <!-- 插件的配置参数相关-->
                <configuration>
                    <!-- 当你在打可执行包,也就是结果包是一个jar时,可以指定主类-->
                    <archive>
                        <manifest>
                            <mainClass>com.yourpackage.MainClass</mainClass> <!-- 指定主类 -->
                        </manifest>
                    </archive>
                    <!-- 这里需要给一个结果包的后缀,用来区分-->
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <!-- 插件的执行阶段定义,可以有多个,不过一般一个打包的就够了 -->
                <executions>
                    <execution>
                        <!-- 这个id是自定的,保证有多个执行阶段的时候是唯一的就行 -->
                        <id>make-assembly</id>
                        <!-- 这个执行阶段在maven的那个阶段生效,这里绑定在打包时生效 -->
                        <phase>package</phase>
                        <!-- 这个single是固定的不用变,意思是根据给定的或者默认的配置来执行编译,默认时是打当前项目的所有dependencies为一个完整包,这个参数不要过多纠结官方文档中也只有这个,你要能力够可以自己封装 -->
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
</build>

打包后项目的输出路径下,除了原本的最小jar外,会有一个包名包含jar-with-dependencies的jar
在这里插入图片描述
第二种:assembly是一个比较好用的编译插件,无论是单独打jar,还是整个项目打归档类的包,都能胜任,不过早些年ssm那个时代,Java常用的编译插件是compiler,这个插件现在也有人用,不过它在打包的时候常常出问题,所以用它来打包的话,保险起见要指定resources。同时它只能打jar包,并且不能指定主类,在ssm这种web开发使用到的比较多,而 Spring boot之后官方提供了自己的编译插件,再加上它没有assembly那么好用,所以现在用的不多

<build>
        <plugins>
            <!-- maven在进行一些编译操作所使用的插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>

		<resources>
            <resource>
                <directory>src/main/java</directory><!--所在的目录-->
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>

            <resource>
                <directory>src/main/resources</directory><!--所在的目录-->
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
        
    </build>

第三种:在多数情况下项目结构比较复杂,比如父子项目,或者需要打一些其他特别的资源文件到结果包中,又或者结果不止需要插件打默认的jar包,因此除非是某个模块或者项目真的就只打一个简单的完整包会使用第一种编译方式外,其他情况需要提供assembly完整的打包说明文件,使用方式如下

首先在需要的项目pom中声明打包用的插件。这里注意一下,一定要把所有需要打包的资源放在一个专门用来打包的子模块中,因为这个插件没办法跨项目打资源,总之我这边本地是尝试了之后没发现能跨模块打资源的方法,最多能做到按照描述文件各打各的,但是然并朊啊

    <build>
        <plugins>
            <plugin>
                <!-- 插件和版本 -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.3.0</version>
                <!-- 这里!!!!需要给插件提供一个打包阶段的描述文件,并且当你这样使用的时候,第一种情况的主类和前缀配置就不要配了,一来是大概率不生效,二来这种给定描述文件的方式通常是用来打归档类结果文件的,也就是tar这种,而不是一个单一的可执行jar -->
                <configuration>
                    <descriptors>
                        <!-- ${project.basedir}是maven自带的变量,可以获取当前项目的根路径 -->
                        <descriptor>${project.basedir}/assembly.xml</descriptor>
                    </descriptors>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

下面是描述文件的内容

<assembly>

    <!-- 设置结果集的id,最后会作为结果文件名的后缀 -->
    <id>bin</id>

    <!-- 指定结果集的格式,可以支持zip, tar, tar.gz等,可以写多个结果就会有对应的多个 -->
    <formats>
        <format>tar.gz</format>
    </formats>

   <includeBaseDirectory>true</includeBaseDirectory>

    <!-- 指定结果集中包含的文件集 -->
    <fileSets>
        <fileSet>
            <directory>${project.basedir}/bin</directory>
            <outputDirectory>/bin</outputDirectory>
            <includes>
                <include>*</include>
            </includes>
            <fileMode>0644</fileMode>
        </fileSet>

    </fileSets>

    <!-- 指定程序集中包含的依赖项集,这个一般使用的时候就是固定的格式 -->
    <dependencySets>
        <dependencySet>
            <!-- 包含所有依赖项,到lib -->
            <outputDirectory>/lib</outputDirectory>
            <!-- 包含项目自身的jar -->
            <useProjectArtifact>true</useProjectArtifact>
            <!-- 还可以指定依赖即便但是一般不写,打全部的 <scope>runtime</scope>-->
        </dependencySet>
    </dependencySets>

</assembly>

上面这个文件内容是通常情况下的使用内容,一般也够了,但是描述文件中还有其他的标签可以用,你可以在网上查它的约束消息,下面一些可能会用到的标签,大家参考一下就行了

<assembly>
    
    <!-- 设置结果集的id,最后会作为后缀 -->
    <id>bin</id>

    <!-- 指定结果集的格式,可以支持zip, tar, tar.gz等 -->
    <formats>
        <format>tar.gz</format>
        <format>dir</format>
    </formats>

    <!-- 在结果集中是否包含一个基本目录,默认值是true,就好比我们使用开源软件解压之后是个完整的目录,而不是全部在当前目录解压所有文件 -->
    <includeBaseDirectory>true</includeBaseDirectory>

    <!-- 设置生成程序集存档的基本目录名,如果没有设置并且includeBaseDirectory为true,
         则使用${project.build.finalName}作为基本目录名,一般都用默认的 -->
    <baseDirectory>${project.build.finalName}</baseDirectory>

    <!-- 在最终档案中是否包含一个站点目录,默认值是false,这个只有在特殊情况在可能用true -->
    <includeSiteDirectory>false</includeSiteDirectory>

    <!-- 这个很少会用到,它是用来让插件自动合并或定制一些文件,比如多个properties文件聚合成一个,有需要的话网上找找案例就行 -->
    <containerDescriptorHandlers>
        <containerDescriptorHandler>
            <handlerName>metaInf-services</handlerName>
            <configuration>
                <!-- 配置选项,具体根据需求填写 -->
            </configuration>
        </containerDescriptorHandler>
    </containerDescriptorHandlers>

    <!-- 指定包含在程序集中的模块文件,这个也用的很少,因为程序运行的jar一般会打到一个固定的路径下,而且如果你的使用方式和我一样,那么需要的资源就已经在一个专门编译用的子模块下了,不会涉及到从其他模块里面再去指定 -->
    <moduleSets>
        <moduleSet>
            <!-- 包含当前项目的所有模块 -->
            <useAllReactorProjects>true</useAllReactorProjects>
            
            <!-- 指定包含或排除的模块 -->
            <includes>
                <include>com.example:my-module</include>
            </includes>
            <excludes>
                <exclude>com.example:excluded-module</exclude>
            </excludes>
            
            <!-- 设置输出目录 -->
            <outputDirectory>modules</outputDirectory>
        </moduleSet>
    </moduleSets>

    <!-- 指定程序集中包含的文件集,这个很长用 -->
    <fileSets>
        <fileSet>
            <directory>src/main/resources</directory>
            <outputDirectory>conf</outputDirectory>
            <includes>
                <include>*.xml</include>
                <include>*.properties</include>
            </includes>
            <fileMode>0644</fileMode>
        </fileSet>
    </fileSets>

    <!-- 指定程序集中包含的依赖项集 -->
    <dependencySets>
        <dependencySet>
            <!-- 包含所有依赖项 -->
            <outputDirectory>lib</outputDirectory>
            <scope>runtime</scope>
        </dependencySet>
    </dependencySets>
</assembly>

第四种情况:Maven项目可以用来Java和Scala混编,但是上面的maven-assembly-plugin编译不了scala文件,所以需要用下面的两个插件配合,一个是java的,一个是scala的,先编译最后统一用shade打包,但是这种方式只能打可执行jar,至于混编下打tar包, 目前还没有遇到这种情况。

<build>
        <!-- 这里规定插件版本 -->
        <pluginManagement>
            <plugins>
                <!-- 编译scala的插件 -->
                <plugin>
                    <groupId>net.alchim31.maven</groupId>
                    <artifactId>scala-maven-plugin</artifactId>
                    <version>3.2.2</version>
                </plugin>
                <!-- 编译java的插件 -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.5.1</version>
                </plugin>
            </plugins>
        </pluginManagement>
        
        <plugins>
            <!-- 规定Scala怎么编译 注意这里只规定编译,不规定打包-->
            <plugin>
                <groupId>net.alchim31.maven</groupId>
                <artifactId>scala-maven-plugin</artifactId>
                <executions>
                    <!-- 这两个 Execution,规定编译源码添加资源 ,第2个测试编译可以不要-->
                    <execution>
                        <id>scala-compile-first</id>
                        <phase>process-resources</phase>
                        <goals>
                            <goal>add-source</goal>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>scala-test-compile</id>
                        <phase>process-test-resources</phase>
                        <goals>
                            <goal>testCompile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <!-- 这里是规定怎么编译java -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
                <executions>
                    <!-- 作用和上面的一样,只不过这里不用显示的调用add来添加资源 -->
                    <execution>
                        <phase>compile</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            
            <!-- shade插件用来把上面的所有资源统一打包成一个新的jar -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.4.3</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <filters>
                                <filter>
                                    <!-- 打包所有的资源,并过滤中间文件 -->
                                    <artifact>*:*</artifact>
                                    <excludes>
                                        <exclude>META-INF/*.SF</exclude>
                                        <exclude>META-INF/*.DSA</exclude>
                                        <exclude>META-INF/*.RSA</exclude>
                                    </excludes>
                                </filter>
                            </filters>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

第五种:一般情况下需要自己找插件的就这上面几种情况,市面上有些架构有自己的编译插件,比如上面提到的springboot,springboot的编译插件相当简洁,整个spring Boot框架能把能砍掉的繁杂配置步骤全砍了,编译完会有两个结果,用没有后缀的就行

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <mainClass>com.example.bootweb.BootWebApplication</mainClass>
    </configuration>
</plugin>


http://www.kler.cn/a/522635.html

相关文章:

  • 小白爬虫冒险之反“反爬”:无限debugger、禁用开发者工具、干扰控制台...(持续更新)
  • Django ORM解决Oracle表多主键的问题
  • GPU上没程序在跑但是显存被占用
  • 思维练习题
  • Redis常用命令合集【一】
  • OpenBMC:编译
  • CNN-GRU卷积门控循环单元时间序列预测(Matlab完整源码和数据)
  • 在做题中学习(81):替换后的重复字符
  • L30.【LeetCode题解】丢失的数字
  • 【无标题】TensorFlow、PyTorch、ONNX、TensorRT
  • 认知计算与 AI 大模型:数据仓库、数据湖与数据分析的变革力量
  • 《SwinIR:使用Swin-Transformer图像恢复》学习笔记
  • 深度解析:基于Vue 3与Element Plus的学校管理系统技术实现
  • LVGL+FreeRTOS实战项目:智能健康助手(lcd篇)
  • Java学习笔记(二十五)
  • Python面向对象编程实战:构建强大的 `Person` 类
  • CSS知识总结
  • zookeeper-3.8.3-基于ACL的访问控制
  • 私域流量池构建与转化策略:以开源链动2+1模式AI智能名片S2B2C商城小程序为例
  • Hive详细讲解-调优分区表速通
  • The Simulation技术浅析(二):模型技术
  • Python爬虫获取custom-1688自定义API操作接口
  • 【异步编程基础】FutureTask基本原理与异步阻塞问题
  • constexpr 实现编译时加密
  • Spark入门(Python)
  • python基础语法(4) ----- 学习笔记分享