Maven: properties-file alongside jar - maven

I am packaging my application as jar.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<mainClass>...</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
And also I have my .properties-file placed inside of src/main/resources. I can freely move this file to any other place. I don't want properties-file to be included into jar, but rather placed into the same output directory (where we get jar) side-by-side. What is the best practice for this in Maven?

Okay, one can use goal resources:copy-resources of maven-resources plugin.
I am just leaving standard resources folder for embedded (into jar) resources. And for external resource I create another folder: src/main/external-resources. Here I put my .properties-file.
Following piece will copy external resources to output dir upon validate phase. You can alter the phase per your own needs.
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}</outputDirectory>
<resources>
<resource>
<directory>src/main/external-resources</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>

Related

Not able to add resources using Maven jar plugin

I have a src folder out of which i need to create multiple jars. Like each package as a separate jar. Also i need to put specific xml files from src folder into specific jars. I created a pom which creates multiple jars successfully using multiple executions in plugin. But the problem is the movement of xml files to jars is not happening. Have provided the pom file below.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<id>tra_common_id</id>
<goals><goal>jar</goal></goals>
<phase>package</phase>
<configuration>
<finalName>tra_common</finalName>
<encoding>ISO-8859-1</encoding>
<classifier>tra_common</classifier>
<includes>
<include>com/**/common/**</include>
<include>com/**/apm/*Access*</include>
</includes>
<excludes>
<exclude>com/**/management/**</exclude>
</excludes>
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
</archive>
</configuration>
</execution>
<execution>
<id>tra_client_id</id>
<goals><goal>jar</goal></goals>
<phase>package</phase>
<configuration>
<finalName>tra_client</finalName>
<encoding>ISO-8859-1</encoding>
<classifier>tra_client</classifier>
<includes>
<include>com/**/client/**</include>
</includes>
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
</archive>
</configuration>
</execution>
</executions>
</plugin>

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>

Create a zip file and add it to a war file with maven

I have some example RESTful client projects that go along with a RESTful Java web service I am working on. Basically, these projects should not be built but instead zipped up and included in the war file so that they will be available as static resources when the war file is deployed. This makes it easy to update the example clients along with the actual Java web service and guarantee that they are deployed together.
I've been able to use the maven assembly plugin to create a zip file but that stage executes after the war stage. I haven't been able to figure out the maven incantation needed to create the zip file then add it to the war file.
Here is what I have so far, but it only does about half the job. Also, I need to move the ExampleProject directory so the unzipped files don't go into the final war file.
pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptor>src/assembly/AssembleExamples.xml</descriptor>
<finalName>examples.zip</finalName>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
AssembleExamples.xml
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>bin</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${project.basedir}/WebContent/docs/</directory>
<outputDirectory/>
<includes>
<include>ExampleProject/pom.xml</include>
<include>ExampleProject/src/**</include>
</includes>
</fileSet>
</fileSets>
</assembly>
Two of the plugins maven-war-plugin and maven-assembly-plugin are required to be executed in the same phase, package. First, maven-assembly-plugin and then maven-war-plugin. You need to add the plugins in the following order to make sure that they run in same phase and correct order:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.0.1</version>
<executions>
<execution>
<id>prepare-war</id>
<phase>package</phase>
<goals>
<goal>exploded</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptor>src/assembly/AssembleExamples.xml</descriptor>
<finalName>examples.zip</finalName>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
You can generate the war using mvn package.
Here is how I ended up doing it.
Thanks to Mithun I realized that there are two ways to configure the war plugin and the way I was doing it was not appropriate for my situation.
This is what I added to my pom file:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<configuration>
<descriptor>src/assembly/AssembleJavaExample.xml</descriptor>
<finalName>myexample</finalName>
<appendAssemblyId>false</appendAssemblyId>
<outputDirectory>${project.build.directory}/${project.build.finalName}/docs</outputDirectory>
</configuration>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>true</failOnMissingWebXml>
<warName>mywar</warName>
<warSourceExcludes>docs/myexample/**</warSourceExcludes>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>war</goal>
</goals>
</execution>
</executions>
</plugin>
The assembly plugin had to go first so it would execute before the war plugin. The assembly plugin creates the zip file and places it in the directory that the war plugin uses to create the war file (the outputDirectory configuration). I then had to exclude the example sources from being included in the war file (the warSourceExcludes configuration). I'm not sure if this is the best way but it seems to be working out quite well.

Files got overwritten in maven project when building a war

I'm building a web application project using maven, and packaging is set to "war". I also use YUI compressor plugin to compress javascript codes in the webapp directory. I've set up the YUI compressor like this:
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.3.0</version>
<executions>
<execution>
<phase>process-resources</phase>
<goals>
<goal>compress</goal>
</goals>
</execution>
</executions>
<configuration>
<excludes>
<exclude>**/ext-2.0/**/*.js</exclude>
<exclude>**/lang/*.js</exclude>
<exclude>**/javascripts/flot/*.js</exclude>
<exclude>**/javascripts/jqplot/*.js</exclude>
</excludes>
<nosuffix>true</nosuffix>
<force>true</force>
<jswarn>false</jswarn>
</configuration>
</plugin>
If I do: mvn process-resources, src/main/webapp will get copied over to target/webapp-1.0/ directory, and javacripts are compressed. However, when I run mvn install, all the compressed javascripts are overwritten, apparently the packaging process copies the content from main/webapp one time before building the war file.
How can I get around this?
As you noticed, the /src/main/webapp dir (aka warSourceDirectory) contents is not copied into the project dir for packaging until the war plugin executes during the package phase. When the war plugin completes the archive is already built; too late to modify those resources. If the .js files you want to compress were moved into another directory (outside of /src/main/webapp) then you could do something like the below.
To test, I created a ${basedir}/src/play directory with a couple of files in it. I used the resource plugin for the example; you'd replace that config with the YUI compressor plugin config you needed and simply add the <webResource> element to your war plugin config as shown below; more info in the war plugin examples. My war ended up with the additional files right where I wanted them.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<phase>process-resources</phase>
<goals><goal>copy-resources</goal></goals>
<configuration>
<outputDirectory>${project.build.directory}/tmpPlay</outputDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/play</directory>
<includes>
<include>**/*</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<executions>
<execution>
<id>default-war</id>
<configuration>
<webResources>
<resource>
<directory>${project.build.directory}/tmpPlay</directory>
<targetPath>WEB-INF/yourLocationHere</targetPath>
<includes>
<include>**/*</include>
</includes>
</resource>
</webResources>
</configuration>
</execution>
</executions>
</plugin>
I think #user944849 answer is the correct answer, at least one of the correct answers. Another way of archiving this is to exclude the modified javascript directory from maven-war-plugin configuration, e.g.:
<plugin>
<artifactId> maven-war-plugin </artifactId>
<configuration>
<warSourceExcludes>**/external/ dojo/**/*.js </warSourceExcludes>
</configuration>
</plugin>
this will tell maven-war-plugin not to copy from the excluded directory, but since the modified javascript directory is already there, the war file still contains the javascript directory, BUT with the modified, in this case, compressed javascript codes.
in your execution directive, set the phase for applying your compression and copying to be install and that will hopefully do the trick. the code should be something like this:
<executions>
<execution>
....
<phase>install</phase>
....
</execution>
<executions>
Here is my solution, simply add an antrun plugin which updates the packaged war file using the processed outputs, which binds to the package phase:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>package</id>
<phase>package</phase>
<configuration>
<target>
<zip basedir="${project.build.directory}/${project.build.finalName}"
destfile="${project.build.directory}/${project.build.finalName}.war"
update="true">
</zip>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>

