Create a single executable JAR from a Spring Based Java Application

13,268

Solution 1

use Maven Shade Plugin for create uberjar. This could help you too.

Solution 2

I just had the very same problem than you today, with doing exactly the same steps :)

So thanks for your message, it makes me save some time and besides, i just want to quickly answer to your "Why it worked is still a mystery." sentence :

"This is because I have several Spring Jar in my dependencies. Some of the spring jars contain meta info files with the same name. To avoid that some meta files are overridden you have to merge it"

So this is why you need to add those two transformers to the maven snippet given into the Maven Shade Plugin documentation :

<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

source : http://robert-reiz.com/2011/11/14/832/

Hope it helps for understanding ;)

Share:
13,268
P456678
Author by

P456678

Updated on July 26, 2022

Comments

  • P456678
    P456678 almost 2 years

    I have a spring based application that does a component/package scan looking for packages within a certain namespace. The application runs perfectly in Eclipse and I'd like to create a single executable JAR to deploy to our various environments.

    I've tried various ways to get this to work but the only thing that's working is if I include the dependencies in a folder outside of the JAR. Here is what I have tried so far -

    1. Maven Compile to a single jar from here , using this approach the single JAR is created with the dependencies included as classes. When running the JAR using -

      “java –jar jarName.jar”

      I get an error stating - "Error: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace http://www.springframework.org/schema/context]"

    2. Using Export ‘As Runnable JAR file’ from Eclipse, and choose ‘Extract required libraries into generated JAR’ in the Library Handling section.

      This also builds one jar with the dependencies as classes within it. When running the jar, I get the same “Error: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/context]

    3. Using Export ‘As Runnable JAR file’ from Eclipse, and choose ‘Package required libraries into generated JAR’ in the Library Handling section.

      This builds one jar with the dependencies inside it as JARs (not classes). When I run this JAR I get the following error –

      “Cannot search for matching files underneath URL [rsrc:com/company/] because it does not correspond to a directory in the file system java.io.FileNotFoundException: URL [rsrc:com/company/] cannot be resolved to absolute file path because it does not reside in the file system: rsrc:com/company/ at org.springframework.util.ResourceUtils.getFile(ResourceUtils.java:210”

      So the JAR ran but was unable to do a scan for the components I was asking it to find.

    4. Using Export ‘As Runnable JAR file’ from Eclipse, and choose ‘Copy required libraries into a sub-folder next to the generated JAR’ in the Library Handling section.

      This creates a small JAR with a folder next to it which contains all of the dependencies as JARs. When I run this, everything works!

    Therefore I don’t think it’s an issue with my code, there seems to be an issue with packaging spring that does a scan inside a single JAR. Would that be correct?

    Does anyone have any advice on how to build a spring based application doing a package/component scan into a single runnable JAR?

    ANSWER:

    I added the following XML to my POM file and just used "mvn package", it created a single executable jar that worked. Why it worked is still a mystery.

          <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.3</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>com.company.project.MainApp</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>