maven 打包詳解
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、要能加載到依賴包。
使用Maven有以下幾種方法可以生成能直接運作的jar包,可以根據需要選擇一種合适的方法。
方法一:使用maven-jar-plugin和maven-dependency-plugin插件打包
這種方式生成jar包有個缺點,就是生成的jar包太多不便于管理,其它兩種方式隻生成一個jar檔案,包含項目本身的代碼、資源以及所有的依賴包。
<build>
<plugins>
<!-- 配置打包,并配置MainClass, 但不将依賴包打包,會出現找不到依賴的異常 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<!-- MANIFEST.MF 中 Class-Path -->
<classpathPrefix>lib/</classpathPrefix>
<mainClass>cn.zoom.wqz.filter.Application</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<!-- 配置依賴包 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<!-- 将依賴包打包至target下的lib目錄 -->
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
方法二:使用maven-assembly-plugin插件打包
打包方式:
mvn package assembly:single
配置方式:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>cn.zoom.wqz.filter.Application</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
打包後會在target目錄下生成一個xxx-jar-with-dependencies.jar檔案,這個檔案不但包含了自己項目中的代碼和資源,還包含了所有依賴包的内容。是以可以直接通過java -jar來運作。
此外還可以直接通過mvn package來打包,無需assembly:single,不過需要加上一些配置:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>cn.zoom.wqz.filter.Application</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<!-- 其中<phase>package</phase>、<goal>single</goal>即表示在執行package打包時,執行assembly:single -->
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
不過,如果項目中用到spring Framework,用這種方式打出來的包運作時會出錯,使用下面的方法三可以處理。
方法三:使用maven-shade-plugin插件打包
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>cn.zoom.wqz.filter.Application</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
配置完成後,執行mvn package即可打包。在target目錄下會生成兩個jar包,注意不是original-xxx.jar檔案,而是另外一個。和maven-assembly-plugin一樣,生成的jar檔案包含了所有依賴,是以可以直接運作。
如果項目中用到了Spring Framework,将依賴打到一個jar包中,運作時會出現讀取XML schema檔案出錯。原因是Spring Framework的多個jar包中包含相同的檔案spring.handlers和spring.schemas,如果生成一個jar包會互相覆寫。為了避免互相影響,可以使用AppendingTransformer來對檔案内容追加合并:
<plugin>
<groupid>org.apache.maven.plugins</groupid>
<artifactid>maven-shade-plugin</artifactid>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.manifestresourcetransformer">
<mainclass>cn.zoom.wqz.filter.application</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>
如果不是springboot 但是想要運作指定的main方法入口的時候,需要在pom檔案中指定,打包的時候才能寫入。以上的方法有提到使用maven-assembly-plugin插件來打包的時候會生成兩個jar,使用是字尾為xxxx-jar-with-dependencies.jar 這個包
希望本篇文章能夠對你有所幫助,我因為這個找不到main入口,花費了大量的時間。