maven的打包插件如何使用

news2025/7/8 5:00:12

默认的情况下,当直接执行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>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>com.example.MainClass</mainClass> <!-- 如果需要打包可执行jar,可以在这里指定主类,不过一般用不着,和混编一般是应用在数据引擎或实时处理上的,对应的引擎有主类的指定,直接上传一个jar包就好 -->
                                </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>
                        </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.coloradmin.cn/o/2285148.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Controller 层优化四步曲

Controller 层优化四步曲 前言 在开发过程中&#xff0c;Controller 层作为系统与外界交互的桥梁&#xff0c;承担着接收请求、解析参数、调用业务逻辑、处理异常等职责。 然而&#xff0c;随着业务复杂度的增加&#xff0c;Controller 层的代码往往会变得臃肿且难以维护。 …

Java后端之AOP

AOP&#xff1a;面向切面编程&#xff0c;本质是面向特定方法编程 引入依赖&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>示例&#xff1a;记录…

中文输入法方案

使用了三年的自然码双拼&#xff0c;毫无疑问是推荐使用双拼输入法。 三年积累下来的习惯是&#xff1a; 1 自然码方案 2 空格出字 字母选字 直到如今&#xff0c;想要做出改变&#xff0c;是因为这样的方案带来的痛点&#xff1a; 1 使用空格出字就无法使用辅助码&#…

Julius AI 人工智能数据分析工具介绍

Julius AI 是一款由 Casera Labs 开发的人工智能数据分析工具&#xff0c;旨在通过自然语言交互和强大的算法能力&#xff0c;帮助用户快速分析和可视化复杂数据。这款工具特别适合没有数据科学背景的用户&#xff0c;使数据分析变得简单高效。 核心功能 自然语言交互&#x…

机器学习day4

自定义数据集 使用pytorch框架实现逻辑回归并保存模型&#xff0c;然后保存模型后再加载模型进行预测 import numpy as np import torch import torch.nn as nn import torch.optim as optimizer import matplotlib.pyplot as pltclass1_points np.array([[2.1, 1.8],[1.9, 2…

LVGL+FreeRTOS实战项目:智能健康助手(蓝牙模块篇)

HC-05 蓝牙模块简介 功能&#xff1a;支持串口通信的蓝牙模块&#xff0c;广泛应用于无线数据传输。支持 AT 指令配置。 接口&#xff1a;UART 通信&#xff0c;默认波特率为 9600bps。 应用&#xff1a;无线调试、数据传输、无线控制等。 硬件连接 HC-05 引脚功能STM32 连…

【愚公系列】《循序渐进Vue.js 3.x前端开发实践》029-组件的数据注入

标题详情作者简介愚公搬代码头衔华为云特约编辑&#xff0c;华为云云享专家&#xff0c;华为开发者专家&#xff0c;华为产品云测专家&#xff0c;CSDN博客专家&#xff0c;CSDN商业化专家&#xff0c;阿里云专家博主&#xff0c;阿里云签约作者&#xff0c;腾讯云优秀博主&…

Redis学习之哨兵二

一、API 1.sentinel masters:展示被监控的主节点状态及相关的统计信息 2.sentinel master <master name>:展示指定的主节点的状态以及相关的统计信息 3.sentinel slaves <master name>:展示指定主节点的从节点状态以及相关的统计信息 4.sentinel sentinels <mas…

【Linux基础指令】第二期

本期博客的主题依旧是 "基础指令" &#xff1b; 上一期的基础指令链接&#xff1a; 【Linux基础指令】第一期-CSDN博客 &#xff0c;话不多说&#xff0c;正文开始&#xff1a; 一、Linux的指令 1.cp 拷贝功能&#xff1a; cp [stc] [dest] # 将 src文件 拷贝到…

MySQL(表空间)

​开始前先打开此图配合食用 MySQL表空间| ProcessOn免费在线作图,在线流程图,在线思维导图 InnoDB 空间文件中的页面管理 后面也会持续更新&#xff0c;学到新东西会在其中补充。 建议按顺序食用&#xff0c;欢迎批评或者交流&#xff01; 缺什么东西欢迎评论&#xff01;我都…

C26.【C++ Cont】动态内存管理和面向对象的方式实现链表

