This is the 9th day of my participation in Gwen Challenge
Make it a habit to like it first
Spring Boot package plugin is very nice to use, directly into the source code and all dependencies into a Jar package can be directly java-JAR run. What if a non-Spring Boot project wants to make an executable Jar package?
Don’t panic, Maven is an old build tool.
Here are some other Maven plug-ins that can also directly package Maven projects into an executable Jar package (Uber Jar/Executable Jar) with much more power and rich application scenarios.
For the name of the Uber JAR/Executable Jar, please refer to my previous article what is the Executable Jar/Uber jar/ Shade JAR /Shadow jar/ Fat Jar?
maven-dependency-plugin
The Maven-dependency plugin is a built-in plugin for Maven that, as its name suggests, handles dependencies. There are many built-in goals.
- dependency:copydependency:copy-dependencies
- dependency:unpack
- dependency:unpack-dependencies
- dependency:resolve
- dependency:sources
- dependency:resolve-plugins
- dependency:go-offline
- dependency:purge-local-repository
- dependency:analyze
- dependency:analyze-dep-mgt
- dependency:analyze-report
- dependency:tree
- dependency:build-classpath
- dependency:list-repositories
- dependency:get
Unpack-dependencies: < span style = “box-sizing: border-box; color: RGB (51, 51, 51); line-height: 22px; font-size: 14px! Important; word-break: inherit! Important;”
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-dependencies</id>
<! -- Bind to prepare-package phase -->
<phase>prepare-package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeScope>runtime</includeScope>
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Copy the code
This unpacked method will “unpack” all dependencies (internal and external), that is, copy all dependencies (classes) into outputDirectory, like a merge operation, resulting in something like this:Then give the Jar a main-class that it can execute directly:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>
com.github.kongwu.mavenbuild.BuildExample
</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
Copy the code
Of course! That’s not the only thing this plugin can do… If you look at the command above, you can see that it has a lot of functions, and this is just a small part of it.
maven-shade-plugin
Maven-shade-plugin is also a built-in plugin for Maven, which can also be directly exported as an executable Jar. Just like the dependency plug-in, this is a “decompression” mode. Put all the dependency classes together and configure a Transformer and mainClass:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.github.kongwu.mavenbuild.BuildExample</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
Copy the code
The default jar file is ${artifactId}-${version}-shaded. Jar if you don’t like it, you can modify the jar file in
The essence of this plugin is the Shade, and this “unzip” is just the basic function.
Do you think the name of this plugin is strange? What does shade mean?
Shade Jar refers to the packaging of the JAR packages and their dependencies into a JAR file that also provides the ability for shade/rename some of the dependencies
For a detailed explanation of shade, please refer to my other article “Shade Jar/Shadow Jar Explanation”.
maven-assembly-plugin
The maven-assembly-plugin is one of the most powerful build plugins in Maven. It has only one goal, but it is very, very powerful:
- Detailed build rules can be configured through a separate description file
- Contains or excludes a module/directory/file
- Support for maven filter
- A set of code to build multiple bin packages with different configurations at the same time
- Different build package formats, such as JAR /zip/tar/gz, etc
- …
Such as a Zookeeper/Nacos/Arthas/Jenkins, or more fire pulsar recently need independent operation of the software, many of them are built by this plugin
Let’s start with a simple scenario that builds an executable Jar package:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>
com.github.kongwu.mavenbuild.BuildExample
</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
Copy the code
${artifactId}-${version}-jar-with-dependencies. Jar = ${artifactId}-${version}-jar-with-dependencies
It’s a waste of time to build an Uber JAR with such a powerful plugin. If it’s just a simple Uber JAR scenario, the first two approaches will suffice.
So this plugin is more suitable for complex build needs, simple Uber JAR scenarios with this gatling level tool is a bit of a waste…
Take a look at how Nacos is used:In Nacos source code, there is a separate distribution module for building. With the assembly plugin + profile function, it is easy to build bin packages for various environments:
<! -- nacos distribution/pom.xml-->
<profile>
<id>release-nacos</id>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>nacos-console</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>release-nacos.xml</descriptor>
</descriptors>
<tarLongFileMode>posix</tarLongFileMode>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>install</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<finalName>nacos</finalName>
</build>
</profile>
<profile>
<id>release-core</id>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>nacos-core</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>release-core</id>
<goals>
<goal>single</goal>
</goals>
<phase>package</phase>
<configuration>
<descriptors>
<descriptor>release-core.xml</descriptor>
</descriptors>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<finalName>nacos-core</finalName>
</build>
</profile>
Copy the code
Nacos is also the “mainstream” way to build, and if you ever need to build a standalone package, you will use this way.
conclusion
The full code can be found at github.com/kongwu-/mav… , interested partners can pull down to try
Now that we’ve covered how to build Uber-Jar with these plug-ins, here’s a comparison:
dependency | shade | assembly | |
---|---|---|---|
advantages | Goals are rich and have many other functions besides unpack, such as clearing/viewing dependency trees and so on | Designed for Uber-Jar and with shade support, it’s the only option if you need to relocate | The most powerful, very flexible configuration, but no shade function |
disadvantages | After all, it’s just a plug-in that handles dependencies and is weak on the build side | With complex build requirements, the functionality is somewhat inadequate | There is no shade function, and the configuration is complicated |
Application scenarios | Suitable for simple Uber-JAR features | Perfect for Uber-JAR construction, it works perfectly with shade | Suitable for building in complex scenarios, not just uber Jars |
This article introduces three plug-ins that have different mechanisms for building Uber JARS than Spring Boot:
The Spring Boot build plugin will place dependent jars inside uber Jars in a “jars-in-a-jar” way, using its custom ClassLoader to load jars inside jars. The above plug-ins do not interfere with mainClass and ClassLoader, and cannot load Jar packages within Jar packages, so they are “unpacked”.
Note that Spring Boot build plug-ins are not only available in Spring Boot projects. Its core functionality is still build, just replace the Boot class with Spring Boot and load it through its custom ClassLoader.
Therefore, it is perfectly ok to package some non-Spring (Boot) projects into an Uber JAR using spring-boot-Maven-plugin, as long as the JDK and Maven versions match.
reference
For details on the functions of these plugins, please refer to the official documentation for the following plugins. Maven’s documentation is quite detailed:
- Juejin. Cn/post / 694161…
- Maven.apache.org/plugins/mav…
- Maven.apache.org/plugins/mav…
- Maven.apache.org/plugins/mav…
- Maven.apache.org/plugins/mav…
- Github.com/alibaba/nac…
Free side dishes
Attached is a life cycle diagram of Maven Default redrawn by myself, which is relatively clear, indicating different goals of different plugins corresponding to each phase. If necessary, save it by yourself (the original diagram is a little larger, click to view the larger one).
Original is not easy, prohibit unauthorized reprint. Like/like/follow my post if it helps you ❤❤❤❤❤❤