使用maven生成可执行的jar包

来源:互联网 发布:科比0506常规赛数据 编辑:程序博客网 时间:2024/05/02 02:44

最近在使用maven生成可执行的jar包的时候,遇到了个问题,当然maven生成runnable的jar包有很多种方式:

  • maven-jar-plugin和maven-dependency-plugin插件打包
  • maven-assembly-plugin插件打包
  • 使用maven-shade-plugin插件打包

本博文研究的是用maven-assembly-plugin插件打包。

maven-assembly-plugin插件打包的教程网上已经有很多了,但是大部分都是在引用的包是在maven的repository里面的jar包,打包的时候引用包会包含在生成的jar文件里面。

可是如果引用的包是在本地呢?

最近在研究javaagent的时候,需要引用jdk提供的tools.jar,由于该jar包不在jre里面,所以必须额外引用:

<dependency>     <groupId>com.sun</groupId>     <artifactId>tools</artifactId>     <version>1.6</version>     <scope>system</scope>     <systemPath>${JAVA_HOME}/lib/tools.jar</systemPath></dependency>

于是有了以下完整的pom

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  <modelVersion>4.0.0</modelVersion>  <groupId>com.nathan.attach</groupId>  <artifactId>attach</artifactId>  <version>0.0.1-SNAPSHOT</version>  <packaging>jar</packaging>  <name>attach</name>  <url>http://maven.apache.org</url>  <properties>    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  </properties>  <dependencies>    <dependency>      <groupId>junit</groupId>      <artifactId>junit</artifactId>      <version>3.8.1</version>      <scope>test</scope>    </dependency>    <dependency>     <groupId>com.sun</groupId>     <artifactId>tools</artifactId>     <version>1.6</version>     <scope>system</scope>     <systemPath>${JAVA_HOME}/lib/tools.jar</systemPath>    </dependency>  </dependencies>  <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> </project>

接着试着跑一下

