但行好事
莫论前程❤

Maven插件使用—-maven-jar-plugin、dependency、shade

Maven生成可以直接运行的jar包的多种方式

Maven可以使用mvn package指令对项目进行打包,如果使用java -jar xxx.jar执行运行jar文件,会出现”no main manifest attribute, in xxx.jar”(没有设置Main-Class)、ClassNotFoundException(找不到依赖包)等错误。

要想jar包能直接通过运行

java -jar xxx.jar

需要满足:

  • 在jar包中的META-INF/MANIFEST.MF中指定Main-Class,这样才能确定程序的入口在哪里;
  • 要能加载到依赖包

方法一:使用maven-jar-plugin和maven-dependency-plugin插件打包

在pom.xml中配置:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.6</version>
            <configuration>  <!-- 配置 -->
                <!-- 生成MANIFEST.MF的设置 -->
                <archive>   <!-- 存档 -->
                    <manifest> 
                        <!-- 为依赖包添加路径, 这些路径会写在MANIFEST文件的Class-Path下 -->
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>configcenter_lib/</classpathPrefix>
                        <!-- jar启动入口类-->
                        <mainClass>
                            com.allstar.configcenter.control.ConfigCenterEntry
                          </mainClass>
                    </manifest>
<!--                  <manifestEntries>
                            在Class-Path下添加配置文件的路径
                            <Class-Path>conf/</Class-Path>
                      </manifestEntries>
 -->
                </archive>
 <!--            <includes>
                        打jar包时,只打包class文件
                        <include>**/*.class</include>
                 </includes>
-->
            </configuration>
        </plugin>
 <!-- ++++++ 项目依赖插件  将使用到的依赖jar包复制到configcenter_lib文件夹下 +++++++++++++-->       
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>2.10</version>
            <executions>
                <execution>    <!-- 执行器 -->
                    <id>copy-dependencies</id>
                    <phase>package</phase>     <!-- 阶段 -->
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <!-- 拷贝项目依赖包到configcenter_lib/目录下 -->
                        <outputDirectory>
                            ${project.build.directory}/configcenter_lib    
                          </outputDirectory>
<!--
                        表示是否不包含间接依赖的包
                        <excludeTransitive>false</excludeTransitive>
                        去除版本信息
                        <stripVersion>false</stripVersion>
-->
                    </configuration>
                </execution>
            </executions>
        </plugin>

    </plugins>
</build>

maven-jar-plugin用于生成META-INF/MANIFEST.MF文件的部分内容

  • <mainClass>com.xxg.Main</mainClass>指定MANIFEST.MF中的Main-Class
  • <addClasspath>true</addClasspath>会在MANIFEST.MF加上Class-Path项并配置依赖包
  • <classpathPrefix>configcenter_lib/</classpathPrefix>指定依赖包所在目录。

例如下面是一个通过maven-jar-plugin插件生成的MANIFEST.MF文件片段:

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: liupenggc
Class-Path: configcenter_lib/cincommon-1.1.1.jar configcenter_lib/mchange-commons-java-0.2.11.jar configcenter_lib/log4j-1.2.17.jar configcenter_lib/ojdbc6-11.2.0.3.jar configcenter_lib/c3p0-0.9.5.2.jar configcenter_lib/c3p0-oracle-thin-extras-0.9.5.2.jar
Created-By: Apache Maven 3.5.2
Build-Jdk: 1.8.0_05
Main-Class: com.allstar.configcenter.control.ConfigCenterEntry

只是生成MANIFEST.MF文件还不够,maven-dependency-plugin插件用于将依赖包拷贝到<outputDirectory>${project.build.directory}/configcenter_lib</outputDirectory>指定的位置,

configcenter_lib目录下。

  • ${project.build.directory} 构建目录,缺省为target

配置完成后,通过mvn package指令打包,会在target目录下生成jar包,并将依赖包拷贝到target/lib目录下

指定了Main-Class,有了依赖包,那么就可以直接通过java -jar xxx.jar运行jar包。

这种方式生成jar包有个缺点,就是生成的jar包太多不便于管理,下面两种方式只生成一个jar文件,包含项目本身的代码、资源以及所有的依赖包。

方法二:使用maven-assembly-plugin插件打包

在pom.xml中配置:

<build>
    <plugins>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.5.5</version>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>
                            com.allstar.configcenter.control.ConfigCenterEntry
                          </mainClass>
                    </manifest>
                </archive>
                <descriptorRefs>        <!-- 描述器引用 -->
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
        </plugin>

    </plugins>
</build>

打包方式:

mvn package assembly:single

​ 打包后会在target目录下生成一个xxx-jar-with-dependencies.jar文件,这个文件不但包含了自己项目中的代码和资源,还包含了所有依赖包的内容。所以可以直接通过java -jar来运行。

此外还可以直接通过mvn package来打包,无需assembly:single,不过需要加上一些配置:

<build>
    <plugins>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.5.5</version>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>
                            com.allstar.configcenter.control.ConfigCenterEntry  
                          </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>

其中<phase>package</phase>、<goal>single</goal>即表示在执行package打包时,执行assembly:single,所以可以直接使用mvn package打包。

不过,如果项目中用到Spring Framework,用这种方式打出来的包运行时会出错,使用下面的方法三可以处理。

方法三:使用maven-shade-plugin插件打包

在pom.xml中配置:

<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.allstar.configcenter.control.ConfigCenterEntry 
                                   </mainClass>
                            </transformer>
                        </transformers>
                    </configuration>
                </execution>
            </executions>
        </plugin>

    </plugins>
</build>

​ 配置完成后,执行mvn package即可打包。在target目录下会生成两个jar包,注意不是original-xxx.jar文件,而是另外一个。和maven-assembly-plugin一样,生成的jar文件包含了所有依赖,所以可以直接运行。

如果项目中用到了Spring Framework,将依赖打到一个jar包中,运行时会出现读取XML schema文件出错。原因是Spring Framework的多个jar包中包含相同的文件spring.handlers和spring.schemas,如果生成一个jar包会互相覆盖。为了避免互相影响,可以使用AppendingTransformer来对文件内容追加合并:

<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.allstar.configcenter.control.ConfigCenterEntry   
                                   </mainClass>
                            </transformer>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                <resource>META-INF/spring.handlers</resource>
                            </transformer>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                <resource>META-INF/spring.schemas</resource>
                            </transformer>
 <!-- 
                           <transformer                             implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                    <resource>META-INF/cxf/bus-extensions.txt</resource>
                                </transformer>
                         <transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                    <resource>
                                        META-INF/services/javax.script.ScriptEngineFactory
                                    </resource>
                                </transformer>
--> 
                        </transformers>
 <!-- 
                        <filters>
                            <filter>
                                <artifact>*:*</artifact>
                                <excludes>
                                    <exclude>META-INF/*.SF</exclude>
                                    <exclude>META-INF/*.DSA</exclude>
                                    <exclude>META-INF/*.RSA</exclude>
                                </excludes>
                            </filter>
                        </filters>
                        <shadedArtifactAttached>false</shadedArtifactAttached>
                        <shadedClassifierName>executable</shadedClassifierName>
-->
                    </configuration>
                </execution>
            </executions>
        </plugin>

    </plugins>
</build>

拓展:资源文件的拷贝

  • 项目资源插件,用于拷贝资源文件 maven-resources-plugin
<!-- 项目资源插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.6</version>
                <executions>
                    <execution>
                        <id>copy-resources</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-resources</goal>
                        </goals>
                        <configuration>
                            <encoding>UTF-8</encoding>
                          <!-- 拷贝项目src/main/resources/下,除.bat以外的所有文件到conf/目录下 -->
                            <outputDirectory>${project.build.directory}/conf</outputDirectory>
                            <resources>
                                <resource>
                                    <directory>src/main/resources/</directory>
                                    <filtering>true</filtering>
                                    <excludes>
                                        <exclude>*.bat</exclude>
                                    </excludes>
                                </resource>
                            </resources>
                        </configuration>
                    </execution>
                    <execution>
                        <id>copy-command</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-resources</goal>
                        </goals>
                        <configuration>
                            <encoding>UTF-8</encoding>
                            <!-- 只拷贝项目src/main/resources/目录下的.bat文件到输出目录下 -->
                            <outputDirectory>${project.build.directory}</outputDirectory>
                            <resources>
                                <resource>
                                    <directory>src/main/resources/</directory>
                                    <filtering>true</filtering>
                                    <includes>
                                        <include>*.bat</include>
                                    </includes>
                                </resource>
                            </resources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
  • ### maven打包时的文件拷贝

通常打包外部资源文件时,都使用maven-dependency-plugin或是maven-resources-plugin插件。但是项目中遇见一个问题,在打包jnotify的动态链接库时,使用上面两个插件进行文件拷贝时,程序会无法识别到打包后dll文件。
多次尝试后使用了maven-antrun-plugin进行拷贝,问题得到解决。其拷贝配置如下:

        <plugin>  
                <groupId>org.apache.maven.plugins</groupId>  
                <artifactId>maven-antrun-plugin</artifactId>
                <version>1.7</version>  
                <executions>  
                    <execution>
                        <id>copy-native-libraries</id>  
                        <phase>package</phase>   
                        <goals>  
                            <goal>run</goal>  
                        </goals> 
                        <configuration>  
                            <tasks>  
                                <echo message="copy native libraries" />
                                <copy todir="../../im_target">  
                                    <fileset dir="${project.build.directory}">
                                        <include name="configcenter.jar"/> <!-- 指定拷贝的文件-->
                                    </fileset>  
                                </copy>  
                            </tasks>
                        </configuration> 
                    </execution>  
                </executions>  
            </plugin>
赞(1) 打赏
未经允许不得转载:刘鹏博客 » Maven插件使用—-maven-jar-plugin、dependency、shade
分享到: 更多 (0)

评论 2

评论前必须登录!

 

  1. #2

    Propecia Pas Cher 1mg [url=http://buyciali.com]cialis 5mg[/url] Pharmaciesonline Viagra Discount

    Kelchit2个月前 (04-04)
  2. #1

    Levitra Farmacia Indiageneric Levitra Every Day [url=http://bpdrugs.com]cialis generic[/url] Canadian Pharmacy Brought By Echeck Amoxicillin The Right Dose Forseniors Propecia Front Bald Viagra Oder Levitra Achat Viagra En Inde [url=http://cialcost.com]cialis canada[/url] Online Buy Propecia

    EllCant4个月前 (01-13)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