How to package config.yml and resources in $project--0.0.1-SNAPSHOT.jar - maven

I've a drop wizard project which has the following directory structure:
basedir
pom.xml
config.yml
src
main
resources
myresource.xml
The build portion of
<build>
<finalName>project-${version}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>project-package.App</mainClass>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer">
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
When I run my code from Eclipse, I use command as follows:
$mypackage.App server config.yml
It works fine and I can read the file under resources directory.
When I use mvn to build, in the snapshot jar created, it does not include config.yml and the path to "myresource.xml" is missing even though it is included in the snapshot.jar in the basedir. So, when I run it from my jar file, my code does not find it as resources.
How should I change the pom.xml to include config.yml and package the resource directory such a way that it is accessible as resource.

It is really strange that
this.getClass().getResource("myresource.xml")
does work in IDE but NOT when you run it from a jar.
this.getClass().getResourceAsStream("myresource.xml")
works both inside IDE and from jar.
That resolves the resources issue. However, I need an answer for how to package config.yml file. Should I supply separately in addition to the jar file?

Related

include package in maven while preparing jar

I have below project structure. I wanted to prepare a jar with dependencies including different packages which has .java files.
Project Structure:
src/com/rev/automation/utilities
src/com/rev/automation/testdata
src/com/rev/automation/pages
Main Class:
org.openqa.selenium.remote
How to include "src/com/rev/automation" packages into the jar in maven? i'm preparing the jar using below code, But it is not including packages and files present in "src/com/rev/automation". Kindly suggest
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<!-- get all project dependencies -->
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<!-- MainClass in mainfest make a executable jar -->
<archive>
<manifest>
<mainClass>org.openqa.selenium.remote.RemoteWElement</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<!-- bind to the packaging phase -->
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
While using Maven, you need to follow the Maven Standard Directory Structure.
In your case, create a folder structure like src/main/java and put all your code in java directory. So it should now look like src/main/java/com/rev/automation etc.
If you follow this structure, then your package will get included in the jar.
Update:
If you absolutely don't want to / cannot do what is mentioned above, alternatively, you can use the Maven Build Helper plugin. This will tell maven to include the specified directory as an additional source directory.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>src</source> // specify your directory here
...
</sources>
</configuration>
</execution>
</executions>
</plugin>

How can I specify a custom MANIFEST.MF file while using the Maven Shade plugin?

When a project uses the Maven-jar-plugin, it's easy to include a custom manifest file in the jar, but I can't find a way to do the same thing with Maven shade. How can I use my own manifest file while using the "Maven-shade-plugin"?
Additional details:
My custom manifest file is located in "src/main/resources/META-INF/MANIFEST.MF".
Maven is not including my file, instead it is being replaced in the final jar with a default Maven manifest file.
The reason I need a custom manifest file is to specify some JavaBeans classes in my manifest, for a swing component library. Multiple JavaBeans classes should be specified in the manifest file in the following format, as described here. Note that the empty lines (and the line grouping) are important for marking JavaBeans classes in the manifest.
Name: SomeBean1.class
Java-Bean: True
Name: SomeBean2.class
Java-Bean: True
Name: SomeBean3.class
Java-Bean: True
A list of attempted solutions (these did not work):
This code only works when using the Maven jar plugin (not shade).
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
This link says "As with all the examples here, this configuration can be used in all plugins that use Maven Archiver, not just Maven-jar-plugin as in this example." Based on that advice, I tried the following code, but this did not work either. (Maven still replaced my manifest file with the default manifest file.)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<archive>
<manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
</archive>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>core</shadedClassifierName>
<createDependencyReducedPom>false</createDependencyReducedPom>
<minimizeJar>true</minimizeJar>
</configuration>
</execution>
</executions>
</plugin>
I cannot use the shade "ManifestResourceTransformer" as described here to do the job, for the following reason. I need to add JavaBeans classes to my manifest file as described above under "additional details". However, if I add manifest entries using the shade ManifestResourceTransformer, those entries are inserted into the manifest file in an unpredictable (random-seeming) ordering. For specifying JavaBeans classes, the ordering of the manifest entries (the line order) is important.
I attempted to use IncludeResourceTransformer, but the below code produces the following error: "Error creating shaded jar: duplicate entry: META-INF/MANIFEST.MF".
<configuration> <shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>core</shadedClassifierName><createDependencyReducedPom>false</createDependencyReducedPom>
<minimizeJar>true</minimizeJar>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.IncludeResourceTransformer">
<resource>META-INF/MANIFEST.MF</resource>
<file>src/main/resources/META-INF/MANIFEST.MF</file>
</transformer>
</transformers>
</configuration>
The following pom configuration allows the programmer to replace the manifest file created by Apache Maven Shade plugin, with a custom manifest file. The custom manifest file should be placed in this directory in the maven project: "src/main/resources/META-INF/MANIFEST.MF"
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
...
<transformers>
<!-- Don't do this: Avoid adding anything that makes shade create or modify a manifest file.
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.mypackage.MyMainClass</mainClass>
</transformer>
-->
<!-- Add a transformer to exclude any other manifest files (possibly from dependencies). -->
<transformer implementation="org.apache.maven.plugins.shade.resource.DontIncludeResourceTransformer">
<resource>MANIFEST.MF</resource>
</transformer>
<!-- Add a transformer to include your custom manifest file. -->
<transformer implementation="org.apache.maven.plugins.shade.resource.IncludeResourceTransformer">
<resource>META-INF/MANIFEST.MF</resource>
<file>src/main/resources/META-INF/MANIFEST.MF</file>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>

