让maven生成可运行jar包

  平时项目大多用到的是war包,今天实现了一个简单功能,无需部署到web服务器上,只需本地跑java代码即可,因此只要生成一个jar包。那么怎么让maven项目打成一个可以使用java命令跑的jar包呢?这里通过maven插件实现:

  首先修改pom.xml文件,这里需要新增build节点,在build里加入plugins节点:

<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.wlf.net</groupId>
    <artifactId>point-circle</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>point-circle</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.source>1.8</maven.compiler.source>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.3.12.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>4.3.12.RELEASE</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.12.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>4.3.12.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.3.12.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>4.3.12.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.vividsolutions</groupId>
            <artifactId>jts</artifactId>
            <version>1.8</version>
        </dependency>
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.2.2</version>
        </dependency>
        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc14</artifactId>
            <version>10.2.0.2.0</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>lib/</classpathPrefix>
                            <mainClass>com.wlf.net.point.App</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>
                                ${project.build.directory}/lib
                            </outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

  上面的pom文件里有两个plugin,第一个是在jar包中的META-INF/MANIFEST.MF中指定Main-Class,指定lib库的jar包依赖classpath;第二个是把依赖到的lib库jar包都复制到配置的classpathPrefix目录下,这一步不做的话运行打出来的jar包会报错,因为相关依赖的jar包虽然配置了classpath但其实该classpath下并没有真实的jar包存在。addClasspath为true说明需要在MANIFEST.MF加上classpath并配置依赖包,classpathPrefix指定依赖包所在的目录,mainClass指定MANIFEST.MF中的Main-Class。${project.build.directory}这变量是maven内置的,系统会自动寻找,其实就编译class的目录target,这里配置的${project.build.directory}/lib,在我本机就是E:\workspace\point-circle\target\lib。每次修改完pom配置文件之后,记得在Eclipse右击项目,点击Update Project让修改生效。

  执行maven打包命令:

