zoukankan      html  css  js  c++  java
  • [置顶] 使用 maven 插件 maven-shade-plugin 对可执行 java 工程及其全部依赖 jar 进行打包

    现在基本上都是采用 maven 来进行开发管理,我有一个需求是需要把通过 maven 管理的 java 工程打成可执行的 jar 包,这样也就是说必需把工程依赖的 jar 包也一起打包。而使用 maven 默认的 package 命令构建的 jar 包中只包括了工程自身的 class 文件,并没有包括依赖的 jar 包。我们可以通过配置插件来对工程进行打包,pom 具体配置如下:

    maven-assembly-plugin (使用此插件会有一些问题)

    Xml代码  收藏代码
    1. <plugin>  
    2.     <artifactId>maven-assembly-plugin</artifactId>  
    3.     <configuration>  
    4.         <appendAssemblyId>false</appendAssemblyId>  
    5.         <descriptorRefs>  
    6.             <descriptorRef>jar-with-dependencies</descriptorRef>  
    7.         </descriptorRefs>  
    8.         <archive>  
    9.             <manifest>  
    10.                 <mainClass>com.chenzhou.examples.Main</mainClass>  
    11.             </manifest>  
    12.         </archive>  
    13.     </configuration>  
    14.     <executions>  
    15.         <execution>  
    16.             <id>make-assembly</id>  
    17.             <phase>package</phase>  
    18.             <goals>  
    19.                 <goal>assembly</goal>  
    20.             </goals>  
    21.         </execution>  
    22.     </executions>  
    23. </plugin>  

     

    其中 <mainClass></mainClass> 的值表示此工程的入口类,也就是包含 main 方法的类,在我的例子中就是 com.chenzhou.examples.Main。配置完 pom 后可以通过执行 mvn assembly:assembly 命令来启动插件进行构建。构建成功后会生成 jar 包,这样我们就可以在命令行中通过 java -jar XXX.jar 来运行 jar 文件了。 

     

    不过使用此插件会有一些问题:我在工程中依赖了 spring 框架的 jar 包,我打包成功后使用命令来调用 jar 包时报错如下(内网环境):

     

    Shell代码  收藏代码
    1. org.xml.sax.SAXParseException: schema_reference.4: Failed to read schema document 'http://www.springframework.org/schema/beans/spring-beans-3.0.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>.  

    关于此问题报错的原因,我在网上找到一篇文章对此有比较详细的解释:http://blog.csdn.net/bluishglc/article/details/7596118 简单来说就是 spring 在启动时会加载 xsd 文件,它首先会到本地查找 xsd 文件(一般都会包含在 spring 的 jar 包中),如果找不到则会到 xml 头部定义的 url 指定路径下中去寻找 xsd,如果找不到则会报错。

    附:在 spring jar 包下的 META-INF 文件夹中都会包含一个 spring.schemas 文件,其中就包含了对 xsd 文件的路径定义,具体如下图所示:

    spring-aop.jar包下META-INF文件夹下的内容

    图:spring-aop.jar 包下 META-INF 文件夹下的内容

    spring.schemas文件内容

    图:spring.schemas 文件内容

    由于我的工程是在内网,所以通过 url 路径去寻找肯定是找不到的,但是比较奇怪的是既然 spring 的 jar 包中都会包含,那为什么还是找不到呢?

     原来这是 assembly 插件的一个 bug,具体情况参见:http://jira.codehaus.org/browse/MASSEMBLY-360

    该 bug 产生的原因如下:工程一般依赖了很多的 jar 包,而被依赖的 jar 又会依赖其他的 jar 包,这样,当工程中依赖到不同的版本的 spring 时,在使用 assembly 进行打包时,只能将某一个版本 jar 包下的 spring.schemas 文件放入最终打出的jar包里,这就有可能遗漏了一些版本的 xsd 的本地映射,所以会报错。

    所以一般推荐使用另外的一个插件来进行打包,插件名称为:maven-shade-plugin,shade 插件打包时在对 spring.schemas 文件处理上,它能够将所有 jar 里的 spring.schemas 文件进行合并,在最终生成的单一 jar 包里,spring.schemas 包含了所有出现过的版本的集合,要使用 shade 插件,必须在 pom 进行如下配置:

     

    Xml代码  收藏代码
    1. <plugin>  
    2.     <groupId>org.apache.maven.plugins</groupId>  
    3.     <artifactId>maven-shade-plugin</artifactId>  
    4.     <version>1.4</version>  
    5.     <executions>  
    6.         <execution>  
    7.             <phase>package</phase>  
    8.             <goals>  
    9.                 <goal>shade</goal>  
    10.             </goals>  
    11.             <configuration>  
    12.                 <transformers>  
    13.                     <transformer  
    14.                         implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">  
    15.                         <resource>META-INF/spring.handlers</resource>  
    16.                     </transformer> 
    17.                     <transformer  
    18.                         implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">  
    19.                         <mainClass>com.chenzhou.examples.Main</mainClass>  
    20.                     </transformer>  
    21.                     <transformer  
    22.                         implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">  
    23.                         <resource>META-INF/spring.schemas</resource>  
    24.                     </transformer>  
    25.                 </transformers>  
    26.             </configuration>  
    27.         </execution>  
    28.     </executions>  
    29. </plugin>  

    上面配置文件中有一段定义:

     

    1. <transformer  
    2.     implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">  
    3.     <resource>META-INF/spring.handlers</resource>  
    4. </transformer>  
    5. <transformer  
    6.    implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">  
    7.    <resource>META-INF/spring.schemas</resource> 
    8. </transformer>

    上面这段配置意思是把 spring.handlers 和 spring.schemas 文件以 append 方式加入到构建的 jar 包中,这样就不会出现 xsd 找不到的情况。

    配置完 pom 后,调用 mvn clean install 命令进行构建,构建成功后打开工程 target 目录,发现生成了 2 个 jar 包,一个为:original-XXX-0.0.1-SNAPSHOT.jar,另一个为:XXX-0.0.1-SNAPSHOT.jar,其中 original...jar 里只包含了工程自己的 class 文件,而另外的一个 jar 包则包含了工程本身以及所有依赖的 jar 包的 class 文件。我们只需要使用第二个 jar 包就可以了。


    参考资料:

    http://hi.baidu.com/yuzhi2217/item/2c1714363f25c4f62684f442

    http://blog.csdn.net/bluishglc/article/details/7596118

    http://jira.codehaus.org/browse/MASSEMBLY-360

  • 相关阅读:
    [转] iphoneX、iphoneXS、iphoneXSMax、iphoneXR适配
    [转] 以 async/await 为例,说明 babel 插件怎么搭
    [转] 使用Node.js实现简易MVC框架
    [转] vue异步处理错误
    [转] 谈谈前端异常捕获与上报
    everything 13问
    Mysql 工具mysqlbinlog
    Mysql 删除日志
    Mysql 错误 ERROR 1 (HY000) at line 1: Can't create/write to file '/home/kaizenly/cfg_dict.csv' (Errcode: 13
    Mysql 问题集
  • 原文地址:https://www.cnblogs.com/leonxyzh/p/7289080.html
Copyright © 2011-2022 走看看