In Maven how to exclude resources from the generated jar? - maven

When I create an executable jar with dependencies (using this guide), all properties files are packaged into that jar too. How to stop it from happening? Thanks.
UPDATE: I tried to exclude them using the Maven resources plugin, but then my application won't find the properties files when I run it in Eclipse (right click on the module -> Run As -> Java Application)
UPDATE: Thanks for your useful answers. I think I'd better spend time to learn Maven, for now I just choose the simplest solution.

To exclude any file from a jar / target directory you can use the <excludes> tag in your pom.xml file.
In the next example, all files with .properties extension will not be included:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>*.properties</exclude>
</excludes>
<filtering>false</filtering>
</resource>
</resources>
</build>

By convention, the directory src/main/resources contains the resources that will be used by the application. So Maven will include them in the final JAR.
Thus in your application, you will access them using the getResourceAsStream() method, as the resources are loaded in the classpath.
If you need to have them outside your application, do not store them in src/main/resources as they will be bundled by Maven. Of course, you can exclude them (using the link given by chkal) but it is better to create another directory (for example src/main/external-resources) in order to keep the conventions regarding the src/main/resources directory.
In the latter case, you will have to deliver the resources independently as your JAR file (this can be achieved by using the Assembly plugin). If you need to access them in your Eclipse environment, go to the Properties of your project, then in Java Build Path in Sources tab, add the folder (for example src/main/external-resources). Eclipse will then add this directory in the classpath.

This calls exactly for the using the Maven JAR Plugin
For example, if you want to exclude everything under src/test/resources/ from the final jar, put this:
<build>
<plugins>
<!-- configure JAR build -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<excludes>
<exclude>src/test/resources/**</exclude>
</excludes>
</configuration>
</plugin>
...
Files under src/test/resources/ will still be available on class-path, they just won't be in resulting JAR.

Put those properties files in src/test/resources. Files in src/test/resources are available within Eclipse automatically via eclipse:eclipse but will not be included in the packaged JAR by Maven.

Exclude specific pattern of file during creation of maven jar using maven-jar-plugin.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3</version>
<configuration>
<excludes>
<exclude>**/*.properties</exclude>
<exclude>**/*.xml</exclude>
<exclude>**/*.exe</exclude>
<exclude>**/*.java</exclude>
<exclude>**/*.xls</exclude>
</excludes>
</configuration>
</plugin>

Do you mean to property files located in src/main/resources? Then you should exclude them using the maven-resource-plugin. See the following page for details:
http://maven.apache.org/plugins/maven-resources-plugin/examples/include-exclude.html

Another possibility is to use the Maven Shade Plugin, e.g. to exclude a logging properties file used only locally in your IDE:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>${maven-shade-plugin-version}</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>log4j2.xml</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
This will however exclude the files from every artifact, so it might not be feasible in every situation.

When I create an executable jar with dependencies (using this guide), all properties files are packaged into that jar too. How to stop it from happening? Thanks.
Properties files from where? Your main jar? Dependencies?
In the former case, putting resources under src/test/resources as suggested is probably the most straight forward and simplest option.
In the later case, you'll have to create a custom assembly descriptor with special excludes/exclude in the unpackOptions.

here is another solution to exclude all files in resources folder, the final configuration looks like:
<build>
<!-- exclude all files in resources-->
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>**/**</exclude>
</excludes>
<filtering>false</filtering>
</resource>
</resources>
<!-- other configurations/plugins in the pom.xml-->
</build>
or we can use includes to only package some file or folder.
But this method has a side effect. IDE will also exclude the resource files in target/classes folder. maven-jar-plugin only affect jar file.
I found a better solution to execludes resourses folder using maven-jar-plugin, here we use includes:
<build>
<plugins>
<!-- configure JAR build -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<includes>
<include>**/*.class</include>
</includes>
</configuration>
</plugin>
...

Related

Java EE / Maven - package WEB-INF folder into multiple wars

