打包方法
方法一:使用maven-jar-plugin
和maven-dependency-plugin
首先,maven-jar-plugin
的作用是配置mainClass和指定classpath。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>libs/</classpathPrefix>
<mainClass>
org.baeldung.executable.ExecutableMavenJar
</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
addClasspath: 是否在manifest文件中添加classpath。默認為false。如果為true,則會在manifest文件中添加classpath,這樣在啟動的時候就不用再手動指定classpath了。如下所示,文件中增加了
Class-Path
一行
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: michealyang
Class-Path: libs/jetty-server-9.4.7.v20170914.jar lib/javax.servlet-api
-3.1.0.jar libs/jetty-http-9.4.7.v20170914.jar
Created-By: Apache Maven 3.3.9
Build-Jdk: 1.8.0_162-ea
Main-Class: com.michealyang.jetty.embeded.EmbeddedJettyServer
classpathPrefix: classpath的前綴。如上面的manifest文件中,Class-Path的值中,每個jar包的前綴都是libs/。本質上,這個配置的值是所依賴jar包所在的文件夾。配置正確了才能找到依賴
mainClass: 指定啟動時的Main Class
其次,maven-dependency-plugin
會把所依賴的jar包copy到指定目錄
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/libs
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
executions中的配置都很重要,按照上面的配置來就行了。outputDirectory指定了要將所依賴的jar包copy到哪個目錄。要與maven-jar-plugin
中的classpathPrefix一致。
執行如下命令,即可打包:
mvn package
打包結果是,自己寫的Class在jar包中,所依賴的jar包在libs目錄中:
├── embedded-jetty-1.0.0-SNAPSHOT.jar
├── lib
│ ├── jetty-server-9.4.7.v20170914.jar
│ ├── jetty-http-9.4.7.v20170914.jar
執行如下命令即可啟動jar包:
java -jar embedded-jetty-1.0.0-SNAPSHOT.jar
優點
有諸多配置項,很自由,每個步驟都可控
缺點
打成的最終jar包中沒有所依賴的jar包。依賴跟自己的代碼不在一個jar包中。部署或者移動的時候,要考慮到多個文件,比較麻煩
方法二:使用maven-assembly-plugin
(推薦)
maven-assembly-plugin
可以將所有的東西都打包到一個jar包中。
<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.michealyang.jetty.embeded.EmbeddedJettyServer
</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
執行mvn package
后,會在target文件夾下生成兩個jar包,一個是不帶依賴的jar包,一個是后綴有-dependencies
帶有依賴的jar包,如:
May 31 16:42 embedded-jetty-1.0.0-SNAPSHOT-jar-with-dependencies.jar
May 31 16:42 embedded-jetty-1.0.0-SNAPSHOT.jar
啟動時,直接執行即可:
java -jar embedded-jetty-1.0.0-SNAPSHOT-jar-with-dependencies.jar
優點
所有的東西都打到一個jar包中,很方便
缺點
配置項少,不自由。
方法三:使用maven-shade-plugin
跟maven-assembly-plugin
類似,都可以將所有的東西都打包到一個jar包中。
<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.michealyang.jetty.embeded.EmbeddedJettyServer</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
執行mvn package
后,會在target文件夾下生成兩個jar包,一個是不帶依賴的jar包,一個是后綴有-shaded
帶有依賴的jar包,如:
May 31 16:53 embedded-jetty-1.0.0-SNAPSHOT-shaded.jar
May 31 16:53 embedded-jetty-1.0.0-SNAPSHOT.jar
啟動時,直接執行即可:
java -jar embedded-jetty-1.0.0-SNAPSHOT-jar-with-shaded.jar
優點
功能同maven-assembly-plugin
,但比前者強大
缺點
配置起來太麻煩。當你需要高級功能的時候,更是麻煩的不要不要的。
方法四:使用onejar-maven-plugin
This provides custom classloader that knows how to load classes and resources from jars inside an archive, instead of from jars in the filesystem.
<plugin>
<groupId>com.jolira</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<executions>
<execution>
<configuration>
<mainClass>org.baeldung.executable.
ExecutableMavenJar</mainClass>
<attachToBuild>true</attachToBuild>
<filename>
${project.build.finalName}.${project.packaging}
</filename>
</configuration>
<goals>
<goal>one-jar</goal>
</goals>
</execution>
</executions>
</plugin>
優點
clean delegation model, allows classes to be at the top-level of the One Jar, supports external jars and can support Native libraries
缺點
not actively supported since 2012
方法五:使用spring-boot-maven-plugin
能同時打可執行jar包和war包
This allows to package executable jar or war archives and run an application “in-place”.
需要maven版本不低于3.2
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>spring-boot</classifier>
<mainClass>
org.baeldung.executable.ExecutableMavenJar
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
兩個重點:
-
goal
要寫成repackage
-
classifier
要寫成spring-boot
優點
dependencies inside a jar file, you can run it in every accessible location, advanced control of packaging your artifact, with excluding dependencies from the jar file etc., packaging of war files as well
缺點
添加了一些不必要的Spring和Spring Boot依賴
方法六:使用tomcat7-maven-plugin
可打包成一個web工程類型的jar包。其實是內嵌了一個tomcat在里面。
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.0</version>
<executions>
<execution>
<id>tomcat-run</id>
<goals>
<goal>exec-war-only</goal>
</goals>
<phase>package</phase>
<configuration>
<path>/</path>
<enableNaming>false</enableNaming>
<finalName>webapp.jar</finalName>
<charset>utf-8</charset>
</configuration>
</execution>
</executions>
</plugin>
The goal is set as exec-war-only, path to your server is specified inside configuration tag, with additional properties, like finalName, charset etc. To build a jar, run man package, which will result in creating webapp.jar in your target directory. To run
To run the application, just write this in your console: java -jar target/webapp.jar and try to test it by specifying the localhost:8080/ in a browser.
優點
只有一個jar包
缺點
打包出的文件很大。因為里面內嵌了一個tomcat