Many ways MAVEN generates a jar package that can be run directly

Source: Internet
Author: User

Maven can use the MVN package directive to pack the project, and if you run the jar file with Java-jar Xxx.jar, "No main manifest attribute, in Xxx.jar" will appear (No setup Main-class), ClassNotFoundException (no dependency package found), and other errors.

To be able to run the jar package directly through the Java-jar Xxx.jar, you need to meet:

1, the meta-inf/manifest in the jar package. The Main-class is specified in MF so as to determine where the entry of the program is;

2. To be able to load to the dependent package.

There are several ways to use MAVEN to generate a jar package that can be run directly, and you can choose an appropriate method as needed.

method One: Package with Maven-jar-plugin and Maven-dependency-plugin plugins

Configure in Pom.xml:

<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId>< artifactid>maven-jar-plugin</artifactid><version>2.6</version><configuration>< archive><manifest><addclasspath>true</addclasspath><classpathprefix>lib/</ classpathprefix><mainclass>com.xxg.main</mainclass></manifest></archive></ configuration></plugin><plugin><groupid>org.apache.maven.plugins</groupid>< Artifactid>maven-dependency-plugin</artifactid><version>2.10</version><executions> <execution><id>copy-dependencies</id><phase>package</phase><goals><goal >copy-dependencies</goal></goals><configuration><outputdirectory>${ Project.build.directory}/lib</outputdirectory></configuration></execution></executions ></plugin></plugins></build>


Maven-jar-plugin is used to generate meta-inf/manifest. Part of the MF file,<mainclass>com.xxg.main</mainclass> the main-class,<addclasspath>true in the specified MANIFEST.MF </addClasspath> will add Class-path to MANIFEST.MF and configure the dependency package,<classpathprefix>lib/</classpathprefix> Specifies the directory where the dependent package resides.

For example, here is a fragment of the MANIFEST.MF file generated by the Maven-jar-plugin plugin:

Class-path:lib/commons-logging-1.2.jar Lib/commons-io-2.4.jarmain-class:com.xxg.main

Just generating the manifest.mf file is not enough, the Maven-dependency-plugin plugin is used to copy the dependent package to the <outputdirectory>${project.build.directory}/lib </outputDirectory> the specified location, that is, the Lib directory.

After the configuration is complete, it is packaged with the MVN package directive, the jar package is generated under the target directory, and the dependent packages are copied to the Target/lib directory with the following directory structure:

With the main-class specified, you can run the jar package directly from the Java-jar Xxx.jar with a dependent package.

One drawback of generating jar packages in this way is that the resulting jar packages are too many to manage, and the following two ways to generate only one jar file, containing the code, resources, and all the dependencies of the project itself.

Method Two: Use the Maven-assembly-plugin plugin to package

Configure in Pom.xml:

<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId>< Artifactid>maven-assembly-plugin</artifactid><version>2.5.5</version><configuration ><archive><manifest><mainclass>com.xxg.main</mainclass></manifest></ archive><descriptorrefs><descriptorref>jar-with-dependencies</descriptorref></ Descriptorrefs></configuration></plugin></plugins></build>

Packing method:

MVN Package Assembly:single

After packaging, a Xxx-jar-with-dependencies.jar file is generated in the target directory, which contains not only the code and resources in its own project, but also the contents of all dependent packages. So it can be run directly through Java-jar.

It can also be packaged directly from the MVN package without the need for assembly:single, but with some configuration:

<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId>< Artifactid>maven-assembly-plugin</artifactid><version>2.5.5</version><configuration ><archive><manifest><mainclass>com.xxg.main</mainclass></manifest></ archive><descriptorrefs><descriptorref>jar-with-dependencies</descriptorref></ Descriptorrefs></configuration><executions><execution><id>make-assembly</id> <phase>package</phase><goals><goal>single</goal></goals></execution> </executions></plugin></plugins></build>

Where <phase>package</phase>, <goal>single</goal> is the execution of Assembly:single when the package is executed, So you can use the MVN package directly.

However, if the spring Framework is used in the project, the package that is punched in this way will run out of error, and the following method can be used to handle it.

Method Three: Use the Maven-shade-plugin plugin to package

Configure in Pom.xml:

<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId>< artifactid>maven-shade-plugin</artifactid><version>2.4.1</version><executions>< execution><phase>package</phase><goals><goal>shade</goal></goals>< Configuration><transformers><transformer implementation= " Org.apache.maven.plugins.shade.resource.ManifestResourceTransformer "><mainclass>com.xxg.main</ Mainclass></transformer></transformers></configuration></execution></executions ></plugin></plugins></build>

After the configuration is complete, the MVN package is executed for packaging. In the target directory, two jar packages are generated, note that not the Original-xxx.jar file, but the other one. Like Maven-assembly-plugin, the generated jar file contains all dependencies, so it can be run directly.

If the spring Framework is used in the project, the dependency is hit into a jar package and an error reading the XML schema file occurs at run time. The reason is that multiple jar packages in the spring framework contain the same files Spring.handlers and Spring.schemas If a jar package is generated that overwrites each other. To avoid interaction, you can use Appendingtransformer to append the contents of the file:

<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId>< artifactid>maven-shade-plugin</artifactid><version>2.4.1</version><executions>< execution><phase>package</phase><goals><goal>shade</goal></goals>< Configuration><transformers><transformer implementation= " Org.apache.maven.plugins.shade.resource.ManifestResourceTransformer "><mainclass>com.xxg.main</ Mainclass></transformer><transformer implementation= " Org.apache.maven.plugins.shade.resource.AppendingTransformer "><resource>meta-inf/spring.handlers</ Resource></transformer><transformer implementation= " Org.apache.maven.plugins.shade.resource.AppendingTransformer "><resource>meta-inf/spring.schemas</ Resource></transformer></transformers></configuration></execution></executions ></plugin></plugins></build>


Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Many ways MAVEN generates a jar package that can be run directly

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.