使用maven生成可执行的jar包

最近在使用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.AppTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.009 sec

Results :

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.AppTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.011 sec

Results :

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 9504
Exception 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.0
Archiver-Version: Plexus Archiver
Built-By: Administrator
Created-By: Apache Maven 3.5.0
Build-Jdk: 1.8.0_91
Main-Class: com.nathan.attach.attach.AttachAPI

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

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

1.创建assembly.xml

<assembly
xmlns="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.jar
java.util.ServiceConfigurationError: com.sun.tools.attach.spi.AttachProvider: Provider sun.tools.attach.WindowsAttachProvider could not be instantiated
com.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包,搞了一个下午,不容易啊!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值