E:\workspace\point-circle>mvn clean install
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building point-circle 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ point-circle ---
[INFO] Deleting E:\workspace\point-circle\target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ point-circle ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory E:\workspace\point-circle\src\main\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ point-circle ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 3 source files to E:\workspace\point-circle\target\classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ point-circle ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory E:\workspace\point-circle\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ point-circle ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to E:\workspace\point-circle\target\test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ point-circle ---
[INFO] Surefire report directory: E:\workspace\point-circle\target\surefire-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.wlf.net.point.AppTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.063 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO]
[INFO] --- maven-jar-plugin:2.6:jar (default-jar) @ point-circle ---
[INFO] Building jar: E:\workspace\point-circle\target\point-circle-0.0.1-SNAPSHOT.jar
[INFO]
[INFO] --- maven-dependency-plugin:2.8:copy-dependencies (copy) @ point-circle ---
[INFO] Copying commons-dbcp-1.2.2.jar to E:\workspace\point-circle\target\lib\commons-dbcp-1.2.2.jar
[INFO] Copying spring-expression-4.3.12.RELEASE.jar to E:\workspace\point-circle\target\lib\spring-expression-4.3.12.RELEASE.jar
[INFO] Copying jts-1.8.jar to E:\workspace\point-circle\target\lib\jts-1.8.jar
[INFO] Copying commons-pool-1.3.jar to E:\workspace\point-circle\target\lib\commons-pool-1.3.jar
[INFO] Copying hamcrest-core-1.3.jar to E:\workspace\point-circle\target\lib\hamcrest-core-1.3.jar
[INFO] Copying spring-aop-4.3.12.RELEASE.jar to E:\workspace\point-circle\target\lib\spring-aop-4.3.12.RELEASE.jar
[INFO] Copying spring-web-4.3.12.RELEASE.jar to E:\workspace\point-circle\target\lib\spring-web-4.3.12.RELEASE.jar
[INFO] Copying junit-4.12.jar to E:\workspace\point-circle\target\lib\junit-4.12.jar
[INFO] Copying commons-logging-1.2.jar to E:\workspace\point-circle\target\lib\commons-logging-1.2.jar
[INFO] Copying spring-jdbc-4.3.12.RELEASE.jar to E:\workspace\point-circle\target\lib\spring-jdbc-4.3.12.RELEASE.jar
[INFO] Copying spring-webmvc-4.3.12.RELEASE.jar to E:\workspace\point-circle\target\lib\spring-webmvc-4.3.12.RELEASE.jar
[INFO] Copying spring-core-4.3.12.RELEASE.jar to E:\workspace\point-circle\target\lib\spring-core-4.3.12.RELEASE.jar
[INFO] Copying spring-context-4.3.12.RELEASE.jar to E:\workspace\point-circle\target\lib\spring-context-4.3.12.RELEASE.jar
[INFO] Copying ojdbc14-10.2.0.2.0.jar to E:\workspace\point-circle\target\lib\ojdbc14-10.2.0.2.0.jar
[INFO] Copying spring-beans-4.3.12.RELEASE.jar to E:\workspace\point-circle\target\lib\spring-beans-4.3.12.RELEASE.jar
[INFO] Copying spring-context-support-4.3.12.RELEASE.jar to E:\workspace\point-circle\target\lib\spring-context-support-4.3.12.RELEASE.jar
[INFO] Copying spring-tx-4.3.12.RELEASE.jar to E:\workspace\point-circle\target\lib\spring-tx-4.3.12.RELEASE.jar
[INFO]
[INFO] --- maven-install-plugin:2.4:install (default-install) @ point-circle ---
[INFO] Installing E:\workspace\point-circle\target\point-circle-0.0.1-SNAPSHOT.jar to E:\Users\wulf\.m2\repository\com\wlf\net\point-circle\0.0.1-SNAPSHOT\point-circle-0.0.1-SNAPSHOT.jar
[INFO] Installing E:\workspace\point-circle\pom.xml to E:\Users\wulf\.m2\repository\com\wlf\net\point-circle\0.0.1-SNAPSHOT\point-circle-0.0.1-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 17.180 s
[INFO] Finished at: 2018-01-25T21:13:38+08:00
[INFO] Final Memory: 23M/196M
[INFO] ------------------------------------------------------------------------

  看下我们打出来的jar包里的MANIFEST.MF目录和内容:point-circle-0.0.1-SNAPSHOT.jar\META-INF\MANIFEST.MF

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: wulf
Class-Path: lib/spring-core-4.3.12.RELEASE.jar lib/commons-logging-1.2
 .jar lib/spring-context-support-4.3.12.RELEASE.jar lib/spring-beans-4
 .3.12.RELEASE.jar lib/spring-context-4.3.12.RELEASE.jar lib/spring-ao
 p-4.3.12.RELEASE.jar lib/spring-expression-4.3.12.RELEASE.jar lib/spr
 ing-web-4.3.12.RELEASE.jar lib/spring-webmvc-4.3.12.RELEASE.jar lib/s
 pring-jdbc-4.3.12.RELEASE.jar lib/spring-tx-4.3.12.RELEASE.jar lib/jt
 s-1.8.jar lib/commons-dbcp-1.2.2.jar lib/commons-pool-1.3.jar lib/ojd
 bc14-10.2.0.2.0.jar
Created-By: Apache Maven 3.3.9
Build-Jdk: 1.8.0_102
Main-Class: com.wlf.net.point.App

  上面列出了classpath里所依赖到的jar包列表、主class。最后打开命令行界面执行jar包:

E:\>cd E:\workspace\point-circle\target

E:\workspace\point-circle\target>java -jar point-circle-0.0.1-SNAPSHOT.jar
Exception in thread "main" java.lang.NullPointerException
        at com.wlf.net.point.App.main(App.java:39)

  空指针是spring的注入问题,这里说明可执行jar包出炉了。但如果我把这个新鲜烤出来的jar包复制到另一个地方,比如E盘,再执行就报找不到依赖的jar包了:

