Apache Maven Assembly自定义打包插件的使用
前言
- 本文主要记录在SpringBoot项目中使用Apache Maven Assembly插件进行打包的相关内容;
- 官网说明:https://maven.apache.org/plugins/maven-assembly-plugin/
概述
- 是什么:Apache Maven Assembly是Maven的程序集插件使开发人员能够将项目输出合并到单个可分发的存档中,该存档还包含依赖项、模块、站点文档和其他文件。
- 作用:可以实现自定义打包,从而实现打包项目可以外挂yml配置文件,提供shell运维脚本,大大降低运维成本,比较适用于小规模的SpringBoot项目(大规模的项目推荐docker容器部署)
配置说明
引入插件(pom文件中)
<?xml version="1.0" encoding="UTF-8"?>
<project>
...
<build>
<plugins>
<!--springboot项目打包插件-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.7.RELEASE</version>
<configuration>
<mainClass>com.alan.SpringBootMain</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<!--maven自定义打包插件-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<descriptors>
<!--具体的配置文件-->
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<!--绑定到maven操作类型上-->
<phase>package</phase>
<!--运行一次-->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
配置assembly文件(在pom中设定的位置下创建,我这里是src/main/assembly/assembly.xml)
<assembly>
<!--
必须写,否则打包时会有 assembly ID must be present and non-empty 错误
这个名字最终会追加到打包的名字的末尾,如项目的名字为 hangge-test-0.0.1-SNAPSHOT,
则最终生成的包名为 hangge-test-0.0.1-SNAPSHOT-bin.tar.gz
-->
<id>bin</id>
<!-- 打包的类型,如果有N个,将会打N个类型的包 -->
<formats>
<format>tar.gz</format>
<!--<format>zip</format>-->
</formats>
<includeBaseDirectory>true</includeBaseDirectory> <!--第三方依赖设置-->
<dependencySets>
<dependencySet>
<!--使用项目中的artifact,第三方包打包进tar.gz文件的lib目录下-->
<useProjectArtifact>true</useProjectArtifact>
<outputDirectory>lib</outputDirectory>
</dependencySet>
</dependencySets>
<!--文件设置-->
<fileSets>
<!--
0755->即用户具有读/写/执行权限,组用户和其它用户具有读写权限;
0644->即用户具有读写权限,组用户和其它用户具有只读权限;
-->
<!-- 将src/main/assembly/bin目录下的所有文件输出到打包后的bin目录中 -->
<fileSet>
<directory>src/main/assembly/bin</directory>
<outputDirectory>bin</outputDirectory>
<fileMode>0755</fileMode>
<!--如果是脚本,一定要改为unix.如果是在windows上面编码,会出现dos编写问题-->
<lineEnding>unix</lineEnding>
<filtered>true</filtered><!-- 是否进行属性替换 -->
</fileSet>
<!-- 将src/main/assembly/config目录下的所有文件输出到打包后的config目录中 -->
<fileSet>
<directory>src/main/assembly/config</directory>
<outputDirectory>config</outputDirectory>
<fileMode>0644</fileMode>
</fileSet>
<!-- 将src/main/resources下配置文件打包到config目录 -->
<fileSet>
<directory>src/main/resources</directory>
<outputDirectory>/config</outputDirectory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
<include>**/*.yml</include>
</includes>
<filtered>true</filtered><!-- 是否进行属性替换 -->
</fileSet>
<!-- 将项目启动jar打包到lib目录中 -->
<fileSet>
<directory>target</directory>
<outputDirectory>lib</outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
<!-- 将项目说明文档打包到docs目录中 -->
<fileSet>
<directory>.</directory>
<outputDirectory>docs</outputDirectory>
<includes>
<include>*.md</include>
</includes>
<fileMode>0644</fileMode>
</fileSet>
<fileSet>
<directory>docs</directory>
<outputDirectory>docs</outputDirectory>
<fileMode>0644</fileMode>
</fileSet>
<fileSet>
<directory>src/main/assembly/docs</directory>
<outputDirectory>docs</outputDirectory>
<fileMode>0644</fileMode>
</fileSet>
</fileSets>
</assembly>
编写运维shell脚本(在assembly中设定的位置下创建,我这里是src/main/assembly/bin)
- start.sh
#!/bin/bash
# 项目名称
SERVER_NAME="${project.artifactId}" # jar名称
JAR_NAME="${project.build.finalName}.jar" # 进入bin目录
cd `dirname $0`
# bin目录绝对路径
BIN_DIR=`pwd`
# 返回到上一级项目根目录路径
cd ..
# 打印项目根目录绝对路径
# `pwd` 执行系统命令并获得结果
DEPLOY_DIR=`pwd` # 外部配置文件绝对目录,如果是目录需要/结尾,也可以直接指定文件
# 如果指定的是目录,spring则会读取目录中的所有配置文件
CONF_DIR=$DEPLOY_DIR/config
# SERVER_PORT=`sed '/server.port/!d;s/.*=//' config/application.properties | tr -d '\r'`
# 获取应用的端口号
SERVER_PORT=`sed -nr '/port: [0-9]+/ s/.*port: +([0-9]+).*/\1/p' config/application.yml` PIDS=`ps -f | grep java | grep "$CONF_DIR" |awk '{print $2}'`
if [ "$1" = "status" ]; then
if [ -n "$PIDS" ]; then
echo "The $SERVER_NAME is running...!"
echo "PID: $PIDS"
exit 0
else
echo "The $SERVER_NAME is stopped"
exit 0
fi
fi if [ -n "$PIDS" ]; then
echo "ERROR: The $SERVER_NAME already started!"
echo "PID: $PIDS"
exit 1
fi if [ -n "$SERVER_PORT" ]; then
SERVER_PORT_COUNT=`netstat -tln | grep $SERVER_PORT | wc -l`
if [ $SERVER_PORT_COUNT -gt 0 ]; then
echo "ERROR: The $SERVER_NAME port $SERVER_PORT already used!"
exit 1
fi
fi # 项目日志输出绝对路径
LOGS_DIR=$DEPLOY_DIR/logs
# 如果logs文件夹不存在,则创建文件夹
if [ ! -d $LOGS_DIR ]; then
mkdir $LOGS_DIR
fi
STDOUT_FILE=$LOGS_DIR/catalina.log # JVM Configuration
JAVA_OPTS=" -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true "
JAVA_DEBUG_OPTS=""
if [ "$1" = "debug" ]; then
JAVA_DEBUG_OPTS=" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n "
fi JAVA_JMX_OPTS=""
if [ "$1" = "jmx" ]; then
JAVA_JMX_OPTS=" -Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false "
fi JAVA_MEM_OPTS=""
BITS=`java -version 2>&1 | grep -i 64-bit`
if [ -n "$BITS" ]; then
JAVA_MEM_OPTS=" -server -Xmx512m -Xms512m -XX:PermSize=128m -XX:+UseG1GC "
else
JAVA_MEM_OPTS=" -server -Xms512m -Xmx512m -XX:PermSize=128m -XX:+UseParallelGC "
fi # 加载外部log4j2文件的配置
LOG_IMPL_FILE=log4j2.xml
LOGGING_CONFIG=""
if [ -f "$CONF_DIR/$LOG_IMPL_FILE" ]
then
LOGGING_CONFIG="-Dlogging.config=$CONF_DIR/$LOG_IMPL_FILE"
fi
CONFIG_FILES=" -Dlogging.path=$LOGS_DIR $LOGGING_CONFIG -Dspring.config.location=$CONF_DIR/ "
echo -e "Starting the $SERVER_NAME ..."
nohup java $JAVA_OPTS $JAVA_MEM_OPTS $JAVA_DEBUG_OPTS $JAVA_JMX_OPTS $CONFIG_FILES -jar $DEPLOY_DIR/lib/$JAR_NAME > $STDOUT_FILE 2>&1 & echo "OK!"
PIDS=`ps -f | grep java | grep "$DEPLOY_DIR" | awk '{print $2}'`
echo "PID: $PIDS"
echo "STDOUT: $STDOUT_FILE"
- stop.sh
#!/bin/bash
# 项目名称
APPLICATION="${project.artifactId}"
# 项目启动jar包名称
APPLICATION_JAR="${project.build.finalName}.jar"
# 通过项目名称查找到PI,然后kill -9 pid
PID=$(ps -ef | grep "${APPLICATION_JAR}" | grep -v grep | awk '{ print $2 }')
if [[ -z "$PID" ]]
then
echo ${APPLICATION} is already stopped
else
echo kill ${PID}
kill -9 ${PID}
echo ${APPLICATION} stopped successfully
fi
- start.sh
打包项目
- 项目下执行
mvn clean package
命令进行打包,打包后的压缩包路径/project_url/target/test01-1.0-SNAPSHOT-bin.tar.gz; - 打包后的项目文件如下:
- 项目下执行
运行项目
- 解压文件:
tar -zxvf /project_url/target/test01-1.0-SNAPSHOT-bin.tar.gz
- 进入bin目录下:
cd /project_url/target/test01-1.0-SNAPSHOT/bin
- 运行项目:
sh start.sh
,运行日志在/project_url/target/test01-1.0-SNAPSHOT/logs路径下 - 关闭项目:
sh stop.sh
- 解压文件:
Apache Maven Assembly自定义打包插件的使用的更多相关文章
- maven-使用assembly自定义打包
用maven管理项目引用依赖很方便,但是打包的时候如果是web包还好,会直接把依赖的jar包打到lib目录中,如果是jar包的话,依赖默认是不打入进去的 这样如果运行环境中没有依赖的jar包,就麻烦了 ...
- Maven学习总结(27)——Maven自定义打包插件maven-assembly-plugin详解
Assembly插件会生成 "assemblies", 此特性等同于的Maven 1 distribution plug-in..该插件不仅支持创建二进制归档文件,也支持创建源码归 ...
- 05 Maven 生命周期和插件
Maven 生命周期和插件 除了坐标.依赖以及仓库之外, Maven 另外两个核心概念是生命周期和插件.在有关 Maven 的日常使用中,命令行的输入往往就对应了生命周期,如 mvn package ...
- 使用Maven的assembly插件实现自定义打包
一.背景 最近我们项目越来越多了,然后我就在想如何才能把基础服务的打包方式统一起来,并且可以实现按照我们的要求来生成,通过研究,我们通过使用maven的assembly插件完美的实现了该需求,爽爆了有 ...
- Maven的assembly插件实现自定义打包部署(包含依赖jar包)
微服务必备 优点: 1.可以直接导入依赖jar包 2.可以添加插件启动 .sh 文件 3.插件的配置以及微服务的统一打包方式 1.首先我们需要在pom.xml中配置maven的assembly插件 & ...
- 【Maven实战技巧】「插件使用专题」Maven-Assembly插件实现自定义打包
前提概要 最近我们项目越来越多了,然后我就在想如何才能把基础服务的打包方式统一起来,并且可以实现按照我们的要求来生成,通过研究,我们通过使用maven的assembly插件完美的实现了该需求,爽爆了有 ...
- Maven打包插件Assembly(七)
1. 在 dubbo 的 provider 项目(实现类项目dubbo-service-impl)中 pom.xml 配置 assembly插件信息 <!-- 指定项目的打包插件信息 --> ...
- java工程打成jar包 - 使用maven assembly插件打包及手动打包
在java工程打包的过程中遇到过不少问题,现在总结一下.一种是典型的maven工程打包,依赖的jar包全都在pom.xml中指定,这种方式打包很方便:另一种是依赖了本机jar包(不能通过pom.xml ...
- assembly打包插件引发的自定义spring标签找不到声明的错误
异常信息:通配符的匹配很全面, 但无法找到元素 的声明. 报的异常信息是关于我们使用的一个自定义的spring标签,这个异常通常的原因可能是读取不到自定义标签的映射. 到META-INF目录下找一下是 ...
- Maven Assembly插件介绍
转自:http://blueram.iteye.com/blog/1684070 已经写得挺好的,就不用重写了. 你是否想要创建一个包含脚本.配置文件以及所有运行时所依赖的元素(jar)Assembl ...
随机推荐
- 【每日一题】2021年12月11日-69. Sqrt(x)/x的平方根
给你一个非负整数 x ,计算并返回 x 的 算术平方根 . 由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 . 注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或 ...
- 解决.net Core中WebApi自动Model验证导致数据格式不能统一
简言: 最近做项目用WebAPI Core时,想把返回数据的格式,统一弄成:{"errorMsg":"xxx","Data":"x ...
- Python实验报告(第6章)
实验6:函数 一.实验目的和要求 1.掌握函数的创建和调用: 2.了解不同的参数如何进行传递: 3.了解返回值的应用: 4.学习变量的作用域: 5.学习匿名函数(lambda). 二.实验环境 软件版 ...
- Vue中实现自定义excel下载
目录 第一种:后端生成excel 第二种:前端合成excel 总结 参考资料 最近在工作中遇到一个需求,就是需要在前端实现一个错误模板Excel的下载功能. 实现下载有两种方式,一种是后端生成一个ex ...
- 记录Typescript的学习调试笔记(比 javascript更具面向对象,强类型检查,静态字段,适合现代的大团队分工与管理风格).
1.)先来一段Typescript的环境安装. 安装nodejs ,下载地址:https://nodejs.org/en/download/ //(node-v12.1 ...
- [论文总结] kmeans聚类和WGCNA
kmeans聚类和WGCNA 文章目录 kmeans聚类和WGCNA 论文1 论文2 论文3 总结 总结了3篇论文中kmeans聚类和WGCNA的运用. 论文1 Comprehensive disse ...
- 使用Python库pyqt5制作TXT阅读器(一)-------UI设计
项目地址:https://github.com/pikeduo/TXTReader PyQt5中文手册:https://maicss.gitbook.io/pyqt-chinese-tutoral/p ...
- S2-009 CVE-2011-3923
漏洞名称 CVE-2011-3923 S2-009 远程代码执行漏洞 利用条件 Struts 2.0.0 - Struts 2.3.1.1 漏洞原理 OGNL提供了广泛的表达式评估功能等功能.该漏洞允 ...
- [WPF]创建系统栏小图标
隐藏窗体任务栏图标 /// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class Ma ...
- App几个可能造成内存泄漏的情况:
App几个可能造成内存泄漏的情况: 1.block块中直接用self调用,self将会被block copy到内部增加一次饮用计数,形成循环引用 在block里调用self会不会造成循环引用和这个bl ...