Spring Boot Packaging with Maven Assembly Plugin and Deployment Shell Script (shenniu_publish.sh)
This article explains how to use Maven profiles and the maven‑assembly‑plugin to create environment‑specific Spring Boot zip packages, configure the accompanying assembly.xml, and deploy them on Linux with a custom shenniu_publish.sh script that supports unzip, start, stop and restart operations.
The guide demonstrates building a Spring Boot application for multiple environments (dev, test, uat, prod) by defining Maven <profiles> with properties such as activeProfile, package-name, and boot-main. Two methods are described: setting profile.active in application.yml or using Maven profiles to generate separate packages, with the latter being recommended.
In the Maven pom.xml, a series of profiles ( node, node1, node2) are configured, each providing values for the properties that will be substituted into the assembly and shell scripts. The activeByDefault flag selects the default profile.
1 <profiles>
2 <profile>
3 <id>node</id>
4 <properties>
5 <!-- parameters passed to the script -->
6 <activeProfile>node</activeProfile>
7 <package-name>${scripts_packageName}</package-name>
8 <boot-main>${scripts_bootMain}</boot-main>
9 </properties>
10 <activation>
11 <activeByDefault>true</activeByDefault>
12 </activation>
13 </profile>
... (other profiles omitted for brevity)
30 </profiles>The maven-assembly-plugin together with maven-jar-plugin creates a zip archive that contains the compiled jar, configuration files, and the deployment script. Important plugin settings include mainClass (the entry point), excludes (to keep config files out of the jar), and descriptor (pointing to assembly.xml).
1 <plugin>
2 <groupId>org.apache.maven.plugins</groupId>
3 <artifactId>maven-jar-plugin</artifactId>
4 <version>2.6</version>
5 <configuration>
6 <archive>
7 <addMavenDescriptor>false</addMavenDescriptor>
8 <manifest>
9 <addClasspath>true</addClasspath>
10 <classpathPrefix>lib/</classpathPrefix>
11 <mainClass>${scripts_bootMain}</mainClass>
12 </manifest>
13 </archive>
14 <excludes>
15 <exclude>**/*.yml</exclude>
16 <exclude>**/*.properties</exclude>
17 <exclude>**/*.xml</exclude>
18 <exclude>**/*.sh</exclude>
19 </excludes>
20 </configuration>
21 </plugin>
... (assembly plugin configuration omitted for brevity)The accompanying assembly.xml defines the zip format, disables the base directory, and specifies dependencySets and fileSets to place libraries under conf/lib, configuration files under conf, the shell script under the root, and the built jar in the package directory.
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0" ...>
<id>${activeProfile}</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<useProjectArtifact>false</useProjectArtifact>
<outputDirectory>${package-name}-${activeProfile}/lib</outputDirectory>
<unpack>false</unpack>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>${project.basedir}/src/main/profiles/${activeProfile}</directory>
<outputDirectory>${package-name}-${activeProfile}/conf</outputDirectory>
<includes><include>**/*</include></includes>
</fileSet>
<fileSet>
<directory>${project.basedir}/src/main/scripts</directory>
<outputDirectory>/</outputDirectory>
<includes><include>**/*</include></includes>
<fileMode>777</fileMode>
<directoryMode>777</directoryMode>
<filtered>true</filtered>
</fileSet>
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory>${package-name}-${activeProfile}/</outputDirectory>
<includes><include>*.jar</include></includes>
</fileSet>
</fileSets>
</assembly>The shenniu_publish.sh script provides functions to unzip the package, detect the running process ID, start the application (supporting java -cp and java -jar modes), stop it, and handle command‑line arguments such as start, stop, restart, and unzip. It also includes a helper to convert the script to Unix line endings when edited on Windows.
#!/usr/bin/env bash
# variable definitions
languageType="javac" # java, javac, netcore
baseZipName="${package-name}-${activeProfile}"
packageName="${package-name}"
mainclass="${boot-main}"
function shenniu_unzip() {
echo "解压..."
if [ ! `find ${baseZipPath}` ]; then
echo "不存在压缩包:${baseZipPath}"
else
unzip -od ${baseDirPath}/${baseZipName} ${baseZipPath}
chmod +x ${baseDirPath}/${baseZipName}/${packageName}
echo "解压完成。"
fi
}
function getPid() {
pid=`ps -ef | grep -n ${packageName} | grep -v grep | awk '{print $2}'`
if [ ${pid} ]; then echo "运行pid:${pid}"; else echo "未运行"; fi
}
function start() {
stop
if [ ${pid} ]; then echo "停止程序失败,无法启动"; else
echo "启动程序..."
read -p "输入程序类型(java,javac,netcore) (默认:${languageType}):" read_languageType
if [ ${read_languageType} ]; then languageType=${read_languageType}; fi
cd ${baseDirPath}/${baseZipName}
if [ "${languageType}" == "javac" ]; then
nohup java -cp conf:lib/*.jar:${packageName}.jar ${mainclass} > ${baseDirPath}/${packageName}.out 2>&1 &
elif [ "${languageType}" == "java" ]; then
nohup java -jar ${baseDirPath}/${baseZipName}/${packageName}.jar > /dev/null 2>&1 &
elif [ "${languageType}" == "netcore" ]; then
nohup ${baseDirPath}/${baseZipName}/${packageName} > /dev/null 2>&1 &
fi
getPid
if [ ${pid} ]; then echo "已启动"; else echo "启动失败"; fi
fi
}
function stop() {
getPid
if [ ${pid} ]; then
echo "停止程序..."
kill -9 ${pid}
getPid
if [ ${pid} ]; then echo "停止失败"; else echo "停止成功"; fi
fi
}
if [ $# -ge 1 ]; then
case $1 in
"start") start ;;
"restart") start ;;
"stop") stop ;;
"unzip") shenniu_unzip; start ;;
*) echo "$1 无任何操作" ;;
esac
else
echo "命令如下:
unzip:解压并启动
start:启动
stop:停止进程
restart:重启
示例:./shenniu_publish.sh start"
fiAfter building the zip, upload it to the Linux server, unzip it (or let the script do it), and run ./shenniu_publish.sh start. If the script was edited on Windows, convert it to Unix format with vim and set ff=unix. The article concludes that the script reliably starts, stops, and restarts the Spring Boot service and provides a GitHub link for the full project.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Architect
Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
