Maven shade plugin does not exclude an artifact - maven

I need to exclude the log4j artifact from the shade plug-in to avoid the log4j vulnerability, however, the exclude tag under artifactSet does not seem to work. Any suggestion to fix this?
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
~~
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<excludes>
<exclude>*:log4j-core:jar</exclude>
</excludes>
</artifactSet>
~~~
I keep getting below error:
Failed to execute goal org.apache.maven.plugins:maven-shade-plugin:3.2.4:shade (default) on project : Execution default of goal org.apache.maven.plugins:maven-shade-plugin:3.2.4:shade failed: Plugin org.apache.maven.plugins:maven-shade-plugin:3.2.4 or one of its dependencies could not be resolved: Could not find artifact org.apache.logging.log4j:log4j-core:jar:2.13.0

I meet the same problem, and finally solved by maven-shade-plugin config. In your case, you want to exclude log4j-core, your filter config must put outside of artifactSet as below.
find log4j-core class path prefix, for example org/slf4j/;
put this class path prefix in filter exclude rule, run cmd mvn package
use vim your-target.jar to check exclude success or not, you will find that org/slf4j has gone.
for more exclude info, pls see https://maven.apache.org/plugins/maven-shade-plugin/examples/includes-excludes.html
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>org/slf4j/**</exclude>
</excludes>
</filter>

Related

How do I add a file to the artifact (jar or war) created by maven?

I have an antrun task (goal run on phase prepare-package) set up that creates a file and saves it in /target/foo.bar. How do I add that to the artifact that gets created by maven (depending on module, it could be a jar or a war file)?
I have tried it with resources, with the builder-helper plugin, and the jar plugin - no luck:
<resources>
<resource>
<directory>target</directory>
<includes>
<include>**/foo.bar</include>
</includes>
</resource>
</resources>
That doesn't seem to do anything.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/foo.bar</file>
<type>bar</type>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
According to debug output, this seems to install something extra in the repo, but doesn't add foo.bar to the artefact.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<includes>
<include>../foo.bar</include>
</includes>
</configuration>
</plugin>
No observable effect, either. :(
(I assume this might work for the war file, but I'd prefer one way to do it for both artifact types, if possible - plus I really need this to work for the jars, too...)
Is there a way to do what I want to do?
(I'd prefer not saving my file in src/main/resources first; I thought the packaging processes would pick files up from the build directory after they were placed there anyway, but I suppose I misunderstood something...)
I had my file saved to project.build.directory. Changing that to project.build.outputDirectory means the jar plugin is picking it up, without the need of any other plugins. Unfortunately, that doesn't sort the war issue out... :(
I had a similar problem and stored the resulting artifact in
target/${project.name}-${project.version}/foo.war
To be more precise, I created the war from a directory using the ant target
<war warfile="target/${project.name}-${project.version}/foo.war" basedir="somedir" />
Then it was correctly added to the surrounding ear.

Maven dynamically exclude class with same name from different dependencies

There are two classes com.package.A, one coming from
<dependency>
<groupId>com.package</groupId>
<artifactId>art1</artifactId>
</dependency>
and one coming from
<dependency>
<groupId>com.package</groupId>
<artifactId>art2</artifactId>
</dependency>
Notice that the artifact ids are different.
For different Maven profiles, I want to exclude one version and just keep the other version. I am using the Shade Plugin.
With the maven-shade-plugin, it is possible to exclude certain class for specific dependencies. This is configured with the help of the filters property:
Archive Filters to be used. Allows you to specify an artifact in the form of a composite identifier as used by artifactSet and a set of include/exclude file patterns for filtering which contents of the archive are added to the shaded jar.
In your case, to exclude the class com.package.A from the dependency art2, you can have:
<filters>
<filter>
<artifact>com.package:art2</artifact>
<excludes>
<exclude>com/package/A.class</exclude>
</excludes>
</filter>
</filters>
To make this dynamic, i.e. select at build-time which com.package.A class you want to keep, you don't need to use a profile. You can use a Maven property that will hold the artifact id of the dependency to filter. In your properties, add
<properties>
<shade.exclude.artifactId>art2</shade.exclude.artifactId>
</properties>
The shade.exclude.artifactId property will hold the artifact id of the dependency to filter. By default, this configuration would select art2. Then, in the <filter> configuration of the Shade Plugin, you can use <artifact>com.package:${shade.exclude.artifactId}</artifact>.
Here's a full configuration of this in action:
<build>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<id>shade</id>
<goals>
<goal>shade</goal>
</goals>
<phase>package</phase>
<configuration>
<filters>
<filter>
<artifact>com.package:${shade.exclude.artifactId}</artifact>
<excludes>
<exclude>com/package/A.class</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<shade.exclude.artifactId>art2</shade.exclude.artifactId>
</properties>
Running mvn clean package will create an uber jar with the A.class from art1 since the one from art2 was excluded. And then, running mvn clean package -Dshade.exclude.artifactId=art1 will keep this time A.class from the dependency art2 since the one from art1 was excluded.

Maven checkstyle plugin - check goal cannot find configuration file

I have been unable to use the checkstyle check goal. I'm getting the following error:
Unable to find configuration file at location:
${project.parent.basedir}/.settings/my_checks.xml: Could not find
resource '${project.parent.basedir}/.settings/my_checks.xml'.
I get this error when I use the command mvn checkstyle:check, but if I run mvn checkstyle:checkstyle this configuration file is found and used as expected.
The plugin configuration is shown below.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.17</version>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
<phase>test</phase>
</execution>
</executions>
</plugin>
...
<properties>
<checkstyle.config.location>${project.parent.basedir}/.settings/my_checks.xml</checkstyle.config.location>
</properties>
Any suggestions? Why would the checkstyle goal work but not the check goal?
Edit: Upon further review I have learned that ${project.parent.basedir} does not resolve when running the check goal. It does resolve when calling the checkstyle goal. Still looking for suggestions / workarounds...
My workaround has been to move away from using the ${project.parent.basedir} variable and to use relative paths. This works in my case because all my modules are parallel directories.
<checkstyle.config.location>../parent/.settings/my_checks.xml</checkstyle.config.location>

Building a dependencies jar with Maven

Currently our maven build includes all the dependencies in the jar, using jar-with-dependencies.
We want to split this into two separate jars, one with the project application code and files, and one with the dependencies.
How is this done?
Thanks
This is done using the maven Assembly plugin
http://maven.apache.org/plugins/maven-assembly-plugin/
Use the maven-shade-plugin instead with following configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.1</version>
<configuration>
<finalName>${project.artifactId}-${project.version}-libs</finalName>
<artifactSet>
<excludes>
<exclude>${project.groupId}:${project.artifactId}</exclude>
</excludes>
</artifactSet>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
The trick is to define a specific final name. This avoids the replacement of the default jar, which is packaged by the maven-jar-plugin. The default name is ${project.artifactId}-${project.version}. So simply add a suffix like libs. Then exclude the artifact itself, because the classes should not be packaged twice.
The build will result in two jar files:
${project.artifactId}-${project.version}.jar, containing the classes and files of the project
${project.artifactId}-${project.version}-libs.jar, containing the content of all the dependencies

unable to generate maven plugin.xml descriptor

EDIT : Solved was missing the tag <packaging>maven-plugin</packaging> in my project pom. I misunderstood the sentence in this post, didn't know the meaning of leaving out ... :
thanks man, i figured it out already i left out <packaging>maven-plugin</packaging> in the pom file hope this helps others
I'm trying to build a maven plugin however I can't get the plugin.xml file to be generated.
I've tried command line and pom configuration for maven-plugin-plugin, with/without descriptor goal and phase. I guess I'm doing it right there.
Probably it is the rest that is not done correctly. The only related topics that I found is why is my maven plugin descriptor not being generated automatically? and it doesn't help much.
Here is the maven log
http://pastebin.com/uA2KFTXN
I have two mojos with Java4 anotations (#goal and #phase). I have the following tags in my Pom
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.1</version>
<configuration>
<goalPrefix>signature</goalPrefix>
</configuration>
<executions>
<execution>
<goals>
<goal>descriptor</goal>
</goals>
<phase>process-classes</phase>
</execution>
</executions>
</plugin>

Resources