Like it first, then watch it, develop a good habit
The packaging plug-in of Spring Boot is very cool to use, directly tying the source code and all dependencies into a Jar package can also run java -jar
So what if it is not a Spring Boot project and you want to make an executable Jar package?
Don't panic, Maven is a veteran build tool, it's not easy to get this done!
Here are some other Maven plug-ins, you can also directly package the Maven project into an executable Jar package (uber jar/executable jar), and it has more powerful functions and richer application scenarios!
For the origin of the name of this uber jar/executable jar, please refer to my previous article "Executable Jar/Uber Jar/Shade Jar/Shadow Jar/Fat Jar What is it? 》
maven-dependency-plugin
maven-dependency-plugin is a built-in plugin of Maven. As you can see from the name, its function is to handle dependencies. There are many goals built in, and the functions are very complete:
- 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
By unpack-dependencies
the target of decompress the dependent package/source code , an all-in-one packaging method can be completed:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-dependencies</id>
<!-- 绑定到 prepare-package 阶段 -->
<phase>prepare-package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeScope>runtime</includeScope>
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
This unpack method will "decompress" all dependent packages (internal module dependencies and external module dependencies), which means that the code (class) of the dependent packages will be copied to the outputDirectory directory, which is similar to a merge operation, and the result is like this:
Then assign a main-class to Jar so that it can be executed 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>
of course! This plug-in can do more than just this kind of things... Just look at the above commands and you will know that it has many functions, and only one of its small functions is introduced here.
maven-shade-plugin
maven-shade-plugin is also a built-in plug-in of Maven, you can also directly type an executable Jar. It has the same effect as the dependency plug-in. It is also a "decompression" mode. Put all the classes of the dependent packages 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>
The default jar file after the build is: ${artifactId}-${version}-shaded.jar
, if you don’t like it, you can also modify the output jar file <outputFile>
plug-in lies in the shade, and this "decompression" is only the basic function.
Do you think the name of this plugin is strange, what does shade
The shade machine turns into shadows and masks. Shade jar refers to packaging the jar package and its dependent packages into a jar file, and provides the function of shade "masking/renaming" some dependent packages
shade
a detailed explanation of 060d1362169899, please refer to my other article "Shade Jar/Shadow Jar Explanation"
maven-assembly-plugin
The last maven-assembly-plugin plug-in, which is the strongest build plugin , although it has only one useful goal, but the function is really very powerful:
- Detailed construction rules can be configured through a separate description file
- Include or exclude a module/directory/file
- Support maven filter
- One 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 Zookeeper/Nacos/Arthas/Jenkins, or the recently popular pulsar and other software that needs to run independently, many of them are built with this plug-in
First look at a simple scenario of it, and build 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>
The effect is the same as the above two plug-ins, both are "decompression" methods, the default built file is ${artifactId}-${version}-jar-with-dependencies.jar
With such a powerful plug-in, it is a bit too wasteful to build an uber jar with it. If it is just a simple uber jar scenario, the first two methods are enough.
Therefore, this plug-in is more suitable for complex construction requirements. The simple uber jar
scene is a little wasteful of using this Gatling-level tool...
Let's take a look at the usage in Nacos:
In the source code of Nacos, a distribution module is separately used for construction. With the assembly plug-in + profile function, you can easily 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>
Nacos is a relatively "mainstream" method of construction. If you have a need to build a standalone package someday, I believe you will use this method too.
to sum up
The complete code is placed at https://github.com/kongwu-/maven-build-examples/blob/master/pom.xml , interested friends can pull it down and try
Well, after introducing the gameplay of these plug-ins to build uber-jar, let's make a comparison:
dependency | shade | assembly | |
---|---|---|---|
advantage | The goals are rich, in addition to unpack, there are many other functions, such as cleaning/viewing the dependency tree, etc. | It is specially designed for uber-jar and supports the shade function. If there is a need for relocation, you can only choose it | The strongest function, the configuration is very flexible, but there is no shade function |
Disadvantage | After all, it's just a plug-in that handles dependencies, and its function in terms of construction is relatively weak. | Under complex construction requirements, the functions will be somewhat insufficient | There is no shade function, and the configuration is more complicated |
Application scenario | Suitable for simple uber-jar functions | Most suitable for the construction of uber-jar, it is perfect with the shade function | Suitable for construction in complex scenarios, not only uber jar |
The three plug-ins introduced in this article are different from Spring Boot in the mechanism of uber jar
The Spring Boot build plug-in will put the dependent Jar package in uber jar
, which is a "jars-in-a-jar" way, through its custom ClassLoader to load the Jar package in the Jar package; and the above introduced Several plug-ins do not interfere with mainClass and ClassLoader, and cannot load the Jar package in the Jar package, so they all use the "decompression" method.
Note that Spring Boot's build plug-in can not only be used in Spring Boot projects. Its core function is still construction, just replace the startup class with Spring Boot, and then load it through its custom ClassLoader.
Therefore, using spring-boot-maven-plugin
to package some non-Spring (Boot) projects into a uber jar
is no problem at all, just match the JDK and Maven versions.
reference
For the detailed functions of the above plugins, you can refer to the official documentation of the following plugins. The Maven documentation is more detailed:
- https://juejin.cn/post/6941618160386703390
- http://maven.apache.org/plugins/maven-dependency-plugin/index.html
- http://maven.apache.org/plugins/maven-jar-plugin/
- http://maven.apache.org/plugins/maven-shade-plugin/
- http://maven.apache.org/plugins/maven-assembly-plugin/index.html
- https://github.com/alibaba/nacos
Free side dishes
Attached is a Maven default life cycle diagram redrawn by myself, which is quite clear, indicating the different goals of different plugins corresponding to each phase, and save it if necessary (the original image is slightly larger, click to view the larger image)
Originality is not easy, unauthorized reprinting is prohibited. If my article is helpful to you, please like/favorite/follow to encourage and support it ❤❤❤❤❤❤
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。