问题
I have a Maven based Spring-WS client project that I want to package as a single jar. In eclipse, everything runs properly. When I try to package it as an executable jar, I get ClassNotFound exceptions since the Spring jars are not included in my application jar.
So I added the maven-shade-plugin to include all my dependencies in my application jar. When I look at my app jar, I see all the class files from all the dependencies included (all the library jar\'s are exploded).
<build>
<plugins>
<plugin>
<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-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.cws.cs.Client</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<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>
</execution>
</executions>
</plugin>
</plugins>
</build>
My problem is that in the packaging process, my multiple spring dependencies have different META-INF/spring.schemas files that override each other. Consequently, my final jar has an incomplete spring.schemas file.
So when I try to run my executable jar, I get Spring error messages that files cannot be found since the spring.schemas file is incomplete (the Spring-WS\'s jar has overriden the Spring-core\'s spring.schemas file).
My executable jar\'s META-INF/spring.schemas:
http\\://www.springframework.org/schema/web-services/web-services-1.5.xsd=/org/springframework/ws/config/web-services-1.5.xsd
http\\://www.springframework.org/schema/web-services/web-services-2.0.xsd=/org/springframework/ws/config/web-services-2.0.xsd
http\\://www.springframework.org/schema/web-services/web-services.xsd=/org/springframework/ws/config/web-services-2.0.xsd
Instead of Spring-beans.jar META-INF/spring.schemas:
http\\://www.springframework.org/schema/beans/spring-beans-2.0.xsd=org/springframework/beans/factory/xml/spring-beans-2.0.xsd
http\\://www.springframework.org/schema/beans/spring-beans-2.5.xsd=org/springframework/beans/factory/xml/spring-beans-2.5.xsd
http\\://www.springframework.org/schema/beans/spring-beans-3.0.xsd=org/springframework/beans/factory/xml/spring-beans-3.0.xsd
http\\://www.springframework.org/schema/beans/spring-beans-3.1.xsd=org/springframework/beans/factory/xml/spring-beans-3.1.xsd
http\\://www.springframework.org/schema/beans/spring-beans.xsd=org/springframework/beans/factory/xml/spring-beans-3.1.xsd
http\\://www.springframework.org/schema/tool/spring-tool-2.0.xsd=org/springframework/beans/factory/xml/spring-tool-2.0.xsd
http\\://www.springframework.org/schema/tool/spring-tool-2.5.xsd=org/springframework/beans/factory/xml/spring-tool-2.5.xsd
http\\://www.springframework.org/schema/tool/spring-tool-3.0.xsd=org/springframework/beans/factory/xml/spring-tool-3.0.xsd
http\\://www.springframework.org/schema/tool/spring-tool-3.1.xsd=org/springframework/beans/factory/xml/spring-tool-3.1.xsd
http\\://www.springframework.org/schema/tool/spring-tool.xsd=org/springframework/beans/factory/xml/spring-tool-3.1.xsd
http\\://www.springframework.org/schema/util/spring-util-2.0.xsd=org/springframework/beans/factory/xml/spring-util-2.0.xsd
http\\://www.springframework.org/schema/util/spring-util-2.5.xsd=org/springframework/beans/factory/xml/spring-util-2.5.xsd
http\\://www.springframework.org/schema/util/spring-util-3.0.xsd=org/springframework/beans/factory/xml/spring-util-3.0.xsd
http\\://www.springframework.org/schema/util/spring-util-3.1.xsd=org/springframework/beans/factory/xml/spring-util-3.1.xsd
http\\://www.springframework.org/schema/util/spring-util.xsd=org/springframework/beans/factory/xml/spring-util-3.1.xsd
I\'m stumped. I am not sure if/how I can package everything as a single executable jar. I don\'t know if this is a shade-plugin configuration issue, or if I am trying to do something impossible. It would not seem correct that I would have to manually create my own spring.schemas file (a concatenation of the others).
I may have jumped the gun a little. In digging up more info on the shade plugin, I noticed the AppendingTransformer that I had previously missed. However, my concern is how to know which other files are having the same problems? I\'ve discovered/caught this particular Spring issue. I have no idea about any other libraries that may be doing something similar...
Any suggestions would be appreciated.
回答1:
Instead of maven-shade-plugin use onejar-maven-plugin. One-JAR lets you package a Java application together with its dependency Jars into a single executable Jar file.
回答2:
You can add the following configuration so that the contents of the .schema files from all the jars get appended together.
<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.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
</transformers>
</configuration>
回答3:
Yesterday I was encountered this issue too.
The solution was to prepare required files by manual concatenation and configuration of assembly plugin by this:
<files>
<file>
<source>src/META-INF/spring.schemas</source>
<outputDirectory>META-INF</outputDirectory>
</file>
<file>
<source>src/META-INF/spring.handlers</source>
<outputDirectory>META-INF</outputDirectory>
</file>
</files>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>true</unpack>
<scope>runtime</scope>
<unpackOptions>
<excludes>
<exclude>META-INF/spring.handlers</exclude>
<exclude>META-INF/spring.schemas</exclude>
</excludes>
</unpackOptions>
</dependencySet>
</dependencySets>
NOTE: using one jar approach is not good enough - you can't be certain on hand mixed files, try to keep exporting of all dependence's as is...
回答4:
Have you tried the maven-assembly-plugin ?
It will create a single jar with dependencies for you and morevover it can make this jar be executable :
Use mainClass to specify the class you want to execute.
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.3</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>org.sample.App</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
回答5:
assembly plugin have issues, use below plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>at.seresunit.lecturemanager_connector.App</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>
you may get security exception resolve it using below configuration
<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>
来源:https://stackoverflow.com/questions/11160534/how-to-create-spring-based-executable-jar-with-maven