文档章节

使用 maven 插件 maven-shade-plugin 对可执行 java 工程及其全部依赖

独钓渔
 独钓渔
发布于 2016/04/13 18:05
字数 1458
阅读 831
收藏 6

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

前半部分转自:http://www.xuebuyuan.com/1500726.html

现在基本上都是采用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文件夹下的内容

图: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进行如下配置:

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


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

  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


我这次是由于把dubbo-admin改成一个jar 可执行型遇到打成的jar 加载spring 文件时找不到文件,所以。这个shade这个插件,还是我们另外的开发把我们的另一个项目用的这种打包方式,所以才给我改了一下,我也单独使用过shade 这个卑件打包,同样报的是打不到spring文件,所以,我让他给我给找找原因,找到了这篇,所以,我需要记录一下。

同时把我打包的xml发出来。


<build>
	    <finalName>bbupdate</finalName>
<!-- 	    <filters> -->
<!-- 	    	<filter>src/main/resources/filter/${env}.properties</filter> -->
<!-- 	    </filters> -->
	    <resources>
	      	<resource>
	           <directory>src/main/resources</directory>
	           <filtering>true</filtering>
	       </resource>
	    </resources>
		<plugins>
		    <plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.6</source>
					<target>1.6</target>
				</configuration>
			</plugin>
			<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>
							<filters>
								<filter>
									<artifact>*:*</artifact>
									<excludes>
										<exclude>META-INF/*.SF</exclude>
										<exclude>META-INF/*.DSA</exclude>
										<exclude>META-INF/*.RSA</exclude>
									</excludes>
								</filter>
							</filters>
							<transformers>
								<transformer
									implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
									<mainClass>com.bbpay.bbupdate.main.Bbupdate</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>
							</transformers>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>


我的问题和他的问题不一样,他报的是找不到XSD,而我报的是找不到spring的xml配置文件,但是配置文件确实在,所以,但是我用了这个之后,确实可以了。

无语,感觉和他这个找不到XSD原因类似,记录。方便下次查找。






© 著作权归作者所有

独钓渔
粉丝 49
博文 413
码字总数 159659
作品 0
沙坪坝
系统管理员
私信 提问
根据 Jar 文件直接创建 Windows 的可执行程序

程序员经常被要求将一个 Java 应用程序打包成 Windows 下的可执行程序。下面这个简单的实例就是演示如何创建一个包含开发商信息的 Windows 可执行程序,并包含一个不错的图标。这里需要用到 ...

曾沙
2012/11/26
735
0
根据 Jar 文件直接创建 Windows 的可执行程序

程序员经常被要求将一个 Java 应用程序打包成 Windows 下的可执行程序。下面这个简单的实例就是演示如何创建一个包含开发商信息的 Windows 可执行程序,并包含一个不错的图标。这里需要用到 ...

红薯
2012/08/13
6.7K
12
浅谈 java 中构建可执行 jar 包的几种方式

有时候,由于项目的需要,我们会将源码编译后以工具包(class打成jar包)的形式对外提供,此时, 你的 jar 包不一定要是可执行的,只要能通过编译,能被别人以 import 的方式调用就行了。但还...

大数据之路
2013/05/05
7.4K
3
第一章:JAVA项目工程化之项目构建工具maven

版权声明:本文为博主原创文章,转载需注明出处 https://blog.csdn.net/ldz1997106/article/details/82856804 欢迎查看Java开发之上帝之眼系列教程,如果您正在为Java后端庞大的体系所困扰,...

jimisun
2018/09/26
0
0
Maven常用插件的使用Case

Maven是Java工程常用的项目管理工具,通过Maven可以管理项目的各个生命周期。Maven本质是一个插件框架,本身并不执行任何构建任务,所有的工作都是交给插件来完成的。熟练使用Maven插件,可以...

huamingweiwen
2015/08/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

sed -i linux 批量替换命令

批量替换 /usr/local/rocketmq/conf 目录下 的 xml 里头的 ${user.home} 替换为 /usr/local/rocketmq # mkdir -p /usr/local/rocketmq/logs# cd /usr/local/rocketmq/conf && sed -i 's#${......

jxlgzwh
26分钟前
4
0
如何在嵌入式CSS中编写a:hover?

我有一种情况,我必须编写内联CSS代码,并且我想在锚点上应用悬停样式。 如何在HTML样式属性内的CSS中使用a:hover ? 例如,您不能在HTML电子邮件中可靠地使用CSS类。 #1楼 简短的答案:您不...

技术盛宴
34分钟前
4
0
一些常用工具下载

golang: https://dl.google.com/go/go1.13.5.window-amd64.zip https://dl.google.com/go/go1.13.5.linux-amd64.tar.gz 更换版本号可以下载其他版本。...

bobby2006
40分钟前
4
0
centos使用yum安装或者更新时总是提示被PackageKit占用

centos使用yum安装或者更新时总是提示被PackageKit占用 使用yum安装或更新软件时总是提示yum被PackageKit锁定占用 Existing lock /var/run/yum.pid: another copy is running as pid 13090. ...

流麦士
47分钟前
4
0
使用CSS内容添加HTML实体

如何使用CSS content属性添加html实体? 使用这样的东西只打印  到屏幕而不是不间断的空间: .breadcrumbs a:before { content: ' ';} #1楼 更新 :PointedEars提到正确的立...

javail
49分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部