&#x1f9e8;&#x1f9e8;&#x1f9e8;&#x1f9e8;&#x1f9e8;&#x1f9e8;&#x1f9e8;&#x1f9e8;&#x1f9e8;除夕篇&#x1f9e8;&#x1f9e8;&#x1f9e8;&#x1f9e8;&#x1f9e8;&#x1f9e8;&#x1f9e8;&#x1f9e8;&#x1f9e8; 目录 1.知识回顾…

求解旅行商问题的三种精确性建模方法,性能差距巨大

文章目录 旅行商问题介绍三种模型对比求解模型1决策变量目标函数约束条件Python代码 求解模型2决策变量目标函数约束条件Python代码 求解模型3决策变量目标函数约束条件Python代码 三个模型的优势与不足 旅行商问题介绍 旅行商问题 (Traveling Salesman Problem, TSP) 是一个经…

C++:多继承习题3

题目内容&#xff1a; 声明一个时间类Time&#xff0c;时间类中有3个私有数据成员(Hour&#xff0c;Minute&#xff0c;Second)和两个公有成员函数(SetTime和PrintTime)。要求&#xff1a; &#xff08;1&#xff09; SetTime根据传递的3个参数为对象设置时间&#xff1b; &a…

低代码系统-产品架构案例介绍、得帆云(八)

产品名称 得帆云DeCode低代码平台-私有化 得帆云DeMDM主数据管理平台 得帆云DeCode低代码平台-公有云 得帆云DePortal企业门户 得帆云DeFusion融合集成平台 得帆云DeHoop数据中台 名词 概念 云原生 指自己搭建的运维平台&#xff0c;区别于阿里云、腾讯云 Dehoop 指…

【Unity3D】实现Decal贴花效果,模拟战旗游戏地形效果

目录 一、基础版 二、Post Process 辉光Bloom效果 矩形渐隐 涉及知识点&#xff1a;Decal贴花、屏幕后处理Bloom、屏幕空间构建世界空间、ChracterController物体移动、Terrain地形创建 一、基础版 Unity 2019.4.0f1 普通渲染管线&#xff08;非URP、非HDRP&#xff09; UR…

实践网络安全:常见威胁与应对策略详解

&#x1f4dd;个人主页&#x1f339;&#xff1a;一ge科研小菜鸡-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 引言 在数字化转型的浪潮中&#xff0c;网络安全的重要性已达到前所未有的高度。无论是个人用户、企业&#xff0c;还是政府机构…

UART、I2C和SPI对比

UARTSPII2C英文Universal Asynchronous Receive/TransmitSerial Peripheral InterfaceInner Integrated Communication通讯速度115200、38400 bit/s高达100M bit/s 100k、400k、1M、3.4M bit/s时钟同/异步性时钟异步时钟同步时钟同步接线方式3线(Rx、Tx、GND) 4线(MISO、…

开源项目Umami网站统计MySQL8.0版本Docker+Linux安装部署教程

Umami是什么&#xff1f; Umami是一个开源项目&#xff0c;简单、快速、专注用户隐私的网站统计项目。 下面来介绍如何本地安装部署Umami项目&#xff0c;进行你的网站统计接入。特别对于首次使用docker的萌新有非常好的指导、参考和帮助作用。 Umami的github和docker镜像地…

KIMI K1.5:用大语言模型扩展强化学习(论文翻译)

文章目录 KIMI K1.5技术报告摘要 1. 引言2. 方法&#xff1a;基于大语言模型的强化学习2.1 强化学习提示集整理2.2 长思维链监督微调2.3 强化学习2.3.1 问题设定2.3.2 策略优化2.3.3 长度惩罚2.3.4 采样策略2.3.5 训练方法的更多细节 2.4 长到短&#xff1a;短思维链模型的上下…

思科交换机telnet配置案例

目录 1.telnet简述2.网络拓扑3.设备说明4.网络配置4.1 电脑PC ip设置4.2 网络交换机telnet配置 5.小结 1.telnet简述 Telnet是远程登录服务的一个协议&#xff0c;该协议定义了远程登录用户与服务器交互的方式。它允许用户在一台联网的计算机上登录到一个远程分时系统中&#…