前言

  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>
  2. 配置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>
  3. 编写运维shell脚本(在assembly中设定的位置下创建,我这里是src/main/assembly/bin)

    1. 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"
    2. 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
  4. 打包项目

    1. 项目下执行mvn clean package命令进行打包,打包后的压缩包路径/project_url/target/test01-1.0-SNAPSHOT-bin.tar.gz;
    2. 打包后的项目文件如下:

  5. 运行项目

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

Apache Maven Assembly自定义打包插件的使用的更多相关文章

  1. maven-使用assembly自定义打包

    用maven管理项目引用依赖很方便,但是打包的时候如果是web包还好,会直接把依赖的jar包打到lib目录中,如果是jar包的话,依赖默认是不打入进去的 这样如果运行环境中没有依赖的jar包,就麻烦了 ...

  2. Maven学习总结(27)——Maven自定义打包插件maven-assembly-plugin详解

    Assembly插件会生成 "assemblies", 此特性等同于的Maven 1 distribution plug-in..该插件不仅支持创建二进制归档文件,也支持创建源码归 ...

  3. 05 Maven 生命周期和插件

    Maven 生命周期和插件 除了坐标.依赖以及仓库之外, Maven 另外两个核心概念是生命周期和插件.在有关 Maven 的日常使用中,命令行的输入往往就对应了生命周期,如 mvn package ...

  4. 使用Maven的assembly插件实现自定义打包

    一.背景 最近我们项目越来越多了,然后我就在想如何才能把基础服务的打包方式统一起来,并且可以实现按照我们的要求来生成,通过研究,我们通过使用maven的assembly插件完美的实现了该需求,爽爆了有 ...

  5. Maven的assembly插件实现自定义打包部署(包含依赖jar包)

    微服务必备 优点: 1.可以直接导入依赖jar包 2.可以添加插件启动 .sh 文件 3.插件的配置以及微服务的统一打包方式 1.首先我们需要在pom.xml中配置maven的assembly插件 & ...

  6. 【Maven实战技巧】「插件使用专题」Maven-Assembly插件实现自定义打包

    前提概要 最近我们项目越来越多了,然后我就在想如何才能把基础服务的打包方式统一起来,并且可以实现按照我们的要求来生成,通过研究,我们通过使用maven的assembly插件完美的实现了该需求,爽爆了有 ...

  7. Maven打包插件Assembly(七)

    1. 在 dubbo 的 provider 项目(实现类项目dubbo-service-impl)中 pom.xml 配置 assembly插件信息 <!-- 指定项目的打包插件信息 --> ...

  8. java工程打成jar包 - 使用maven assembly插件打包及手动打包

    在java工程打包的过程中遇到过不少问题,现在总结一下.一种是典型的maven工程打包,依赖的jar包全都在pom.xml中指定,这种方式打包很方便:另一种是依赖了本机jar包(不能通过pom.xml ...

  9. assembly打包插件引发的自定义spring标签找不到声明的错误

    异常信息:通配符的匹配很全面, 但无法找到元素 的声明. 报的异常信息是关于我们使用的一个自定义的spring标签,这个异常通常的原因可能是读取不到自定义标签的映射. 到META-INF目录下找一下是 ...

  10. Maven Assembly插件介绍

    转自:http://blueram.iteye.com/blog/1684070 已经写得挺好的,就不用重写了. 你是否想要创建一个包含脚本.配置文件以及所有运行时所依赖的元素(jar)Assembl ...

随机推荐

  1. Linux系统CentOS6找回密码解决方法

    1.首先在开机启动的时候快速按键盘上的"E"键 或者"ESC"键,会进入如下界面,按E键: 2.出现下面这个界面,选择第二项以kernel开头,再次按" ...

  2. JavaScript:输出语法

    主要有三种,如下所示:

  3. 【nginx】代理设置Host

    旧文章从语雀迁移过来,原日期为2021-02-18 nginx 的 proxy 模块使我们经常会用到的模块之一,比如我们常用的 nginx 反向代理. 反向代理我们一般有这么几行配置代码: locat ...

  4. python实现单向循环链表与双向链表

    目录 单向循环链表 操作 实现 双向链表 操作 实现 单向循环链表 单链表的一个变形是单向循环链表,链表中最后一个节点的next域不再为None,而是指向链表的头节点. 操作 is_empty() 判 ...

  5. ArcGIS工具 - 导出空数据库

    有时,需要根据已有的成果数据创建一个空的数据库模板文件,用于新的编辑或对外发布.那么,如果又快又好的创建呢?为源GIS为您编写了一个导出空数据库工具,它可以实现"一键"快速导出任意 ...

  6. ChatGPT 背后的“功臣”——RLHF 技术详解

    OpenAI 推出的 ChatGPT 对话模型掀起了新的 AI 热潮,它面对多种多样的问题对答如流,似乎已经打破了机器和人的边界.这一工作的背后是大型语言模型 (Large Language Mode ...

  7. Quartz 使用教程

    首先说说,为什么要写这篇文章: Quartz 的 v2.3.2 版本改动比较大,目前网上的资料都是旧版本,很缺乏相关资料 很多资料讲解非常不全面,例如 Quartz Listener 的介绍和使用基本 ...

  8. mysql常用命令,检查数据库连接情况以及修改时区

    常用操作 注:也可以运行 mysql -u 用户名(root) -p 密码(root) 数据库名(bank) ,然后回车 导入文件:source e:bank.sql (你的sql文件) 回车 PS ...

  9. 使用json数据动态创建表格2(多次绘制第一次简化 var tr=tbody.insertRow();)

    <!DOCTYPE HTML> <html> <head> <title>动态创建表格</title> <meta charset=& ...

  10. django框架之drf:2、restful规范,序列、反序列化,drf安装及使用(django原生接口及drf接口编写)

    Django之drf 一.restful规范 1.概念 ​ REST全称是Representational State Transfer,中文意思是表述:表征性状态转移,它首次出现在2000年Roy ...