Gendaful
Gendaful

Reputation: 5802

How to package the dependencies in jar using maven?

BackGround : I am working on a standalone application using Spring and Maven. I want to create a jar from my application so I can deploy it on a remote server and test it.

I am facing below issues,

(1) When I am exporting this jar as executable jar thru eclipse, I am getting below exception.

Exception in thread "main" 

org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate Spring NamespaceHan
dler for XML schema namespace [http://www.springframework.org/schema/context]
Offending resource: class path resource [applicationContext.xml]

Since the above issue with with spring.handlers file namespace conflict ,So, I thought to create a jar using plugin in Maven like as below.

    <plugin>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.2</version>
            <configuration>
            <archive>
                <manifest>
                  <addClasspath>true</addClasspath>
                  <mainClass>com.comcast.start.Application</mainClass>
                </manifest>
        </archive>
            <shadedArtifactAttached>true</shadedArtifactAttached>
            <shadedClassifierName>jar-with-dependencies</shadedClassifierName>
            <finalName>ds</finalName>
            <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>
                <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                    <resource>META-INF/spring.tooling</resource>
                </transformer>
            </transformers>
        </configuration>
        </plugin>

        <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                  <execution>
                    <id>copy-dependencies</id>
                    <phase>package</phase>
                    <goals>
                      <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                      <outputDirectory>${project.build.directory}/alternateLocation</outputDirectory>
                      <overWriteReleases>false</overWriteReleases>
                      <overWriteSnapshots>false</overWriteSnapshots>
                      <overWriteIfNewer>true</overWriteIfNewer>
                    </configuration>
                  </execution>
                </executions>
         </plugin>

But the issue here is I am not able to find a plugin which will copy the dependant libraries into my jar file. The copy-dependencies plugin will copy the file into my workspace but not place the libraries into the my jar file.

Since, I have to run this standalone jar on a remote machine, all the dependant libraries should be packaged inside this jar when the jar is created.

Please suggest if you have some ideas. Thanks

Upvotes: 0

Views: 2556

Answers (1)

Petr Kozelka
Petr Kozelka

Reputation: 7980

It seems that you are trying to create standalone executable jar. (or, is your primary goal to carry the dependencies inside one file? - please make this cleaner)

There are several approaches to do that, let me list some:

  1. simply unpack dependencies into ${project.build.outputDirectory} - simple cases only
  2. use maven-shade-plugin for roughly the same, but with resolving resource conflicts
  3. use onejar-maven-plugin which embeds dependency jars into the primary jar, and creates launcher with custom classloader to run it

Your fragment seems to be an invalid mixture of the first two approaches (because maven-jar-plugin does not support shaded* and transformers properties)

Note that in some cases, you cannot use first two - because some frameworks scan the classpath in order to list libraries in use, and these are reducing many manifests into one.

Most often the third one is working fine. It is my favorite also because it includes the original jars unmodified, which makes me more confident with the result, especially when experimenting with unstable libraries.

Upvotes: 1

Related Questions