Exclude all but some artifacts with Maven shade - maven

Is there a way to create a fat jar with Maven that only contains some but not all dependency artifacts?
More concretely, I want to have two executions of shade: one that includes com.acme:* and one that includes all else. The point is to have two jars -- one with all my code and one with all the 3rd party deps. The latter is easy:
<artifactSet>
<excludes>
<exclude>com.acme:*</exclude>
</excludes>
</artifactSet>
But the former isn't. Because exclusions are processed after inclusions and everything is included by default, the following would not work:
<artifactSet>
<excludes>
<exclude>*:*</exclude>
</excludes>
<includes>
<include>com.acme:*</include>
</includes>
</artifactSet>
Any Maven mavens out there? (sorry but I had to)

Related

outputFileNameMapping and exclude problem with maven-assembly-plugin (3.1.0)

I have a multi-module maven project with two separate "main" projects (projectA and projectB) from which I would like to build a zip file (incl. all dependencies).
One of the dependencies "subProjectC" I would like to exclude. This is the relevant portion of assembly.xml:
<moduleSets>
<moduleSet>
<!-- Enable access to all projects in the current multimodule build! -->
<useAllReactorProjects>true</useAllReactorProjects>
<includes>
<include>${project.groupId}:projectA</include>
<include>${project.groupId}:projectB</include>
</includes>
<excludes>
<exclude>${project.groupId}:subProjectC</exclude>
</excludes>
<binaries>
<outputFileNameMapping>${module.artifactId}.${module.extension}</outputFileNameMapping>
<outputDirectory>project-root/lib</outputDirectory>
<unpack>false</unpack>
</binaries>
</moduleSet>
</moduleSets>
subProjectC turns up in the zip file nevertheless.
Also, all dependencies show up with their full version, e.g. projectA-0.0.1-SNAPSHOT.jar, although the outputFileNameMapping should have prevented this...
What am I doing wrong?
Ok, it seems "outputFileNameMapping" only affects those artifacts that are specified in the "includes" list...

Maven: How to exclude an artifact from fat-jar?

I know about the <exclusions> attribute that is placed inside a <dependency> to exclude specific artifacts from a dependency but the problem with this is that one has to find out all the dependencies that might have the artifact that is desired to be excluded and then one by one exclude that artifact from all those dependencies. Isn't there a simpler way of specifying in the pom that a certain artifact should not end up in the fat-jar no matter what dependency is trying to include it?
I found the answer here and here
Use artifactSet exclusions:
<artifactSet>
<excludes>
<exclude>classworlds:classworlds</exclude>
<exclude>junit:junit</exclude>
<exclude>jmock:*</exclude>
<exclude>*:xml-apis</exclude>
<exclude>org.apache.maven:lib:tests</exclude>
<exclude>log4j:log4j:jar:</exclude>
</excludes>
</artifactSet>
and also use filters to exclude classes:
<filters>
<filter>
<artifact>junit:junit</artifact>
<includes>
<include>junit/framework/**</include>
<include>org/junit/**</include>
</includes>
<excludes>
<exclude>org/junit/experimental/**</exclude>
<exclude>org/junit/runners/**</exclude>
</excludes>
</filter>

Why does maven create two copies of my filtered persistence.xml?

Below is the relevant section of the maven project I'm working on. I would like Maven to filter the persistence-context.xml file inside of the WEB-INF directory, and then place it into the WEB-INF directory inside of my war. When I run mvn clean package on this project I see the following two things.
The successfully filtered persistence-context.xml in the target/projectname/ folder. This is NOT the correct place. I want it one directory up in the WEB-INF.
The unfiltered persistence-context.xml in the target/projectname/WEB-INF/ folder. This is NOT what I want. I want the filtered one here.
I'm not even sure how two copies of this file are being generated! Any help would be much appreciated.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<webResources>
<resource>
<directory>${basedir}/src/main/webapp/WEB-INF</directory>
<filtering>true</filtering>
<includes>
<include>persistence-context.xml</include>
</includes>
<targetPath>WEB-INF</targetPath>
</resource>
</webResources>
</configuration>
</plugin>
I realized I had another plugin entry for the war plugin which was interfering (possibly overwriting?) with this one. Once I removed that my above entry worked okay!

Maven - Exclude certain resource files into WAR from the default src/main/resources location

Currently, I want to exclude some files from the default src/main/resources folder into my WAR when packaging
I tried using maven-war-plugin with the following configuration but failed.
<webResources>
<resource>
<directory>src/main/resources</directory>
<targetPath>WEB-INF/classes</targetPath>
<excludes>
<exclude>*.xml</exclude>
</excludes>
</resource>
</webResources>
...WEB-INF/classes will still contain the XML files.
How to do so?
As pointed out in https://stackoverflow.com/a/2737635/722997, a quick way to exclude files from the WAR package is to exclude them in the build->resources section, like:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>*.xml</exclude>
</excludes>
</resource>
</resources>
...
</build>
Note: take into account that the following configuration will only affect default executions of Maven (WAR package, JAR package, ...), but not assemblies or other user configurations.
This is somewhat late to this question, but I was just trying to do the same thing, and have found that (with the maven-war-plugin 3.1.0 version), adding:
<packagingExcludes>WEB-INF/classes/*.xml</packagingExcludes>
to the configuration should do what was asked for (it worked for me to remove properties files we didn't want to distribute with the war file).
From the documentation of maven war plugin, you can include and exclude resources as follows:
...
<configuration>
<webResources>
<resource>
<!-- the default value is ** -->
<includes>
<include>**/pattern1</include>
<include>*pattern2</include>
<includes>
<!-- there's no default value for this -->
<excludes>
<exclude>*pattern3/pattern3</exclude>
<exclude>pattern4/pattern4</exclude>
</excludes>
</resource>
</webResources>
</configuration>
...
Are you following this and it still does not work? If so, can you post your pom snippet?

In Maven how to exclude resources from the generated jar?

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>
...

Resources