http://mgorski.net/2013/dev/executable-jar-with-spring-based-application-inside-usin-maven
当用maven-assembly-plugin连同第三方包一起打包到一个jar包,会出错,这里就用maven-shade-plugin进行打包。
While working with java and maven, I used to create executable JARs with maven-assembly-plugin [link]. Is is simple and it does its job pretty well in most of the cases – but not when building Spring-based applications with a lot of modules.
Of course the same application, when started from IDE, runs fine.
After a while of googling I was able to understand the problem: spring’s namespace handlers for various modules are registered in special files (META-INF/spring.handlers, META-INF/spring.schemas, META-INF/spring.tooling) – and those are getting overwritten when the final bundle is being created out of other JARs. To solve this problem I have switched tomaven-shade-plugin and configured its transformers to merge (append) spring files.
Here is a piece of maven configutation that does the job.
(You need to add it to you pom.xml, under build/plugins).
<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>
<!-- 打包后jar包的名字,可随意写 -->
<finalName>my-spring-app</finalName>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>jar-with-dependencies</shadedClassifierName>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.tang.path.to.my.main.Clazz</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>
如果一些配置文件不想放jar包内,想放在外面方便修改,可以配置:
<resources>
<resource>
<targetPath>${basedir}/target/conf</targetPath>
<filtering>false</filtering>
<directory>${basedir}/conf</directory>
<includes>
<include>*.properties</include>
</includes>
</resource>
<resource>
<targetPath>${basedir}/target/classes</targetPath>
<filtering>false</filtering>
<directory>${basedir}/src/main/resources</directory>
<includes>
<include>*.xml</include>
</includes>
<excludes>
<exclude>**/*.properties</exclude>
</excludes>
</resource>
</resources>
放到jar包外面后的访问路径类似 "file:conf/myproperty.properties",
方法一,在java代码中:
Resource resource = resourceLoader.getResource("file:conf/myproperty.properties");
方法二,在配置文件中:
<beans:value>file:conf/hubInterface.properties</beans:value>
另外需要说明的是,如果是防在jar包里面,访问路径类似"classpath:myproperty.properties",
这时, 方法一就找不到它,但方法二能找到