E:\>java -jar point-circle-0.0.1-SNAPSHOT.jar
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: com/vividsolutions/jts/io/ParseException
        at java.lang.Class.getDeclaredMethods0(Native Method)
        at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
        at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
        at java.lang.Class.getMethod0(Class.java:3018)
        at java.lang.Class.getMethod(Class.java:1784)
        at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
        at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)
Caused by: java.lang.ClassNotFoundException: com.vividsolutions.jts.io.ParseException
        at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        ... 7 more

  看来这个面包只能在面包店里吃了,我打包带走就吃不了。这是因为classpath已经设定了依赖jar包的位置了,只能到当前目录target的lib目录下找,你拿到其他地方还想跑也可以,那么请你一并把lib目录复制过去吧。难道我吃个面包还得随身带个烤面包机吗?是的,但是我们不用到处复制,把烤面包机放进面包里就可以了。这里我们就要用到另一个maven插件了,它可以把我们所依赖的jar包一并打入我们自己的jar包里。我们干掉之前那两个plugin,换成maven-assembly-plugin这个plugin,改后的pom文件的build节点如下:

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <mainClass>com.wlf.net.point.App</mainClass>
                        </manifest>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

  再次执行打包命令:

E:\workspace\point-circle>mvn clean install
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building point-circle 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ point-circle ---
[INFO] Deleting E:\workspace\point-circle\target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ point-circle ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory E:\workspace\point-circle\src\main\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ point-circle ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 3 source files to E:\workspace\point-circle\target\classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ point-circle ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory E:\workspace\point-circle\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ point-circle ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to E:\workspace\point-circle\target\test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ point-circle ---
[INFO] Surefire report directory: E:\workspace\point-circle\target\surefire-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.wlf.net.point.AppTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.068 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ point-circle ---
[INFO] Building jar: E:\workspace\point-circle\target\point-circle-0.0.1-SNAPSHOT.jar
[INFO]
[INFO] --- maven-assembly-plugin:2.2-beta-5:single (make-assembly) @ point-circle ---
[INFO]
[INFO] --- maven-install-plugin:2.4:install (default-install) @ point-circle ---
[INFO] Installing E:\workspace\point-circle\target\point-circle-0.0.1-SNAPSHOT.jar to E:\Users\wulf\.m2\repository\com\wlf\net\point-circle\0.0.1-SNAPSHOT\point-circle-0.0.1-SNAPSHOT.jar
[INFO] Installing E:\workspace\point-circle\pom.xml to E:\Users\wulf\.m2\repository\com\wlf\net\point-circle\0.0.1-SNAPSHOT\point-circle-0.0.1-SNAPSHOT.pom
[INFO] Installing E:\workspace\point-circle\target\point-circle-0.0.1-SNAPSHOT-jar-with-dependencies.jar to E:\Users\wulf\.m2\repository\com\wlf\net\point-circle\0.0.1-SNAPSHOT\point-circle-0.0.1-SNAPSHOT-jar-with-dependencies.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 24.621 s
[INFO] Finished at: 2018-01-26T11:17:05+08:00
[INFO] Final Memory: 29M/230M
[INFO] ------------------------------------------------------------------------

  

  这次生成的jar包里多了很多东西,而且名称也变了:point-circle-0.0.1-SNAPSHOT-jar-with-dependencies.jar。我们把它复制到E盘执行,这次没问题了:

C:\Users\wulf>e:

E:\>java -jar point-circle-0.0.1-SNAPSHOT-jar-with-dependencies.jar
Exception in thread "main" java.lang.NullPointerException
        at com.wlf.net.point.App.main(App.java:39)

  还可以用另外一个插件maven-shade-plugin来代替maven-assembly-plugin,修改后的pom文件如下:

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.4.1</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer
                                    implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>com.wlf.net.point.App</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

  执行maven打包:

