Using spring boot packaging plug-in to remove jar package and reduce weight

Time:2022-5-5

1. POM file configuration

1.1 add Maven dependency plugin to copy the referenced jar package to the specified path

It is convenient to specify the dependent package path for subsequent Tomcat startup

<!-- Copy the dependency to the Lib directory outside the jar -- >
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy</id>
            <phase>package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>                <!-- Specified dependency path -- >
                <outputDirectory>
                    ${project.build.directory}/lib
                </outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

After using this plug-in to build the directory structure, there is an additional lib directory (i.e. the path specified in the outputdirectory configured above), which is the dependent jar package:

1.2 spring boot project uses spring boot Maven plugin to package plug-ins

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <executable>true</executable>
     <layout>ZIP</layout>
        <mainClass>
            com.iasp.BasicStarter
        </mainClass>
        <!-- Include only yourself -- >
        <includes>
            <include>
                <groupId>${groupId}</groupId>
                <artifactId>${artifactId}</artifactId>
            </include>
         <!-- Or -- >
           <!-- Dependent jars do not enter the project jar package -- >
             <!--<include>
                  <groupId>nothing</groupId>
                  <artifactId>nothing</artifactId>
             </include>-->
        </includes>
        <!-- What are not included -- >
        <!--<excludeGroupIds>-->
            <!--com.hundsun.jrescloud,-->
            <!--org.springframework.boot,-->
            <!--org.springframework-->
        <!--</excludeGroupIds>-->
    </configuration>

    <executions>
        <execution>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
</plugin>

After configuring the above packaging, the corresponding jar package will be excluded, so that the size of the flat jar package printed by the plug-in becomes smaller, which is convenient for the upload server to publish. The effect is as follows: the Lib directory under the boot-inf directory is gone:

The structure in the original jar package is

Then specify the jar package path – dloader. Exe when starting the project Path = “.. / lib”, which can achieve the slimming effect. Put the dependency in the D: develop / shared / fjar directory and execute the run command


java -Dloader.path="D:develop/shared/fjar" -jar mytest.jar

Note: another startup scheme is not to add – dloader Path = “D: develop / shared / fjar” to specify the path, and directly use the following instructions to start


java -jar mytest.jar

To use the above startup, you need to add Maven jar plugin plug-in and configure the < classpathprefix > attribute. In addition, when processing some files read from executable jars, you can use Maven jar plugin plug-in to replace spring boot Maven plugin for packaging

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <!-- Addclasspath indicates that it needs to be added to the class construction path -- >
                <addClasspath>true</addClasspath>
                <!-- Classpathprefix specifies that the path is added before the class path dependent Lib in the generated manifest file to build lib / XX jar-->
                <classpathPrefix>lib/</classpathPrefix>
                <mainClass>com.common.util.CommonUtilsApplication</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

The above plug-in effect is meta in the bag_ Manifest.inf directory Add the jar corresponding to class path in the MF file, so that when the later application is just started, it will only load the required version dependency according to the class path (solve the problem of multi version loading reference conflict in the shared directory). This effect is equivalent to adding the parameter – classpath XXX (specific jar).

At this point, put the required jar directory lib and XXX to run You can start without adding the same level directory -dloader.jar Path parameter, if the Lib directory and XXX to be run If jar is not in the same level directory, you need to use – dloader Path to start

As follows: start in the same level directory

Not started at the same level of directory:

Where – dloader Path can specify multiple directories, so that when there are multiple microservices, some public jars can be placed in a shared directory, and the jars unique to each microservice can be placed in the private directory of the microservice (to solve the problem of jar version conflict). The example is as follows:

be careful:

1. Use – dloader Path needs to add < layout > zip < / layout > when packaging. If it is not specified – dloader Path does not take effect

For the downsizing packaging of multiple micro services, it is recommended to use Maven jar plugin packaging to avoid some application startup problems caused by the spring boot Maven plugin packaging mechanism

2. If there are different version dependencies:

For example, if project a relies on version 1.0 of Library y and project B relies on version 2.0 of Library y, there may be a version dependency conflict (when the two versions are incompatible). Solution:

  

2.1 keep the same version if you can keep the same version to ensure the consistency of versions. You can use Maven’s version dependency management for processing, that is, use < dependency Management > to uniformly manage dependent versions in the parent POM file

  

2.2. Make the project depend on the required version and put it into the war package, and put other jar packages of the same version under the same shared package

The test found that the dependency is found from top to bottom during searching, and the first one is used when it is matched, as shown in the figure below. Comm-0.0.1 will be used Jar version

note appended:

Using the spring boot Maven plugin, we will package all the dependent jar packages, so that we can directly run the generated jar package, which simplifies our development operation.

Using the spring boot Maven plugin, if the main running entry class of the program is not specified, the default is main class: org springframework. boot. loader. JarLauncher

The main entry class can be customized and executed in the following ways:

1. POM inherits spring boot starter parent


<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.9.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
<properties>
        <!-- The main class to start by executing java -jar -->
        <start-class>ccom.notes.JavaNotesApplication</start-class>
</properties>

2. POM should be specified when it does not inherit spring boot starter parent


<plugin>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-maven-plugin</artifactId>
  <version>2.1.9.RELEASE</version>
  <configuration>
    <mainClass>com.notes.JavaNotesApplication</mainClass>
    <layout>ZIP</layout>
  </configuration>
  <executions>
    <execution>
      <goals>
        <goal>repackage</goal>
      </goals>
    </execution>
  </executions>
</plugin>

3. POM does not inherit spring boot starter paren, and uses Maven jar plugin plug-in to specify the class to be executed


<plugin>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-jar-plugin</artifactId>
   <configuration>
      <archive>
         <manifest>
            <addClasspath>true</addClasspath>
            <useUniqueVersions>false</useUniqueVersions>
            <classpathPrefix>lib/</classpathPrefix>
            <mainClass>com.notes.JavaNotesApplication</mainClass>
         </manifest>
         <manifestEntries>
            <version>${project.version}</version>
         </manifestEntries>
      </archive>
   </configuration>
</plugin>

The above is my personal experience. I hope I can give you a reference, and I hope you can support developpaer.