Maven has a variety of fancy builds, and can print executable Jar packages without SpringBoot

 

 

The packaged plug-in of Spring Boot is very cool to use. It can directly type the source code and all dependencies into a Jar package, and it can also run directly in Java Jar. What if a non Spring Boot project wants to make an executable Jar package? ​

Don't panic, Maven is an old building tool. It's not easy to get this done! ​

Here are some other Maven plug-ins, which can also directly package Maven project into an executable Jar package (uber jar/executable jar), with more powerful functions and richer application scenarios! ​

maven-dependency-plugin

Maven dependency plugin is a built-in plug-in of Maven. It can be seen from its name that its function is to handle dependencies. There are many built-in goals with full functions:

  • 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 unpacking the dependent packages / source codes with the goal of "unpack dependencies", you can complete an all in one packaging method:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-dependency-plugin</artifactId>
  <executions>

    <execution>
      <id>unpack-dependencies</id>
      <!-- Bind to prepare-package stage -->
      <phase>prepare-package</phase>
      <goals>
        <goal>unpack-dependencies</goal>
      </goals>
      <configuration>
        <includeScope>runtime</includeScope>
        <outputDirectory>${project.build.outputDirectory}</outputDirectory>
      </configuration>
    </execution>
  </executions>
</plugin>

In this unpack ing method, all dependent packages (internal module dependency and external module dependency) will be "decompressed", that is, the code (class) of the dependent package will be copied to the outputDirectory directory, which is similar to a merge operation. The result is like this:Then specify a main class for Jar to directly execute:

<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 that... Look at the commands above. It has many functions. Here is only a small function.

maven-shade-plugin

Maven shade plugin is also a built-in plug-in of Maven. You can also type an executable Jar directly. Like the dependency plug-in, it is also a "decompression" mode. Put all the classes that depend on the package 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 construction is ${artifactid} - ${version} - shaded Jar. If you don't like it, you can also modify the output jar file through < outputFile >

The essence of this plug-in lies in the shade, and this "decompression" is only a basic function.

Do you think the plug-in name is strange? What does shade mean?

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

maven-assembly-plugin

Finally, the maven assembly plugin is the strongest build plugin in maven. Although it has only one useful goal, its function is really very powerful:

  1. Detailed build rules can be configured through independent description files
  2. Include or exclude a module / directory / file
  3. Support maven filter
  4. A set of code to build multiple bin packages with different configurations at the same time
  5. Different build package formats, such as jar/zip/tar/gz, etc
  6. ......

For example, Zookeeper/Nacos/Arthas/Jenkins, or pulsar, which is popular recently, and many other software that need to run independently, are built with this plug-in

Let's look at a simple scenario 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>

Like the above two plug-ins, they are "decompressed". The default built file is ${artifactid} - ${version} - jar with dependencies jar​

For such a powerful plug-in, it's a bit wasteful to build a uber jar. If it's just a simple uber jar scenario, the first two methods are enough.

Therefore, this plug-in is more suitable for complex construction requirements. In a simple uber jar scenario, taking this Gatling level tool is a bit wasteful

Let's take a look at how Nacos is used:In the source code of Nacos, a distribution module is placed separately for construction. With the help of assembly plug-in + profile function, it is convenient 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>

This construction method of Nacos is also a "mainstream" method. If you need to build an independent running package one day, I believe you will use this method.

summary

The complete code can be added to my QQ: 3177181324. Interested partners can try it

Well, after introducing the playing methods of building Uber jar by these plug-ins, let's make a comparison:

 dependencyshadeassembly
advantagegoals is rich. In addition to unpack, there are many other functions, such as cleaning / viewing dependency trees and so onIt is designed for Uber jar and supports the shade function. If there is a need for relocation, you can only choose itThe function is the strongest and the configuration is very flexible, but there is no shade function
shortcomingAfter all, it is only a plug-in to deal with dependencies, and its function in construction is relatively weakUnder complex construction requirements, there will be some deficiencies in functionsThere is no shade function, and the configuration is complex
Application scenarioSuitable for simple Uber jar functionIt is most suitable for the construction of Uber jar and is perfect with the function of shadeIt is suitable for building in complex scenarios, not just uber jar

The three plug-ins introduced in this article are different from Spring Boot in the mechanism of building "uber jar":

The Spring Boot build-up plug-in will type the dependent Jar package in "uber jar", which is a "jars-in-a-jar" method, and load the Jar package in the Jar package through its custom ClassLoader; The plug-ins described above do not interfere with mainClass and ClassLoader and cannot load the Jar package in the Jar package, so they are all "decompressed". ​

Note that the build plug-in of Spring Boot can not only be used in Spring Boot projects. Its core function is to build, just replace the startup class with Spring Boot, and then load it through its custom ClassLoader. ​

Therefore, it's no problem to package some non Spring(Boot) projects into a "uber jar" with spring boot Maven plugin. Just match the versions of JDK and Maven.


If I think the article is helpful to you, please praise, comment and collect. Your support is my biggest motivation!!!

Finally, Xiaobian sorted out some learning materials during the learning process, which can be shared with Java engineers and friends to exchange and learn from each other, If necessary, you can join my learning exchange group 323432957 to obtain Java architecture learning materials for free (including architecture materials of multiple knowledge points such as high availability, high concurrency, high performance and distribution, Jvm performance tuning, Spring source code, MyBatis, Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx, etc.)

Author: dingyu002

Source: dinyu002

The copyright belongs to the author. For commercial reprint, please contact the author for authorization. For non-commercial reprint, please indicate the source.

Keywords: Java Programming Spring Spring Boot Distribution

Added by crunchyfroggie on Fri, 28 Jan 2022 04:42:37 +0200