前言

  1. 本文主要记录在SpringBoot项目中使用Apache Maven Assembly插件进行打包的相关内容;
  2. 官网说明:https://maven.apache.org/plugins/maven-assembly-plugin/

概述

  • 是什么:Apache Maven Assembly是Maven的程序集插件使开发人员能够将项目输出合并到单个可分发的存档中,该存档还包含依赖项、模块、站点文档和其他文件。
  • 作用:可以实现自定义打包,从而实现打包项目可以外挂yml配置文件,提供shell运维脚本,大大降低运维成本,比较适用于小规模的SpringBoot项目(大规模的项目推荐docker容器部署)

配置说明

  1. 引入插件(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>
  1. 配置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>
  1. 编写运维shell脚本(在assembly中设定的位置下创建,我这里是src/main/assembly/bin)
  2. 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    fifiif [ -n "$PIDS" ]; then    echo "ERROR: The $SERVER_NAME already started!"    echo "PID: $PIDS"    exit 1fiif [ -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    fifi# 项目日志输出绝对路径LOGS_DIR=$DEPLOY_DIR/logs# 如果logs文件夹不存在,则创建文件夹if [ ! -d $LOGS_DIR ]; then    mkdir $LOGS_DIRfiSTDOUT_FILE=$LOGS_DIR/catalina.log# JVM ConfigurationJAVA_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 "fiJAVA_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 "fiJAVA_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.xmlLOGGING_CONFIG=""if [ -f "$CONF_DIR/$LOG_IMPL_FILE" ]then    LOGGING_CONFIG="-Dlogging.config=$CONF_DIR/$LOG_IMPL_FILE"fiCONFIG_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"
  1. stop.sh
#!/bin/bash# 项目名称APPLICATION="${project.artifactId}"# 项目启动jar包名称APPLICATION_JAR="${project.build.finalName}.jar"# 通过项目名称查找到PI,然后kill -9 pidPID=$(ps -ef | grep "${APPLICATION_JAR}" | grep -v grep | awk '{ print $2 }')if [[ -z "$PID" ]]then    echo ${APPLICATION} is already stoppedelse    echo kill  ${PID}    kill -9 ${PID}    echo ${APPLICATION} stopped successfullyfi
  1. 打包项目
  2. 项目下执行mvn clean package命令进行打包,打包后的压缩包路径/project_url/target/test01-1.0-SNAPSHOT-bin.tar.gz;
  3. 打包后的项目文件如下:



多模块 assembly打包 assembly插件打包_Powered by 金山文档


  1. 运行项目
  2. 解压文件:tar -zxvf /project_url/target/test01-1.0-SNAPSHOT-bin.tar.gz
  3. 进入bin目录下:cd /project_url/target/test01-1.0-SNAPSHOT/bin
  4. 运行项目:sh start.sh,运行日志在/project_url/target/test01-1.0-SNAPSHOT/logs路径下
  5. 关闭项目:sh stop.sh