【Java】Maven 打包可運行jar包


前提

  Maven可以使用mvn package指令對項目進行打包,如果使用Java -jar xxx.jar執行運行jar文件,會出現"no main manifest attribute, in xxx.jar"(沒有設置Main-Class)、ClassNotFoundException(找不到依賴包)等錯誤。

  要想jar包能直接通過java -jar xxx.jar運行,需要滿足:

  1、在jar包中的META-INF/MANIFEST.MF中指定Main-Class,這樣才能確定程序的入口在哪里;

  2、要能加載到依賴包。

搭建示例項目

  1、新建Maven工程

  

  2、編輯pom.xml文件

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0"
 3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5     <modelVersion>4.0.0</modelVersion>
 6 
 7     <groupId>org.example</groupId>
 8     <artifactId>test-mvn-package</artifactId>
 9     <version>1.0-SNAPSHOT</version>
10 
11     <dependencies>
12         <dependency>
13             <groupId>cn.hutool</groupId>
14             <artifactId>hutool-all</artifactId>
15             <version>5.3.7</version>
16         </dependency>
17     </dependencies>
18 </project>

  3、編輯主類MyMain.java

 1 public class MyMain {
 2 
 3     public static void main(String[] args) {
 4         System.out.println("===========程 序 啟 動===========");
 5 
 6         // 當前時間字符串,格式:yyyy-MM-dd HH:mm:ss
 7         // DateUtil 第三方jar包中的類
 8         String now = DateUtil.now();
 9         System.out.println("當前時間:" + now);
10 
11         System.out.println("===========程 序 關 閉===========");
12     }
13 }

  4、測試,運行主方法,效果如下:

    

  5、直接mvn package,打包后,運行jar包

    運行方法一:java -jar test-mvn-package-1.0-SNAPSHOT.jar

    

    運行方法二(指定主類):java -cp test-mvn-package-1.0-SNAPSHOT.jar com.test.api.MyMain

    

    均無法直接運行

項目打包

  使用Maven有以下幾種方法可以生成能直接運行的jar包,可以根據需要選擇一種合適的方法。

方法一:使用maven-jar-plugin和maven-dependency-plugin插件打包

  1、在pom.xml中配置:

 1 <build>
 2     <plugins>
 3 
 4         <!-- 使用maven-jar-plugin和maven-dependency-plugin插件打包 -->
 5         <plugin>
 6             <groupId>org.apache.maven.plugins</groupId>
 7             <artifactId>maven-jar-plugin</artifactId>
 8             <version>3.1.0</version>
 9             <configuration>
10                 <archive>
11                     <manifest>
12                         <addClasspath>true</addClasspath>
13                         <classpathPrefix>lib/</classpathPrefix>
14                         <mainClass>com.test.api.MyMain</mainClass>
15                     </manifest>
16                 </archive>
17             </configuration>
18         </plugin>
19         <plugin>
20             <groupId>org.apache.maven.plugins</groupId>
21             <artifactId>maven-dependency-plugin</artifactId>
22             <version>3.1.1</version>
23             <executions>
24                 <execution>
25                     <id>copy-dependencies</id>
26                     <phase>package</phase>
27                     <goals>
28                         <goal>copy-dependencies</goal>
29                     </goals>
30                     <configuration>
31                         <outputDirectory>${project.build.directory}/lib</outputDirectory>
32                     </configuration>
33                 </execution>
34             </executions>
35         </plugin>
36 
37     </plugins>
38 </build> 

    說明:

    maven-jar-plugin用於生成META-INF/MANIFEST.MF文件的部分內容,com.xx.Main指定MANIFEST.MF中的Main-Class,true會在MANIFEST.MF加上Class-Path項並配置依賴包,lib/指定依賴包所在目錄。

    只是生成MANIFEST.MF文件還不夠,maven-dependency-plugin插件用於將依賴包拷貝到${project.build.directory}/lib指定的位置,即lib目錄下。

  2、使用maven命令:mvn clean package 打包

  3、target目錄內容如下,多了lib目錄

    

    反編譯jar包,MANIFEST.MF文件內容如下:

    

  4、使用命令:java -jar test-mvn-package-1.0-SNAPSHOT.jar,可以直接運行

    

方法二:使用maven-assembly-plugin插件打包

  1、在pom.xml中配置:

 1 <build>
 2     <plugins>
 3 
 4         <!-- 使用maven-assembly-plugin插件打包 -->
 5         <plugin>
 6             <groupId>org.apache.maven.plugins</groupId>
 7             <artifactId>maven-assembly-plugin</artifactId>
 8             <version>3.2.0</version>
 9             <configuration>
10                 <archive>
11                     <manifest>
12                         <mainClass>com.test.api.MyHttpRequest</mainClass>
13                     </manifest>
14                 </archive>
15                 <descriptorRefs>
16                     <descriptorRef>jar-with-dependencies</descriptorRef>
17                 </descriptorRefs>
18             </configuration>
19             <executions>
20                 <execution>
21                     <id>make-assembly</id>
22                     <phase>package</phase>
23                     <goals>
24                         <goal>single</goal>
25                     </goals>
26                 </execution>
27             </executions>
28         </plugin>
29 
30     </plugins>
31 </build>

  2、使用maven命令:mvn clean package 打包

  3、target目錄內容如下,多了test-mvn-package-1.0-SNAPSHOT-jar-with-dependencies.jar包

    

    反編譯jar包,test-mvn-package-1.0-SNAPSHOT-jar-with-dependencies.jar內容如下:

    

    可以看到其中把第三方包的內容放到新的jar包中了

    不過,如果項目中用到hutool-all第三方包,用這種方式打出來的包運行時可能會出錯,但實驗中沒有出現這種情況。項目中最好使用maven依賴源包

  4、使用命令:java -jar test-mvn-package-1.0-SNAPSHOT.jar,無法運行

  5、使用命令:java -jar test-mvn-package-1.0-SNAPSHOT-jar-with-dependencies.jar,可以直接運行

    

方法三:使用maven-shade-plugin插件打包

  1、在pom.xml中配置:

 1 <build>
 2     <plugins>
 3 
 4         <!-- 使用maven-shade-plugin插件打包 -->
 5         <plugin>
 6             <groupId>org.apache.maven.plugins</groupId>
 7             <artifactId>maven-shade-plugin</artifactId>
 8             <version>3.2.3</version>
 9             <configuration>
10                 <createDependencyReducedPom>false</createDependencyReducedPom>
11             </configuration>
12             <executions>
13                 <execution>
14                     <phase>package</phase>
15                     <goals>
16                         <goal>shade</goal>
17                     </goals>
18                     <configuration>
19                         <transformers>
20                             <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
21                                 <mainClass>com.test.api.MyMain</mainClass>
22                             </transformer>
23                         </transformers>
24                     </configuration>
25                 </execution>
26             </executions>
27             </plugin>
28 
29     </plugins>
30 </build>

  2、使用maven命令:mvn clean package 打包 

  3、target目錄內容如下,多了original-test-mvn-package-1.0-SNAPSHOT.jar包

    

    反編譯jar包,test-mvn-package-1.0-SNAPSHOT.jar內容如下:

    

    可以看到其中把第三方包的內容放到新的jar包中了

    不過,如果項目中用到hutool-all第三方包,用這種方式打出來的包運行時可能會出錯,但實驗中沒有出現這種情況。項目中最好使用maven依賴源包

  4、使用命令:java -jar test-mvn-package-1.0-SNAPSHOT.jar

    

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM