Maven WAR <overlays> - Include a file from WEB-INF/classes - maven

I would like to pick a class file(StartEngine.class) from my WEB-INF/classes and put in the root directory of my WAR file to get below structure
process-engine.war
|
|-WEB-INF
|-js
|-StartEngine.class
|
I used of maven war but its not copying it. Please help me if anyone has any solution for the same.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<overlays>
<overlay>
<artifactId>process-engine</artifactId>
<excludes>
<includes>
<include>/WEB-INF/classes/StartEngine.class</include>
</includes>
<type>jar</type>
</overlay>
...
</plugins>

It looks like your configuration needs to be reworked. First of all, I suggest reading this page for a better understanding of overlays. There are a couple of possible situation which aren't clear to me from your question:
An overlay is supposed to come from a separate artifact. If you are indeed trying to pull in the StartEngine.class file from a separate artifact, then you'll need to add the groupId as well as the artifactId. Also since the class file is in a WEB-INF directory, then I'd suspect that this artifact would be of type 'war' (not jar).
If you are trying to move a file that is already in the project, then an overlay is not what you should use. Moving a class file to the base of the war file isn't a standard layout and if you must do this, then I suggest looking at the maven resources plugin's copy resources goal

Related

maven-jar-plugin does not include .gitignore file

I try to package an application into a jar file with maven. Somehow all files except .gitignore files are added to the jar.
Why is this file skipped and how can I disable this?
Even if I try to include it like below the include is ignored and the jar file remains empty.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<includes>
<include>**/.gitignore</include>
</includes>
</configuration>
</plugin>
maven-jar-plugin version: 3.1.0
maven version: 3.5.2
I tried this with a src/main/resources/.gitignore and it worked with the default maven-jar-plugin:2.4, i.e. .gitignore was packaged into the JAR.
Then I used the maven-jar-plugin:3.1.0 you mention and it did not work, as you describe.
It turned out that it doesn't work from v2.5 onwards.
I have the same issue with a .metadata folder in the target/classes folder. The .metadata folder is not included in the jar archive.
For me, it is not working with maven-jar-plugin:2.4 and upper. With version 2.3 it is working.
I submitted this issue : https://issues.apache.org/jira/browse/MJAR-265
The first thing is using a jar file example projects is astonishing. I would never expect to have example projects within a .jar file. The intention of a jar files is something different. I would suggest to use something more appropriate like .zip or .tar.gz etc. (This can be achieved with the maven-assembly-plugin) This will prevent accidental not intended use.
Apart from the whole problem is based on the definition of resources which are usually copied from src/main/resources to the target/classes directory. This is done by the maven-resources-plugin.
The maven-resources-plugin plugin has some kind of configuration which excludes some files which are usually not copied which contains .gitignore. So this means just putting a .gitignore file into src/main/resources will not produce the expected result nor using <includes>..</includes> configuration will not help here as well.
This means you need to change the default configuration of maven-resources-plugin via pluginManagement section like the following:
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<addDefaultExcludes>false</addDefaultExcludes>
</configuration>
</plugin>
Than the .gitignore file will be copied and should be packaged into the resulting jar file (Which I would not recommend to do.)

How to generate a resource to be included in Jar file with maven?

During my build I need to some files to be generated by an external tool. For my minimal compilable example I reduced my "external tool" to the following script:
mkdir -p target/generated-resources
echo "hello world" > target/generated-resources/myResource.txt
Now I want to execute my external tool during build and the generated resource should be included in the war file. I could not find any documention on how that should be done, so it was just a guess that I need to write my generated resource to target/generated-resources. So maybe that is a problem?
I created a pom.xml file with the following build configuration:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>./createResource.sh</executable>
</configuration>
</plugin>
</plugins>
</build>
If I run mvn package my createResource.sh script gets executed successfully and the myResource.txt file is created. However the myResource.txt file is not included in the resulting .jar file.
I noticed that it works if I add
<resources>
<resource>
<directory>target/generated-resources</directory>
</resource>
</resources>
to my build config, but I fear that this may cause problems if other plugins which may use this directory differently (Do they? I could not really find anything about the conventions of the target directory).
Additionally I'd prefer a solution that works with the usual maven conventions (if a convention for this case exists).
How do I correctly generate a resource to be included in the jar file during build using maven?
Convention (or main usage at least)for Maven is to generate resources inside (target/generated-resources/[plugin/process]).
But unlike generated sources and compiler plugin, generated resources are not handled specifically by the jar plugin, so you do have to add it as a resource (with a new resource like you did or the build-helper-plugin).
If you follow the convention to place everything you generate under a sub-directory of generated-resources, you should have no fear about how other plugins use it.