:\workspace\point-circle>mvn clean install
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building point-circle 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ point-circle ---
[INFO] Deleting E:\workspace\point-circle\target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ point-circle ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 2 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ point-circle ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 3 source files to E:\workspace\point-circle\target\classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ point-circle ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory E:\workspace\point-circle\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ point-circle ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to E:\workspace\point-circle\target\test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ point-circle ---
[INFO] Surefire report directory: E:\workspace\point-circle\target\surefire-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.wlf.net.point.AppTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.036 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ point-circle ---
[INFO] Building jar: E:\workspace\point-circle\target\point-circle-0.0.1-SNAPSHOT.jar
[INFO]
[INFO] --- maven-shade-plugin:2.4.1:shade (default) @ point-circle ---
[INFO] Including org.springframework:spring-core:jar:4.3.12.RELEASE in the shaded jar.
[INFO] Including commons-logging:commons-logging:jar:1.2 in the shaded jar.
[INFO] Including org.springframework:spring-context-support:jar:4.3.12.RELEASE in the shaded jar.
[INFO] Including org.springframework:spring-beans:jar:4.3.12.RELEASE in the shaded jar.
[INFO] Including org.springframework:spring-context:jar:4.3.12.RELEASE in the shaded jar.
[INFO] Including org.springframework:spring-aop:jar:4.3.12.RELEASE in the shaded jar.
[INFO] Including org.springframework:spring-expression:jar:4.3.12.RELEASE in the shaded jar.
[INFO] Including org.springframework:spring-web:jar:4.3.12.RELEASE in the shaded jar.
[INFO] Including org.springframework:spring-webmvc:jar:4.3.12.RELEASE in the shaded jar.
[INFO] Including org.springframework:spring-jdbc:jar:4.3.12.RELEASE in the shaded jar.
[INFO] Including org.springframework:spring-tx:jar:4.3.12.RELEASE in the shaded jar.
[INFO] Including com.vividsolutions:jts:jar:1.8 in the shaded jar.
[INFO] Including commons-dbcp:commons-dbcp:jar:1.2.2 in the shaded jar.
[INFO] Including commons-pool:commons-pool:jar:1.3 in the shaded jar.
[INFO] Including com.oracle:ojdbc14:jar:10.2.0.2.0 in the shaded jar.
[INFO] Replacing original artifact with shaded artifact.
[INFO] Replacing E:\workspace\point-circle\target\point-circle-0.0.1-SNAPSHOT.jar with E:\workspace\point-circle\target\point-circle-0.0.1-SNAPSHOT-shaded.jar
[INFO] Dependency-reduced POM written at: E:\workspace\point-circle\dependency-reduced-pom.xml
[INFO] Dependency-reduced POM written at: E:\workspace\point-circle\dependency-reduced-pom.xml
[INFO]
[INFO] --- maven-install-plugin:2.4:install (default-install) @ point-circle ---
[INFO] Installing E:\workspace\point-circle\target\point-circle-0.0.1-SNAPSHOT.jar to E:\Users\wulf\.m2\repository\com\wlf\net\point-circle\0.0.1-SNAPSHOT\point-circle-0.0.1-SNAPSHOT.jar
[INFO] Installing E:\workspace\point-circle\dependency-reduced-pom.xml to E:\Users\wulf\.m2\repository\com\wlf\net\point-circle\0.0.1-SNAPSHOT\point-circle-0.0.1-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.557 s
[INFO] Finished at: 2018-01-26T16:33:45+08:00
[INFO] Final Memory: 28M/195M
[INFO] ------------------------------------------------------------------------

 

  注意这里会生成两个jar,一个带original前缀表示原始jar包,一个没带该前缀,我们要用的是没带的。

posted on 2018-01-25 21:35  不想下火车的人  阅读(426)  评论(0编辑  收藏  举报

导航