Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add resources to jar using maven shade plugin

Tags:

java

maven

My Project structure has resources folder inside the src/main/ folder. The resources folder contains the file server.properties. My pom is as follows:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.fde</groupId>
    <artifactId>Listener</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>Listener</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <hibernate.version>3.6.10.Final</hibernate.version>
        <java.version>1.6</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <!-- Hibernate dependencies START -->
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.0</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-ehcache</artifactId>
            <version>${hibernate.version}</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>${hibernate.version}</version>
        </dependency>
        <dependency>
            <groupId>javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.12.1.GA</version>
        </dependency>
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>3.2.1</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.9</version>
        </dependency>
        <!-- Hibernate dependencies END -->
    </dependencies>
    <build>
        <sourceDirectory>src/main/java</sourceDirectory>
        <resources>
            <resource>
                <directory>resources</directory>
            </resource>
        </resources>
        <testSourceDirectory>src/test/java</testSourceDirectory>

        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.2</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>com.fde.ListenerServer</mainClass>
                                </transformer>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.IncludeResourceTransformer">
                                    <resource>resources</resource>
                                    <file>server.properties</file>
                                </transformer>
                            </transformers>
                            <artifactSet>
                                <excludes>

                                    <exclude>junit:junit</exclude>

                                </excludes>
                            </artifactSet>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>
</project>

The Jar is created properly and the main class is mentioned in the manifest. I have the following questions :

  1. The target folder contains the classes folder whch has the class files. The jar also contains them so why are they needed. My goal is to have a executable jar with all the dependancies only.

  2. The resources are not getting added in the jar at all. I have added the transformer according to instructions seen on the net but no use!!!

  3. What are the other dir getting created in the target folder (maven-archiver, surefire, surefire-reports etc) ??

  4. Another jar gets created every time i do a maven clean install (original-Listener....jar)

I have absolutely no clue about how to include resources. Any help is appreciated!!

EDIT:::

This is the tag i used for the maven-assembly-plugin:

 <plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <executions>
      <execution>
        <phase>package</phase>
        <goals>
          <goal>attached</goal>
        </goals>
      </execution>
    </executions>
    <configuration>
    <archive>
            <manifest>
              <mainClass>com.fde.ListenerServer</mainClass>
            </manifest>
          </archive>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
    </configuration>
  </plugin>

This created the Listener-1.0-SNAPSHOT-jar-with-dependencies.jar with all the classes from referred jars in the folders. The manifest also contains the main class.

The problem still is that I cant include the resource bundle in the folder \src\main\resources.

Also I cant understand why jar files referenced from my code are included in the jar as well as inside the META-INF folder.

like image 827
kavita Avatar asked Feb 10 '14 14:02

kavita


People also ask

What is the use of Maven Shade plugin?

This plugin provides the capability to package the artifact in an uber-jar, including its dependencies and to shade - i.e. rename - the packages of some of the dependencies.

What is transformer in maven shade plugin?

Aggregating classes/resources from several artifacts into one uber JAR is straight forward as long as there is no overlap. Otherwise, some kind of logic to merge resources from several JARs is required. This is where resource transformers kick in.

Are Maven dependencies included in jar?

The difference is that the Maven Assembly Plugin will automatically copy all required dependencies into a jar file. In the descriptorRefs part of the configuration code, we provided the name that will be added to the project name. Output in our example will be named as core-java-jar-with-dependencies.


2 Answers

The problem wasn't in your maven-shade-plugin's configuration, rather that you have explicitly set resource directory to a wrong path:

    <!-- wrong -->
    <resource>    
      <directory>resources</directory>
    </resource>

As <directory> element's doc says: "Describe the directory where the resources are stored. The path is relative to the POM."

So if you follow default maven project structure you have to set like this:

    <!-- correct -->
    <directory>src/main/resources</directory>

or don't set it, then it falls back to same as maven defaults.

like image 144
Daniel Hári Avatar answered Oct 05 '22 14:10

Daniel Hári


I removed the following from the pom.xml and the property files were included at the root dir.

<sourceDirectory>src/main/java</sourceDirectory>
    <resources>
      <resource>
        <directory>resources</directory>
      </resource>
    </resources>
    <testSourceDirectory>src/test/java</testSourceDirectory>

Still havent figured out why there is a repetition of the referred classes in the jar.

like image 41
kavita Avatar answered Oct 05 '22 13:10

kavita