I have a Java EE project packaged as an EAR using Maven, it contains two WAR modules (one web one mobile) in following structure:
EAR
-Entities.jar
-EJB.jar
-Test.jar
-Web.war
-Mobile.war
I have a directory within the Web.war/WEB-INF which contains some .xhtml files that are common to both .wars
Is there any way to instruct Maven to copy this directory into the other .war automatically during build?
eg. I would like..
WebApp-Web/src/main/webapp/WEB-INF/emails/*
to build into
WebApp/WebApp-web/WEB-INF/emails
AND
WebApp/WebApp-mobile/WEB-INF/emails
(I am using the maven-war-plugin btw)
If you add your shared resources into the "parent project" (or elsewhere), you could define the relative path in maven-war-plugin's webResources tag (for both web projects):
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<webResources>
<resource>
<directory>../src/main/resources</directory>
<targetPath>WEB-INF</targetPath>
</resource>
</webResources>
</configuration>
</plugin>
Another way would be to use the maven-resources-plugin to copy the files from a relative path at build-time, but I believe the maven-war-plugin approach is better.
Using maven-resources-plugin: (source how-to-get-a-war-package-with-resources-copied-in-web-inf)
I only changed the directory, to make it relative to its parent (ie: ../src/main/resource)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.4.2</version>
<executions>
<execution>
<id>default-copy-resources</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<overwrite>true</overwrite>
<outputDirectory>${project.build.directory}/${project.artifactId}-${project.version}/WEB-INF/</outputDirectory>
<resources>
<resource>
<directory>../src/main/resources</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
If you're using a web container that implements Servlet 3.0 or newer then you can make use of the web-fragment feature to build these common files into a jar file that is added to the WEB-INF/lib directory of each web application.
Make web resources such as your xhtml files available by placing them in the META-INF/resources directory of the jar file. Any web.xml configuration that might be associated with these xhtml files can be placed in a META-INF/web-fragment.xml file.

How to exclude certain resources from the maven war plugin war file?

We've been using war:exploded for a while now and I'm trying to do away with it. I've added the following to my pom:
<resource>
<directory>src/main/webapp</directory>
</resource>
This copies files such as the in src/main/webapp/keystore into target/classes/keystore so my local UI launcher works and sees everything. Score!
However, by adding to the resources list, this means that the same files also show up in the war file as keystore (correct) and WEB-INF/classes/keystore (wrong). It also means there there is a WEB-INF/classes/WEB-INF directory (blah). I'm trying to exclude the resource files from src/main/webapp resource since src/main/webapp/WEB-INF is already a resource.
I'm trying not to specifically exclude keystore and other files since we add/delete from that list semi-often. I've tried to add the following (and a number of other variants) to the war plugin configuration without results:
<webResources>
<resource>
<directory>src/main/webapp</directory>
<excludes>
<exclude>**</exclude>
</excludes>
</resource>
</webResources>
I've also read a number of other SO questions and I've spent at least an hour reading docs on from the maven war plugin page and tried other configs without success.
Any idea what magic I need to do here? Thanks in advance.
You need
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<packagingExcludes>**/keystore</packagingExcludes>
</configuration>
</plugin>
Also See
Including and Excluding Files From the WAR
warSourceExcludes worked for me. for example.To exclude js folder and scss folder from my war i tried...
<configuration>
<warSourceExcludes>js/*.*,scss/*.*</warSourceExcludes>
<webResources>
<resource>
<directory>src/main/webapp</directory>
<filtering>true</filtering>
<includes>
<include>WEB-INF/web.xml</include>
</includes>
</resource>
</webResources>
</configuration>
However, by adding to the resources list, this means that the same files also show up in the war file as keystore (correct) and WEB-INF/classes/keystore (wrong).
I was not able to get the war-plugin to properly exclude the webapp directory while at the same time allowing the webapp/WEB-INF directory. Instead of adding the following to the pom:
<!-- bad idea, this didn't work -->
<resource>
<directory>src/main/webapp</directory>
</resource>
I switched to using the resources-plugin to be able to copy certain resources over during the validate phase:
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/webapp</outputDirectory>
<resources>
<resource>
<directory>src/main/webapp</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
I initially copied the webapp directory into target/classes but that also seemed to make it into the resulting war file which was what I was trying to avoid. I have the feeling that I could have solved this if necessary.
Instead I decided to copy the webapp files into the target/webapp directory and change my program to look for the resources there:
String RESOURCE_BASE = "target/webapp";
System.setProperty("server.jetty.webapp.resourceBase", RESOURCE_BASE + "/");
System.setProperty("server.jetty.ssl.keystore", RESOURCE_BASE + "/keystore");
System.setProperty("server.jetty.ssl.truststore", RESOURCE_BASE + "/keystore");
...
This seems to be working well. Testing locally now works (without war-exploded!!) and the files are not doubly included in the resulting war file. In addition, I added a symlink at runtime from target/webapp/views/cms to point to our CMS hierarchy which is in another project.

maven-jar-plugin, include upper dir

Build part of POM
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<configuration>
<classesDirectory>./</classesDirectory>
<includes>
<include>*.wsdl</include>
<include>*.xsd</include>
<include>sources/</include>
<include>../configuration.doc</include>
</includes>
</configuration>
</plugin>
In target jar I have all wsdl from root dir, xsds from root dir and sources dir.
But no configuration.doc file in jar.
Any ideas?
You should move the configuration.doc into the appropriate directory like src/main/resources.
How about adding the relevant folder from where you want the .doc to be picked up to your project pom using maven resources plugin - specifically the <resources> configuration - there are examples here. This will make the contents available to the jar plugin.

Configure maven-shade-plugin to include src/main/webapp

I'm working with a simple project, with the webapp directory in the standard location (src/main/webapp). For some reason, it looks like the maven-shade-plugin doesn't include that in the final generated jar - it will only include artifacts src/main/resources by default.
I have tried to use the following configuration, with no luck:
<configuration>
<artifactSet>
<includes>
<include>*</include>
<include>*:*</include>
</includes>
</artifactSet>
</configuration>
Any suggestions on how to do that without having to move src/main/webapp into src/main/resources/webapp?
Thank you.
Eugen.
Have you tried to update your build section with your resource path ?
<build>
<resources>
<resource>
<directory>src/main/webapp</directory>
</resource>
</resources>
</build>
EDIT
As already said, shade purpose is not to war packages.
You need to put it in src/main/resources/webapp or specify the appropriate location explicitly for it to be caught up properly. Annoying, but it works.
For those asking why this kind of thing makes sense to do, it's a typical setup for a jar with an embedded web server like Jetty.
I use the resource plugin to move the webapp to the classes folder.
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>compile</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/classes/webapp</outputDirectory>
<resources>
<resource>
<directory>src/webapp/dist</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
This way I can place the folder with my webapp anywhere, define the destination directory and it is included in my shaded jar.
It sounds you would like to package sources into a package. There exists a maven-source-plugin which will create a jar which contain the source files. Furthermore this is usually done during a release cycle. As already mentioned the maven-share-plugin intention is to package jar files together (their contents; keyword: ueberjar).
I would use the war plugin http://maven.apache.org/plugins/maven-war-plugin/faq.html#attached to create a jar of a webapp project. You have already set <packaging>war</packaging>?
What's the point in adding your webapp resources into a JAR? That's WAR-like.
Change your packaking type to war and it will work.

maven resources plugin flat copy of resources

Given a folder 'database' containing JAR-connectors for different RDBMS. Each JAR is located in its own folder:
+---database
+---db2
+---db2.jar
+---derby
+---derby.jar
+---h2
+---h2.jar
+---mysql
+---mysql.jar
I need all of those JAR-files to be copied into WEB-INF\lib.
Here's my pom.xml:
<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<webResources>
<resource>
<directory>../target/${project.artifactId}/classes/database</directory>
<targetPath>WEB-INF/lib</targetPath>
<includes>
<include>**/*.jar</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
Problem is, that those JARs are copied with their directories:
+---WEB-INF/lib
+---db2
+---db2.jar
+---derby
+---derby.jar
+---h2
+---h2.jar
+---mysql
+---mysql.jar
This is how it should be:
+---WEB-INF/lib
+---db2.jar
+---derby.jar
+---h2.jar
+---mysql.jar
I have 20 connectors and I don't want to hard code them.
The most correct way of doing so will be to install your jar files into Maven repository and then use maven-dependency-plugin:copy goal. Or if you want to solve this roughly then use maven-antrun-plugin (copy rule).
You're having problems because you're trying to bend maven into something it's not supposed to do. Binary artifacts should be deployed into your artifacts repository (or local maven repository) and not included into your project. This way having them defined as dependencies in pom would ensure that they're copied into your WEB-INF/lib.

Resources