将maven项目打包成可执行jar,通常情况下,我们会用maven-assembly-plugin插件。我承认,这是一个很好用的插件,但是在遇到项目中有用到spring的时候,打包没有问题,在用java -jar xxx.jar命令的时候会出现
1、无法加载到spring配置文件的异常或者报spring-beans.xsd不是以<xsd.sheam>开头的错误。
2、又或者是这样的错误:Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace
一开始你会以为难道没有把我们项目中的spring配置打包到jar中吗?其实不然,实际上,这些 schema 是存在与jar包中的。你再看看http://www.springframework.org/schema/beans/spring-beans.xsd,它也是以<xsd:schema>开头的。
原因:assembly的一个bug.参见:http://jira.codehaus.org/browse/MASSEMBLY-360 原因是spring的多个jar包中都含有spring.handlers和spring.schemas文件,而assembly只会把第一次遇到的文件打入jar包,后面遇到的都会skip掉。
解决方法:使用maven-shade-plugin插件来打包.在shade的打包配制中指明spring.handlers和spring.schemas文件会以append方式加入进来,从而确保其他spring的jar中的这两个文件的信息不会被遗漏。下面是一份pom.xml配置的例子:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>mySpringApp</finalName>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>jar-with-dependencies</shadedClassifierName>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.my.Main</mainClass><-- 注意:这里配置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/spring.tooling</resource>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
然后点击mySpringApp项目,右键---“Run As”-----“Maven package”,完成后,在你项目的target目录下就会出现mySpringApp.jar,打开你的命令窗口,执行命令“java -jar mySpringApp.jar”,到这里就完成啦!
附加:
如何用maven-assembly-plugin插件打可执行jar
有两个方法:
方法一:将项目及所依赖的所有jar包打包成一个jar。
1、pom.xml添加assembly插件
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.my.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
2、命令行执行命令:mvn assembly:assembly
3、生成如下文件
4、执行java -jar quickstart-1.0.0-jar-with-dependencies.jar
备注:第2步的命令也可以改成mvn package,但需要更改pom.xml:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.my.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<!-- this is used for inheritance merges -->
<phase>package</phase>
<!-- 指定在打包节点执行jar包合并操作 -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
方法二:将项目依赖的jar复制到一个目录中并在MANIFEST文件中添加Class-Path和Main-Class。
1、在pom.xml中添加jar和dependency插件
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.my.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<!-- 拷贝依赖的jar包到lib目录 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/lib
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
2、命令行执行命令:mvn package
3、生成如下文件
4、执行java -jar quickstart-1.0.0.jar