Backend Development 13 min read

Spring Boot Packaging with Maven Assembly Plugin and a Deployment Shell Script

This article explains how to configure Maven profiles for different environments, use the maven‑assembly‑plugin and maven‑jar‑plugin to create a zip deployment package for a Spring Boot application, and provides a reusable shell script (shenniu_publish.sh) for extracting, starting, stopping, and restarting the service on Linux.

Code Ape Tech Column
Code Ape Tech Column
Code Ape Tech Column
Spring Boot Packaging with Maven Assembly Plugin and a Deployment Shell Script

The author introduces a method to package a Spring Boot application using Maven profiles to separate configuration for development, testing, UAT, and production environments. Two approaches are described: setting profile.active in application.yml and defining profiles in the Maven pom.xml . The article focuses on the latter.

In the Maven pom.xml , a <profiles> section is added with multiple <profile> entries (e.g., node , node1 , node2 ). Each profile defines properties such as activeProfile , package-name , and boot-main , and activates by default when appropriate.

<profiles>
  <profile>
    <id>node</id>
    <properties>
      <activeProfile>node</activeProfile>
      <package-name>${scripts_packageName}</package-name>
      <boot-main>${scripts_bootMain}</boot-main>
    </properties>
    <activation>
      <activeByDefault>true</activeByDefault>
    </activation>
  </profile>
  ...
</profiles>

The maven-assembly-plugin and maven-jar-plugin are configured to produce a zip file that contains the compiled JAR, external configuration files, and the deployment shell script. Important plugin settings include disabling the Maven descriptor, adding a classpath entry, specifying the main class, and defining exclusion patterns for configuration files.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <version>2.6</version>
  <configuration>
    <archive>
      <addMavenDescriptor>false</addMavenDescriptor>
      <manifest>
        <addClasspath>true</addClasspath>
        <classpathPrefix>lib/</classpathPrefix>
        <mainClass>${scripts_bootMain}</mainClass>
      </manifest>
    </archive>
    <excludes>
      <exclude>**/*.yml</exclude>
      <exclude>**/*.properties</exclude>
      <exclude>**/*.xml</exclude>
      <exclude>**/*.sh</exclude>
    </excludes>
    <executions>
      <execution>
        <id>make-a-jar</id>
        <phase>compile</phase>
        <goals><goal>jar</goal></goals>
      </execution>
    </executions>
  </configuration>
</plugin>
... (assembly plugin configuration omitted for brevity) ...

The accompanying assembly.xml defines the structure of the zip package: a formats node set to zip , file sets for the compiled JAR, configuration files, and the shell script, and permissions (fileMode and directoryMode) set to 777 . The filtered flag ensures that Maven properties are substituted into the script.

<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0" ...>
  <id>${activeProfile}</id>
  <formats><format>zip</format></formats>
  <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>
      <fileMode>777</fileMode>
      <directoryMode>777</directoryMode>
      <filtered>true</filtered>
    </fileSet>
    ...
  </fileSets>
</assembly>

After building the zip, the author shares the shenniu_publish.sh script. The script can unzip the package, set execution permissions, detect running processes, and start, stop, or restart the Java service using either java -cp (with a specified main class) or java -jar . It also supports a placeholder for .NET Core binaries.

#!/usr/bin/env bash
# Variable parameters passed from Maven
languageType="javac" # java, javac, netcore
baseZipName="${package-name}-${activeProfile}"
packageName="${package-name}"
mainclass="${boot-main}"

basePath=$(cd `dirname $0`/; pwd)
baseZipPath="${basePath}/${baseZipName}.zip"
baseDirPath="${basePath}"
pid=

function shenniu_unzip() { ... }
function getPid() { ... }
function start() { ... }
function stop() { ... }

if [ ${#} -ge 1 ]; then
  case ${1} in
    "start") start ;;
    "restart") start ;;
    "stop") stop ;;
    "unzip") shenniu_unzip; start ;;
    *) echo "${1} has no action" ;;
  esac
else
  echo "Commands: unzip, start, stop, restart"
fi

To use the script on Linux, the zip is transferred to the server, unzipped (e.g., unzip -od eureka-server-0.0.1-node eureka-server-0.0.1-node.zip ), and the file format is converted to Unix line endings with vim ( set ff=unix ). After that, the script can be executed with commands such as ./shenniu_publish.sh start , and it will start the Spring Boot service, displaying logs or indicating success/failure.

The article concludes with a link to the GitHub repository containing the full project and a call for readers to follow, like, and share the content.

backendDeploymentMavenSpring Bootshell script
Code Ape Tech Column
Written by

Code Ape Tech Column

Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.