使用maven插件对java工程进行打包过程解析

现在基本上都是采用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>. 

关于此问题报错的原因,我在网上找到一篇文章对此有比较详细的解释:https://www.jb51.net/article/168072.htm 简单来说就是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>

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

<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包就可以了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • maven中下载jar包源码和javadoc的命令介绍

    1:Maven命令下载源码和javadocs 当在IDE中使用Maven时如果想要看引用的jar包中类的源码和javadoc需要通过maven命令下载这些源码,然后再进行引入,通过mvn命令能够容易的达到这个目的: 复制代码 代码如下: mvn dependency:sources mvn dependency:resolve -Dclassifier=javadoc 命令使用方法:首先进入到相应的pom.xml目录中,然后执行以上命令: 第一个命令是尝试下载在pom.xml中依赖的文件的源代码

  • Java修改maven的默认jdk版本为1.7的方法

    问题: 1.创建maven项目的时候,jdk版本是1.5版本,而自己安装的是1.7或者1.8版本. 2.每次右键项目名-maven->update project 时候,项目jdk版本变了,变回1.5版本或者其他版本 解决办法: 解决办法一:在项目中的pom.xml指定jdk版本,如下: <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <ar

  • java如何使用自己的maven本地仓库详解

    本地仓库 主要是一种缓存,当你使用远程仓库中下载组件后,它下一次会优先从本地进行加载,一般位于USER_HOME/.m2目录下,我们自己也可以建立公用的包,把包发布到本地仓库,自己在其它项目里直接可以用,当然如果希望在任务地方都使用自己的包,需要把它发布到远程仓库中. 像nuget,npm一样maven也是仓库 Jar的maven配置 <dependency> <groupId>javalindday</groupId> <artifactId>jpaDem

  • Java开发之普通web项目转为Maven项目的方法

    前言 Maven是基于项目对象模型(Project Object Model),可以通过一小段描述信息来管理项目的构建.报告和文档的项目管理工具,提供了一个仓库的概念,统一管理项目所依赖的第三方jar包,最大可能避免了由于环境变量的不同在不同电脑之间无法运行的问题,Struts2.Hibernate都是采用maven部署的项目. 现在网上有许多普通web项目转换为maven项目的博文,但由于项目的不同,所需的步骤及必须的转换步骤也不同.因此,本文章将以一个基于SpringMVC,Spring,H

  • Java命令行下Jar包打包小结

    jar包打包实现 jar包打包可以使用jar指令实现打包,在命令行中输入jar可以查看jar指令的内容 从最后显示的两个示例看出存在两种打包的方法,两者的区别就是是否使用自己定义的MANIFEST清单文件.第一个示例没有使用MANIFEST文件进行打包,所以最终生成的jar包中MANIFEST文件为默认文件,这种方式适用于比较简单的jar包结构,不存在其他jar包依赖以及生成的jar包不需要可执行.这种方式生成的jar包不能使用java -jar XXX.jar命令执行,因为MANIFEST文件

  • java实现服务器文件打包zip并下载的示例(边打包边下载)

    使用该方法,可以即时打包文件,一边打包一边传输,不使用任何的缓存,让用户零等待! 复制代码 代码如下: /** *  * mySocket 客户端 Socket * @param file 待打包的文件夹或文件 * @param fileName 打包下载的文件名 * @throws IOException */ private void down(File file, String fileName) throws IOException { OutputStream outputStream

  • Java中基于maven实现zxing二维码功能

    maven所需jar <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>com.google.zxing</groupId> <artifac

  • 使用maven插件对java工程进行打包过程解析

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

  • 原生Java操作mysql数据库过程解析

    这篇文章主要介绍了原生Java操作mysql数据库过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.引入数据库驱动的jar包 以通过maven引入mysql driver为例 1.1 到http://mvnrepository.com 搜索 mysql 1.2 复制所需maven配置文件到工程的 pom.xml <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-

  • Java继承构造器使用过程解析

    这篇文章主要介绍了Java继承构造器使用过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 初始化基类 前面提到,继承是子类对父类的拓展.<Thinking in Java>中提到下面一段话: 当创建一个导出类的对象时,该对象包含了一个基类的子对象.这个子对象与你用基类直接创建的对象是一样的.二者区别在于,后者来自于外部,而基类的子对象被包装在导出类的对象内部. 我们在创建子类对象时,调用了父类的构造器,甚至父类的父类构造器.我们知道,构

  • 通过Java实现bash命令过程解析

    这篇文章主要介绍了通过Java实现bash命令过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.BASH 命令简介 Bash,Unix shell的一种,在1987年由布莱恩·福克斯为了GNU计划而编写.1989年发布第一个正式版本,原先是计划用在GNU操作系统上,但能运行于大多数类Unix系统的操作系统之上,包括Linux与Mac OS X v10.4都将它作为默认shell. Bash是Bourne shell的后继兼容版本与开放

  • JAVA如何定义构造函数过程解析

    这篇文章主要介绍了JAVA如何定义构造函数过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 构造函数在类里面定义,构造函数名一定要跟类名相同,实例化一个对象的时候,如果没有初始化成员变量,可以不用定义构造函数,系统会自己定义好,定义了也不会影响.如果实例化对象需要初始化成员变量就一定自定义构造函数. 定义构造函数 class Cat { String name; int age; //可定义可不定义,不定义时实例化一个对象会自动定义这个构

  • 如何通过Java实现时间轴过程解析

    这篇文章主要介绍了如何通过Java实现时间轴过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.需要添加FastJson的依赖处理数据. <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </depen

  • Java 图片复制功能实现过程解析

    需求说明 实现思路 见代码注释 代码内容 使用IO复制图片 import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; /** * @auther::9527 * @Description: 第十题 * @program: 多线程 * @create: 2019-08-10 00:26 */ pu

  • MAC配置java+jmeter环境变量过程解析

    打开ITerm终端 进入命令输入,sudo su,输入密码 创建.bash_profile文件touch .bash_profile 打开.bash_profile文件open .bash_profile 弹出文本编辑 export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-14.0.1.jdk/Contents/Home export PATH=$JAVA_HOME/bin:$PATH export CLASSPATH=.:$JAVA_HO

  • 如何基于java实现Gauss消元法过程解析

    补充知识: 正定矩阵 奇异矩阵 严格对角占优 要理解Gauss消去法,首先来看一个例子: 从上例子可以看出,高斯消去法实际上就是我们初中学的阶二元一次方程组,只不过那里的未知数个数$n=2$ $n>2$时,Gauss消去法的思路实际上和解二元一次方程组是一样的,方法如下: 将n方程组中的n−1个方程通过消元,形成一个与原方程组等价的一个新方程组,新方程组中的n−1个方程仅包含n−1个未知数. 故问题就转化为了求解n−1元的方程组,这样我们可以继续消元,以次类推,直到最后一个方程组为一元一次方程组

  • 基于Java信号量解决死锁过程解析

    死锁在多线程的情况下,会出现数据不同步情况, 而为了避免这种情况,之前也说了:界区实现方法有两种,一种是用synchronized,一种是用Lock显式锁实现. 而如果不恰当的使用了锁,且出现同时要锁多个对象时,会出现死锁情况,如下: package lockTest; import java.util.Date; /** * 崔素强 * @author cuisuqiang@163.com */ public class LockTest { public static String obj1

随机推荐