Couldnt find ab-cd config file for this filepath:config.properties. <phase>package</phase><goals> <goal>shade</goal> </goals>

mvn package - ruunable jar file is unable to locate this properties file. In Eclipse my application runs fine but after i create mvn package. runnable jar file is giving me me null pointer. I used 7zip to view the create runnable jar file i see config.properties is correctly added in jar but my ruunable application jar is not picking it up.
I am getting null pointer here..... Its coming from JAR file which i cant edit.
ClassLoader classLoader = super.getClass().getClassLoader();
File file = new File(classLoader.getResource(fileName).getFile());
if (file.exists()) {
reader = new FileReader(file);
instance.properties.load(reader);
} else {
System.out
.println("Couldnt find ab-cd config file for this filepath:"
+ fileName);
Couldnt find ab-cd config file for this filepath:config.properties Oct 18, 2015 3:47:24 PM org.springframework.ws.soap.saaj.SaajSoapMessageFactory afterPropertiesSet INFO: Creating SAAJ 1.3 MessageFactory with SOAP 1.1 Protocol java.lang.NullPointerException at java.net.URI$Parser.parse(URI.java:3004) at java.net.URI.(URI.java:577) at java.net.URI.create(URI.java:839) at org.springframework.ws.client.core.WebServiceTemplate$1.getDestination(WebServiceTemplate.java:213) at org.springframework.ws.client.core.WebServiceTemplate.getDefaultUri(WebServiceTemplate.java:188) at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:380) at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:372) at
My pom.xml file to build it
<build>
<finalName>AE</finalName>
<plugins>
<!-- download source code in Eclipse, best practice -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<configuration>
<downloadSources>true</downloadSources>
<downloadJavadocs>false</downloadJavadocs>
</configuration>
</plugin>
<!-- Set a compiler level -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
</configuration>
</plugin>
<!-- Maven Shade Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<!-- Run shade goal on package phase -->
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<!-- add Main-Class to manifest file -->
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.abcdedf.ghi.main.Start</mainClass>
<manifestEntries>
<Class-Path>.</Class-Path>
</manifestEntries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>

Maven shade plugin does not merge files

My goal is to merge two XML files (both named info.xml) which are in src/main/resources of two Maven modules (packaging:jar) into a target WAR archive.
proj1: contains src/main/resources/info.xml
proj2: contains src/main/resources/info.xml
web: web project which should contain a merged info.xml from proj1 and proj2. I declared the plugin in the web project:
<build>
<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.XmlAppendingTransformer">
<resource>info.xml</resource>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
To build the web project and its modules I have a build project with:
<modules>
<module>proj1</module>
<module>proj2</module>
<module>web</module>
<modules>
I tried using a mvn clean package command in the build project and as result my web/target/web.war contains the unpacked libs (ueber.jar which I don't really want) and NO merged info.xml files.
What am I doing wrong?!
You have to configure Transformers to merge files, since it often requires extra logic, especially XML. See Resource Transformers for the details.

Usage of the maven-shade plugin's AppenderTransformer

Okay, I am running into the typical problem in which I need to create a uber jar, but my project dependencies has multiple spring.handlers and spring.schemas files. I have search around and figured out that my problem required me to use the maven-shade plugin, along with it's AppendingTransformer. The problem is that when I add the configuration and run the goal it does not merge the files; what's more, I can put a bogus classpath in for the appender or resource file and it does not complain, which lead me to believe that it is not even attempting to execute the transformer.
execute- mvn compile package shade:shade
<build>
<finalName>mongo-dictionary</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.7.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
I had my plugins configured as children of the pluginManagement element, once I got rid of the pluginManagement tag everything works as advertised.
where is this plugin configuration, can you ensure that it is in the right place - build -> plugins element of the project for which you are creating uber jar. I have the same configuration which works for me.
Also you don't need to execute shade:shade separately. Running mvn package will do that for you.

Resources