前言

  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. js将时间戳转成时间格式

    let start_time = 1653007401082, date = new Date(+start_time), Y = date.getFullYear() + '-', M = (dat ...

  2. vivo 故障定位平台的探索与实践

    作者:vivo 互联网服务器团队- Liu Xin.Yu Dan 本文基于故障定位项目的实践,围绕根因定位算法的原理进行展开介绍.鉴于算法有一定的复杂度,本文通过图文的方式进行说明,希望即使是不懂技术 ...

  3. S2-048 CVE-2017-9791 远程命令执行

    漏洞名称 S2-048 CVE-2017-9791 远程命令执行 利用条件 Struts 2.3.x 开启Struts 1 plugin and Struts 1 action插件 漏洞原理 漏洞产生 ...

  4. CF构造题1600-1800(1)

    D. Same Count One(Polynomial Round 2022 (Div. 1 + Div. 2, Rated, Prizes!)) 题意 给定 \(n\) 个长度为 \(m\) 的 ...

  5. (21)go-micro微服务logstash使用

    目录 一 Logstash介绍 二 Logstash作用 三 Logstash工作原理 四 Logstash安装 1.拉取镜像 2.运行命令 3.查看是否运行 五 Logstash使用 六 最后 一 ...

  6. ng-alain全局配置NzMessageService

    官方文档是这样子的,抄下来会报错,因为没有后两个设置 import { NgZorroAntdModule, NzConfig, NZ_CONFIG } from 'ng-zorro-antd'; c ...

  7. 使用docker安装hadoop(已实现)

    1.拉镜像 这里推荐第一个 docker pull registry.cn-hangzhou.aliyuncs.com/hadoop_test/hadoop_base 或者 docker pull q ...

  8. java跨域问题解决

    问题描述:在使用前后端分离的情况下,前端访问后端时会出现跨域问题 解决方式: 1.设置跨域 1).单个控制器方法CORS注解 在单个方法中加入注解@CrossOrigin. 2).整个控制器启用COR ...

  9. 【学习笔记】开源库之 - sigslot (在解决浅拷贝问题的基础上增加信号拦截功能)

    前言说明 在文中<[学习笔记]开源库之 - sigslot (提供该库存在对象拷贝崩溃问题的解决方案)>已经介绍过 sigslot ,此文主要应用在实际的工作项目中时,发现会有拦截信号的需 ...

  10. 【Rust学习】内存安全探秘:变量的所有权、引用与借用

    作者:京东零售 周凯 一.前言 Rust 语言由 Mozilla 开发,最早发布于 2014 年 9 月,是一种高效.可靠的通用高级语言.其高效不仅限于开发效率,它的执行效率也是令人称赞的,是一种少有 ...