Unable to get unpack-dependencies to run before jar:jar,

I cannot get maven-dependency-plugin/unpack-dependencies to run before maven-jar-plugin/jar when running mvn clean install from the command line.
Every time, I see it running jar:jar before the unpack stuff runs, I saw in my googling some talk of adding a pre-package phase to the maven lifecycle, doesn't seem to be working thought.
Basically I want to create a single jar file containing all necessary classes (all 2600 of them). This jar gets a Manifest which enables it to be run in the manner of:
java -jar blah.jar
If I ever get it to work...
And here's the xml snippet...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<id>unpack-dependencies</id>
<phase>package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>archivedb.Read</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
In your original question, replace the phase with the following phase.
<phase>prepare-package</phase>
this will cause the jars to be extracted first. For your problem, the shade solution is better, but I will still post this here as a reference for other with similar problems where shade does not help.
The output path is set to make sure that jar's contents end up in dir that the jar:jar goal packages (target/classes).
Full plugin execution xml snippet:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>unpack-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includes>**/*.class</includes>
<excludes>**/*.properties</excludes>
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
I had similiar issue with single jar creation.
My solutions incorporates standard maven-dependency plugin with unpack goal (unpacks all dependencies during compile process and move it into custom outputDirectory.
The secret is, JAR plugin takes all from target/classes directory and packs as a one JAR.
That's why I defined custom outputDirectory. Have a look at the code below:
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<finalName>${project.artifactId}</finalName>
<archive>
<manifest>
<mainClass>pl.company.client.Uploader</mainClass>
</manifest>
</archive>
</configuration>
<version>2.3.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.4</source>
<target>1.4</target>
</configuration>
<version>2.3.2</version>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-dependencies</id>
<phase>compile</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
You may run it by identifying the goal sequentially as
"mvn clean dependency:unpack jar:jar install"
I hope this may help you to achieve the requirement
Regards,
Charlee Ch.

Resources