Administrator@WIN10-706021706 MINGW64 /j/eclipse-workspace/attach$ mvn package assembly:single[INFO] Scanning for projects...[INFO][INFO] ------------------------------------------------------------------------[INFO] Building attach 0.0.1-SNAPSHOT[INFO] ------------------------------------------------------------------------[INFO][INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ attach ---[INFO] Using 'UTF-8' encoding to copy filtered resources.[INFO] skip non existing resourceDirectory J:\eclipse-workspace\attach\src\main\resources[INFO][INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ attach ---[INFO] Changes detected - recompiling the module![INFO] Compiling 1 source file to J:\eclipse-workspace\attach\target\classes[INFO][INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ attach ---[INFO] Using 'UTF-8' encoding to copy filtered resources.[INFO] skip non existing resourceDirectory J:\eclipse-workspace\attach\src\test\resources[INFO][INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ attach ---[INFO] Changes detected - recompiling the module![INFO] Compiling 1 source file to J:\eclipse-workspace\attach\target\test-classes[INFO][INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ attach ---[INFO] Surefire report directory: J:\eclipse-workspace\attach\target\surefire-reports------------------------------------------------------- T E S T S-------------------------------------------------------Running com.nathan.attach.attach.AppTestTests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.009 secResults :Tests run: 1, Failures: 0, Errors: 0, Skipped: 0[INFO][INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ attach ---[INFO] Building jar: J:\eclipse-workspace\attach\target\attach-0.0.1-SNAPSHOT.jar[INFO][INFO] --- maven-assembly-plugin:2.5.5:single (make-assembly) @ attach ---[INFO] Building jar: J:\eclipse-workspace\attach\target\attach-0.0.1-SNAPSHOT-jar-with-dependencies.jar[INFO][INFO] --- maven-assembly-plugin:2.5.5:single (default-cli) @ attach ---[INFO] Building jar: J:\eclipse-workspace\attach\target\attach-0.0.1-SNAPSHOT-jar-with-dependencies.jar[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time: 5.233 s[INFO] Finished at: 2017-08-13T14:41:29+08:00[INFO] Final Memory: 18M/363M[INFO] ------------------------------------------------------------------------Administrator@WIN10-706021706 MINGW64 /j/eclipse-workspace/attach

看起来正常?跑去target目录下看了以下,怎么肥四….只有几k??明显是没有把依赖包打进去…

这里写图片描述

这里有猫腻…

这里写图片描述


为什么打包的时候依赖包没有包含进去?我明明设置了jar-with-dependencies ,于是我开始怀疑是scope搞得怪,老规矩,先科普下scope里面的设置的意义:

http://blog.csdn.net/kimylrong/article/details/50353161

按引用博文里面提到的:

system
从参与度来说,也provided相同,不过被依赖项不会从maven仓库抓,而是从本地文件系统拿,一定需要配合systemPath属性使用。

果然是scope搞的怪啊,那是不是我改成compile就行了呢?Nonono,由于引用本地jar包的特殊性,必须用system呢,不然会报错:

这里写图片描述

辗转反侧,斗转星移,穷尽我的爪牙,终于是找到一篇博文有提到这事情了:

http://m.blog.csdn.net/hhb200766/article/details/42168819

里面提到用resource这个tag

 <resources>      <resource>        <targetPath>lib/</targetPath>        <directory>lib/</directory>        <includes>          <include>**/my-jar.jar</include>        </includes>      </resource>    </resources>

于是我把jar包拷贝到项目的lib目录下

这里写图片描述

接着更该pom:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  <modelVersion>4.0.0</modelVersion>  <groupId>com.nathan.attach</groupId>  <artifactId>attach</artifactId>  <version>0.0.1-SNAPSHOT</version>  <packaging>jar</packaging>  <name>attach</name>  <url>http://maven.apache.org</url>  <properties>    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  </properties>  <dependencies>    <dependency>      <groupId>junit</groupId>      <artifactId>junit</artifactId>      <version>3.8.1</version>      <scope>test</scope>    </dependency>    <dependency>     <groupId>com.sun</groupId>     <artifactId>tools</artifactId>     <version>1.6</version>     <scope>system</scope>     <systemPath>${JAVA_HOME}/lib/tools.jar</systemPath>    </dependency>  </dependencies>  <build>      <plugins>          <plugin>              <groupId>org.apache.maven.plugins</groupId>              <artifactId>maven-assembly-plugin</artifactId>              <version>2.5.5</version>              <configuration>                  <archive>                      <manifest>                          <mainClass>com.nathan.attach.attach.AttachAPI</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>      <resources>          <resource>            <targetPath>lib/</targetPath>            <directory>lib/</directory>            <includes>              <include>**/tools.jar</include>            </includes>          </resource>        </resources></build> </project>

接着生成jar:

Administrator@WIN10-706021706 MINGW64 /j/eclipse-workspace/attach$ mvn package assembly:single[INFO] Scanning for projects...[INFO][INFO] ------------------------------------------------------------------------[INFO] Building attach 0.0.1-SNAPSHOT[INFO] ------------------------------------------------------------------------[INFO][INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ attach ---[INFO] Using 'UTF-8' encoding to copy filtered resources.[INFO] Copying 1 resource to lib/[INFO][INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ attach ---[INFO] Nothing to compile - all classes are up to date[INFO][INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ attach ---[INFO] Using 'UTF-8' encoding to copy filtered resources.[INFO] skip non existing resourceDirectory J:\eclipse-workspace\attach\src\test\resources[INFO][INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ attach ---[INFO] Nothing to compile - all classes are up to date[INFO][INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ attach ---[INFO] Surefire report directory: J:\eclipse-workspace\attach\target\surefire-reports------------------------------------------------------- T E S T S-------------------------------------------------------Running com.nathan.attach.attach.AppTestTests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.011 secResults :Tests run: 1, Failures: 0, Errors: 0, Skipped: 0[INFO][INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ attach ---[INFO] Building jar: J:\eclipse-workspace\attach\target\attach-0.0.1-SNAPSHOT.jar[INFO][INFO] --- maven-assembly-plugin:2.5.5:single (make-assembly) @ attach ---[INFO] Building jar: J:\eclipse-workspace\attach\target\attach-0.0.1-SNAPSHOT-jar-with-dependencies.jar[INFO][INFO] --- maven-assembly-plugin:2.5.5:single (default-cli) @ attach ---[INFO] Building jar: J:\eclipse-workspace\attach\target\attach-0.0.1-SNAPSHOT-jar-with-dependencies.jar[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time: 7.537 s[INFO] Finished at: 2017-08-13T15:16:48+08:00[INFO] Final Memory: 13M/398M[INFO] ------------------------------------------------------------------------Administrator@WIN10-706021706 MINGW64 /j/eclipse-workspace/attach

看了下target目录,貌似正常?

这里写图片描述

于是我尝试跑一下,ops….还是失败了…为什么…

Administrator@WIN10-706021706 MINGW64 /j/eclipse-workspace/attach/target$ java -jar attach-0.0.1-SNAPSHOT-jar-with-dependencies.jar 9504Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/tools/attach/VirtualMachine        at com.nathan.attach.attach.AttachAPI.main(AttachAPI.java:21)Administrator@WIN10-706021706 MINGW64 /j/eclipse-workspace/attach/target

我打开了生成的jar包的 MANIFEST.MF查看:

Manifest-Version: 1.0Archiver-Version: Plexus ArchiverBuilt-By: AdministratorCreated-By: Apache Maven 3.5.0Build-Jdk: 1.8.0_91Main-Class: com.nathan.attach.attach.AttachAPI

不对啊..怎么没有引用信息…

实在没办法了,终于在stackoverflow找到答案,教了我另外一种方法:

1.创建assembly.xml

<assemblyxmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"><id>jar-with-all-dependencies</id><formats>    <format>jar</format></formats><includeBaseDirectory>false</includeBaseDirectory><dependencySets>    <dependencySet>        <outputDirectory>/</outputDirectory>        <useProjectArtifact>true</useProjectArtifact>        <unpack>true</unpack>        <scope>runtime</scope>    </dependencySet>    <dependencySet>        <outputDirectory>/</outputDirectory>        <unpack>true</unpack>        <scope>system</scope>    </dependencySet></dependencySets> </assembly>

指定

 <dependencySet>        <outputDirectory>/</outputDirectory>        <unpack>true</unpack>        <scope>system</scope>    </dependencySet>

然后在pom那里引用

 <descriptors>                              <descriptor>src/main/resource/assembly.xml</descriptor>  </descriptors>  
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  <modelVersion>4.0.0</modelVersion>  <groupId>com.nathan.attach</groupId>  <artifactId>attach</artifactId>  <version>0.0.1-SNAPSHOT</version>  <packaging>jar</packaging>  <name>attach</name>  <url>http://maven.apache.org</url>  <properties>    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  </properties>  <dependencies>    <dependency>      <groupId>junit</groupId>      <artifactId>junit</artifactId>      <version>3.8.1</version>      <scope>test</scope>    </dependency>    <dependency>     <groupId>com.sun</groupId>     <artifactId>tools</artifactId>     <version>1.6</version>     <scope>system</scope>     <systemPath>${project.basedir}/lib/tools.jar</systemPath>    </dependency>  </dependencies>  <build>      <plugins>          <plugin>              <groupId>org.apache.maven.plugins</groupId>              <artifactId>maven-assembly-plugin</artifactId>              <version>2.5.5</version>              <configuration>                  <archive>                      <manifest>                          <mainClass>com.nathan.attach.attach.AttachAPI</mainClass>                      </manifest>                  </archive>                  <descriptorRefs>                      <descriptorRef>jar-with-dependencies</descriptorRef>                  </descriptorRefs>                  <descriptors>                          <descriptor>src/main/resource/assembly.xml</descriptor>                  </descriptors>              </configuration>              <executions>                  <execution>                      <id>make-assembly</id>                      <phase>package</phase>                      <goals>                          <goal>single</goal>                      </goals>                  </execution>              </executions>          </plugin>      </plugins>      </build> </project>

执行 mvn package assembly:single后

这里写图片描述

跑一下

J:\eclipse-workspace\attach\target>java -jar attach-0.0.1-SNAPSHOT-jar-with-all-dependencies.jarjava.util.ServiceConfigurationError: com.sun.tools.attach.spi.AttachProvider: Provider sun.tools.attach.WindowsAttachProvider could not be instantiatedcom.sun.tools.attach.AttachNotSupportedException: no providers installed        at com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:203)        at com.nathan.attach.attach.AttachAPI.main(AttachAPI.java:15)Exception in thread "main" java.lang.NullPointerException        at com.nathan.attach.attach.AttachAPI.main(AttachAPI.java:21)J:\eclipse-workspace\attach\target>

终于没有报找不到依赖类了!大功告成!!!这个报错是程序错误,本篇只讨论依赖包的引入。

脑袋空空,口袋空空,简单的一个打jar包,搞了一个下午,不容易啊!