How to include a generated file into the war with maven, but to not add it to source

I have a dependencies from other projects (.jsp's, .tag files) that I need in my maven project. To solve this I have created a "resource" jar from these other projects and have specified them as a dependency in maven. I then unzip the jar (in ant, during the generate-sources lifecycle phase) and copy files to where they need to go. This is where the question is (suggestions on a better overall approach are also welcome). I was thinking I could just move these files into the target directory where I want them and they'd be packaged with the war, but that doesn't work. The common approach seems to be to add an additional resource directory to the war plugin:
How create file and put it in a war with Maven?
Rename a generated file in Maven before building WAR
However, I really don't want to keep these files around in my source code, since they belong to another project. Is there a way I can include temporary resources into the jar?
I would say that this is a typical case when you should be looking at Maven War Overlay.
Overlays are used to share common resources across multiple web applications. The dependencies of a WAR project are collected in WEB-INF/lib, except for WAR artifacts which are overlayed on the WAR project itself.
It means that you can take pieces of another war and apply to your own war. The best thing would be if all the common resources would be in one parent war that would be used by other wars using the overlay technique.
You add a dependency to the war you want to use as an overlay:
<dependency>
<groupId>com.acne</groupId>
<artifactId>acne-web-style</artifactId>
<type>war</type>
<scope>compile</scope>
</dependency>
Then you apply it in the maven-war-plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.2</version>
<configuration>
<overlays>
<overlay>
<groupId>com.acne</groupId>
<artifactId>acne-web-style</artifactId>
<includes>
<include>**/resources/*.jpg</include>
</includes>
</overlay>
<overlay>
<!-- empty groupId/artifactId represents the current build -->
</overlay>
</overlays>
</configuration>
</plugin>

How to Include a SINGLE dependency into a jar using maven and fatjar plugin

I feel a bit stupid about this question but i can't figure out how to add a SINGLE dependency (jdom.jar) into another jar.
Context: We developed a simple plug-in for our application, this plug-in have many dependency. We were using fatjar to include jdom.jar into it. I am trying to fix a bug in this plug-in, so i decided to "maven-ize" it at the same time. (We just switched to maven) This plug-in is loaded on the runtime so the only dependencies we want packaged with it is the jdom.jar.
Problem: I found that there is a maven fatjar plug-in! Unfortunately i could not find any documentation and this maven plug-in add EVERY dependency into the ouput jar. After many try i decided to give up on this fatjar plug-in and searched for another one. I found one-jar , shade but after a quick read on them they look like they add every dependency.
Question: what would be a simple way to add only jdom.jar into my plug-in jar like this:
-MyPlug-in.jar
|
|-src
|-main
|-java
|-*.java
|-jdom.jar
Also I don't want to alter the manifest or the output jar filename
Thank a lots for your time.
There was no answer here regarding how to use maven to include one single jar-file with the maven-shader-plugin. It took me some time to figure out how to actually do that. Here is a snippet to include just the classes from the dependency com.googlecode.json-simple:json-simple.
<project>
...
<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>com.googlecode.json-simple:json-simple</include>
</includes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
...
</plugins>
</build>
...
</project>
For this kind of purpose i would suggest to use the maven-shade-plugin which will create a ueber-jar which can be controlled in many ways.
With the shade plugin you can exclude things you don't like. But this might be caused by not using a separate maven module where you can control the dependencies.
Using maven Shade would work fine, one-jar would have done the job too.
But we finally decided that packaging jdom in our extension would be a bad practice.
So instead we gonna do this:
|-Root application Folder
|-Extension Folder
|-MyExtension.jar
|-libs Folder
|-jdom.jar
The jar into the lib folder will be loaded dynamically and won't be loaded if the extension cannot find the appropriate libs into the libs folder.
For the people who look to solve my primary problem please check out #khmarbaise Answer.

Where should I put application configuration files for a Maven project?

I'm using the Maven Application Assembler plugin to generate stand-alone executables from my Java project. The application reads in configuration files, including Spring files. The Application Assembler plugin has an option (activated by default) to add a etc/ directory to the application's classpath, but what should I do to have the plugin copy my configuration files to this directory?
Or more generally, where is in Maven the kosher location for application configuration files that should NOT be packaged in the artifact?
You can also use resource filtering:
http://maven.apache.org/guides/getting-started/index.html#How_do_I_filter_resource_files
turn on filtering:
...
<build>
...
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
...
</build>
...
make a file under src/main/resources like: application.properties
application.properties
configprop.1=${param1}
configprop.2=${param2}
Then setup a profile and set some properties perhaps in a settings.xml
that sets different properties depending on if this is a dev or production build.
see: http://maven.apache.org/guides/introduction/introduction-to-profiles.html
I have different properties set depending on if this is the build server, dev or a production deployment
mvn -Denv=dev || mvn -Denv=dev-build || mvn -Denv=production
The maven link has a pretty good description.
For folks who have come to this more recently there is, since version 1.1 of the Application Assembler Plugin, the optional parameters configurationSourceDirectory and copyConfigurationDirectory. Please find them in an example POM.xml extract below:
<configuration>
<!-- Set the target configuration directory to be used in the bin scripts -->
<configurationDirectory>conf</configurationDirectory>
<!-- Copy the contents from "/src/main/config" to the target
configuration directory in the assembled application -->
<copyConfigurationDirectory>true</copyConfigurationDirectory>
<!-- Include the target configuration directory in the beginning of
the classpath declaration in the bin scripts -->
<includeConfigurationDirectoryInClasspath>
true
</includeConfigurationDirectoryInClasspath>
...
</configuration>
More information is here
You could try the maven assembly plugin. I used it in conjunction with the appassembler plugin.
Configure appassembler to point to whatever name you want for your configuration directory, if you don't want 'etc'. The assembly plugin assembles everything in its own output directory, so I configure the assembly plugin to copy the bin and repo dirs from the appassembler directory into its output dir, then I have it copy the config files (mine are in src/main/config) into the expected config dir. There is some duplication in this, because you are copying the appassembler outputs, but that didn't really bother me.
So what you have after executing the assembly plugin is your bin, repo, and config dir are all peer directories under the assembly output directory. You can configure it to have a different structure if you prefer, I just wanted mine to mirror the appassembler structure.
The nice thing is that you can also configure the assembly plugin to change your binaries to executables, which I could't see how to do with appassembler. And, if you then bind appassembler:assemble and assembly:single goals to the package phase, all you have to do is 'mvn package', and it assembles everything.
I don't know if I understand you correctly. But what I have done in the past for a project where I needed to copy configuration files, is use the Maven AntRun plugin. What I did is execute the plugin in the process-resources phase and copied my configuration files to the specified directory using the Ant copy task. The Assembler plugin executes in the package phase so it should pick up your configuration files if you put it in the right place. Hope this answers your question a little bit.
I had been looking for an answer to what I think is your question, or at least a very similar question. Maven allows you to specify directories for resources using the maven-resources-plugin. I have a few configuration files in one of my resource directories. I've noticed that by putting copies of those files in the etc/ directory that you mention (which is at the beginning of my CLASSPATH) I can change values in those files for use at run time. I then wanted to have that etc/ directory created with copies of everything from my resource directory by default. The copy-resources goal from the maven-resources-plugin allowed me to do that. This stanza from Examples > Copy Resources on the left sidebar (I'm limited to 2 links in this post) is what did it for me:
<project>
...
<build>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-resources</id>
<!-- here the phase you need -->
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/extra-resources</outputDirectory>
<resources>
<resource>
<directory>src/non-packaged-resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
...
</build>
...
</project>

Resources