My Spring Boot project has build description:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.18.1</version> <dependencies> <dependency> <groupId>org.apache.maven.surefire</groupId> <artifactId>surefire-junit47</artifactId> <version>2.18.1</version> </dependency> </dependencies> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${spring-boot.version}</version> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> <configuration> <mainClass>com.app.MainClass</mainClass> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build>
I want my JAR file name to be app-1.0-SNAPSHOT.jar
in one branch and 1.0-RELEASE.jar
in another, controlled by Jenkins (using some kind of mvn settings or JVM argument such as -D..
Can I do this?
A Spring Boot application is typically built into a single executable JAR archive. It contains all dependencies inside, packaged as nested JARs. Likewise, a Spring Boot project is usually built as an executable JAR file by a provided maven plugin that does all the dirty work.
The Executable Jar File Structure. Application classes should be placed in a nested BOOT-INF/classes directory. Dependencies should be placed in a nested BOOT-INF/lib directory.
The Spring Boot Maven Pluginimplement a custom ClassLoader to locate and load all the external jar libraries now nested inside the package. automatically find the main() method and configure it in the manifest, so we don't have to specify the main class in our java -jar command.
So simple, In one branch, you have pom.xml
with
<build> <finalName>app-1.0-SNAPSHOT</finalName> </build>
In other branch, you have pom.xml
with
<build> <finalName>1.0-RELEASE</finalName> </build>
You can propagate the version of the project to your build name like this:
<build> <finalName>app-${project.version}</finalName> </build>
or the version of your parent project if you have one:
<build> <finalName>app-${parent.version}</finalName> </build>
Then you would keep track of you project version rather than the build name.
However, note that managing the build verson in SCM using branches is a pain in the neck and error prone. It is rather recommanded that your code repository woud be agnostic of your build version.
A possible alternative would be to use some release management tool, like maven release plugin
, or even more simple maven version
.
Example:
Here I'll give and example using maven verion
.
Say you're using SCM tool (it could be git
) and a build factory (like Jenkins
or any other tool). Say you have a job to build and deploy snapshots and another one for releases.
In the snapshot job, you can set-up a pre-build task with the following maven target:
versions:set -DnewVersion=app-1.0-SNAPSHOT
and the following in the release job:
versions:set -DnewVersion=app-1.0-RELEASE
Now doing this is OK, because you are only doing it locally and never have to manage the build version in your code.
Now, you can tag your (release) version after having applied maven version
and build successfuly (hopefuly including unit, integration and functional tests). This way you may keep track exactly of the code that has been deployed on each release.
Tip!! Space is money! Do yourself a favour: clean your snapshot repository regularly. Creating a job that does so every once in a while shouldn't be to difficult.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With