[1119]使用maven插件maven-shade-plugin对可执行java工程及其全部依赖jar进行打包

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

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

<plugin>  
    <artifactId>maven-assembly-plugin</artifactId>  
    <configuration>  
        <appendAssemblyId>false</appendAssemblyId>  
        <descriptorRefs>  
            <descriptorRef>jar-with-dependencies</descriptorRef>  
        </descriptorRefs>  
        <archive>  
            <manifest>  
                <mainClass>com.chenzhou.examples.Main</mainClass>  
            </manifest>  
        </archive>  
    </configuration>  
    <executions>  
        <execution>  
            <id>make-assembly</id>  
            <phase>package</phase>  
            <goals>  
                <goal>assembly</goal>  
            </goals>  
        </execution>  
    </executions>  
</plugin> 

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

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

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文件夹下的内容
image.png

图:spring.schemas文件内容
image.png

由于我的工程是在内网,所以通过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进行如下配置:

<plugin>  
    <groupId>org.apache.maven.plugins</groupId>  
    <artifactId>maven-shade-plugin</artifactId>  
    <version>1.4</version>  
    <executions>  
        <execution>  
            <phase>package</phase>  
            <goals>  
                <goal>shade</goal>  
            </goals>  
            <configuration>  
                <transformers>  
                    <transformer  
                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">  
                        <resource>META-INF/spring.handlers</resource>  
                    </transformer> 
                    <transformer  
                        implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">  
                        <mainClass>com.chenzhou.examples.Main</mainClass>  
                    </transformer>  
                    <transformer  
                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">  
                        <resource>META-INF/spring.schemas</resource>  
                    </transformer>  
                </transformers>  
            </configuration>  
        </execution>  
    </executions>  
</plugin>

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

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

上面这段配置意思是把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包就可以了。

来源:https://blog.csdn.net/kezhong_wxl/article/details/77622115

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Maven Shade插件可以将多个jar包合并成一个可执行jar包,并且可以将合并后的jar依赖的其他jar包也打包到该jar包中,从而实现系统依赖范围内的可执行jar包。 以下是使用Maven Shade插件生成系统依赖范围的可执行jar包的步骤: 1. 在Maven项目的pom.xml文件中,添加Maven Shade插件依赖项: ``` <dependency> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.4</version> </dependency> ``` 2. 在Maven项目的pom.xml文件中,配置Maven Shade插件: ``` <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.4</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <createDependencyReducedPom>false</createDependencyReducedPom> <shadedArtifactAttached>true</shadedArtifactAttached> <shadedClassifierName>jar-with-dependencies</shadedClassifierName> </configuration> </execution> </executions> </plugin> </plugins> </build> ``` 其中,`createDependencyReducedPom`指定是否创建一个简化的POM文件,`shadedArtifactAttached`指定生成的jar包是否作为附加的构件,`shadedClassifierName`指定生成的jar包的分类器名称。 3. 运行Maven项目的打包命令,生成系统依赖范围内的可执行jar包: ``` mvn package ``` 执行该命令后,Maven Shade插件会自动将项目打包成可执行jar包,并且将该jar依赖的其他jar包也打包到该jar包中,从而生成系统依赖范围内的可执行jar包。生成的jar包的名称一般为`<项目名称>-<版本号>-jar-with-dependencies.jar`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值