在程序中使用到了springframework控件(主要是为了使用Mybatis-spring操作数据库,省事)。
使用maven管理项目的构建,现在需要生成一个jar包,包含所有依赖的jar包,并可以在命令行使用java -jar [filename] 来运行。
1. maven-assembly-plugin
最开始的时候尝试使用maven-assembly-plugin插件,配置如下:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>Main</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
但是,在命令行使用mvn package命令打包之后,运行java -jar 之后,报错如下:
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/context] Offending resource: class path resource [JavaProjectApplicationContext.xml]
google了一阵子之后,网上有人说这是assembly-plugin插件的一个bug,因为它在对第三方打包是,对于 META-INF 下的 spring.handlers,spring.schemas 等多个同名文件进行了覆盖。
推荐使用maven-shade-plugin插件。
2.maven-shade-plugin插件
shade插件可以把所有依赖的包都导入到最终的一个可执行jar包当中。根据网上内容,在pom中设置如下:
<build> <plugins> <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.ManifestResourceTransformer"> <mainClass>com.defonds.RsaEncryptor</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>
但是执行之后依然报错,如下:
Exception in thread "main" java.lang.SecurityException: Invalid signature file digest for Manifest main attributes
查找之后,原因是一些包重复引用,打包后多出来了一些*.SF等文件,导致报错。
解决方案,添加如下代码到pom.xml文件:
<configuration> <filters> <filter> <artifact>*:*</artifact> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> </excludes> </filter> </filters> </configuration>
mvn clean;mvn package; java -jar ... 之后,一切运行正常。
补充一个:
跳过测试阶段:
mvn package -DskipTests
临时性跳过测试代码的编译:
mvn package -Dmaven.test.skip=true
折腾了一天多,总算前进了一步,mark。