Maven打包可执行jar包

一: maven-jar-plugin和maven-dependency-plugin

使用maven-jar-plugin和maven-dependency-plugin

  1. 首先,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
2. 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包:jar会自动到lib下找依赖的其他包。

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

提供了自定义类加载器,它知道如何从归档文件中的jar加载类和资源,而不是从文件系统中的jar加载。

<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>

优点:干净的委托模型,允许类位于One Jar的顶层,支持外部Jar,并且可以支持本机库
缺点:2012后就不再更新

五: spring-boot-maven-plugin

能同时打可执行jar包和war包,且能自动将依赖打到jar包中。需要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

优点:jar文件中的依赖项,您可以在每个可访问的位置运行它,打包工件的高级控制,从jar文件中排除依赖项等,以及打包war文件
缺点:添加了一些不必要的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>

目标设置为exec_war -only,服务器的路径在配置标记中指定,带有附加属性,如finalName, charset等。要构建一个jar,运行man package,这将导致在目标目录中创建webapp.jar。运行
要运行该应用程序,只需在控制台中编写以下代码:java -jar target/webapp.jar,并通过在浏览器中指定localhost:8080/来测试它。
优点:只有一个jar包
缺点:打包出的文件很大。因为里面内嵌了一个tomcat

原文地址:https://www.baeldung.com/executable-jar-with-maven

你可能感兴趣的:(JavaWeb,maven,jar,java,打包方式)