Can't get the maven-war-plugin to exclude jaxb jars - java

I'm trying to use the <packagingExcludes> of the Maven war-plugin.
This is my configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.2</version>
<configuration>
<archive>
<manifestEntries>
<Implementation-Version>${project.artifactId}-${project.version}-r${buildNumber}</Implementation-Version>
<Implementation-Buildtime>${timestamp}</Implementation-Buildtime>
</manifestEntries>
</archive>
<packagingExcludes>WEB-INF/lib/jaxb*.jar</packagingExcludes>
</configuration>
</plugin>
In my understanding this line:
<packagingExcludes>WEB-INF/lib/jaxb*.jar</packagingExcludes>
Should exclude all jars starting with 'jaxb' from the built .war file.
However after I run clean install I get both:
jaxb-api-2.1.jar
jaxb-impl-2.1.3.jar
Packaged in my .war WEB-INF/lib dir.
I'm using Maven 3.
Any help greatly appreciated.
Thanks in advance,
To answer gkamal's comment.
When I run mvn war:war -X I can see:
[DEBUG] Processing: jaxb-api-2.1.jar
[DEBUG] + WEB-INF/lib/jaxb-api-2.1.jar has been copied.
[DEBUG] Processing: jaxb-impl-2.1.3.jar
[DEBUG] + WEB-INF/lib/jaxb-impl-2.1.3.jar has been copied.
Also
[DEBUG] Excluding [WEB-INF/lib/jaxb*.jar] from the generated webapp archive.
No, exceptions, warning or errors or nothing that looks suspicious, anything specific I should look for ?

For a transitive dependency, you can use the exclusions element to exclude it.
<dependency>
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<exclusions>
<exclusion>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api-2.1</artifactId>
</exclusion>
</exclusions>
</dependency>
As gkamal commented, you could also add an explicit dependency on jaxb and set its scope to provided, this will override the scope of the transitive dependency so it is no longer packaged.
Another alternative, the war plugin also allows to exclude based on regular expressions, but the syntax is a bit more involved, the following snippet should exclude everything under lib whose filename starts with "jaxb":
<packagingExcludes>%regex[WEB-INF/lib/jaxb.*]</packagingExcludes>

This means you have them as dependency in your project so they will be packaged into the war. Just remove the dependencies so they wont be packaged anymore.
Based on the documentation of the option you used you have to use regex which means you should write:
<packagingExcludes>WEB-INF/lib/jaxb.*</packagingExcludes>
instead of
<packagingExcludes>WEB-INF/lib/jaxb*.jar</packagingExcludes>

Further to #gkamal's comment to your question (08/05/12#11:52), check your maven-war-plugin's version. I've just spent 2hrs looking at this issue myself to exclude an unknown transient to javaee-api*.jar.
With maven 3.0.4, I was defaulted to maven-war-plugin version 2.1 (you can tell if you run your build in debug - e.g. mvn clean package -X). One of your other comments is correct in saying package-excludes came in after this. See the war plugin page for details (although the actual page describing the entry doesn't indicate version info which is pretty poor as that's what you first search for).
If you update to maven-war-plugin to 2.3 (add <version>2.3</version>, your packaging-excludes should be used. Note though you will only see this in the built war's WEB-INF/lib, not in the transient war directory (which includes the excluded jars even if debug says they're to be excluded, which is very confusing when looking at this issue).
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
...
<packagingExcludes>
WEB-INF/lib/whatever-*.jar,
WEB-INF/lib/javaee-api-*.jar
</packagingExcludes>
...
</plugin>
...
However, in terms of best practice, this is probably a last gasp effort to exclude jars fromo the war and the dependency-level exclusions for transient jars is probably the most precise and correct way. That said, what if a transient jar is being brought in by multiple dependencies?
So, with the version upgrade, I think #khmarbaise's solution is fine (and the comment indicating it won't work is wrong). However, I think best practice is to use dependency-level exclusions as per your accepted answer.

You can do this by specifying inside <packagingExcludes></packagingExcludes> inside </configuration><configuration>.
<project>
...
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<packagingExcludes>
WEB-INF/lib/ex1-*.jar,
WEB-INF/lib/ex2-logging-*.jar
</packagingExcludes>
</configuration>
</plugin>
</plugins>
</build>
...
</project>
You can specify path by wild cards and regular expressions too. See this link for more info.

Related

Run mvn install command skipping selected jar

What I need to do is to build a jar without one huuuge dependency, which is a fellow below
<dependency>
<groupId>com.groupdocs</groupId>
<artifactId>groupdocs-conversion</artifactId>
<version>21.1</version>
</dependency>
The system scope is one of solutions, but not in this case. None of my teammates would be happy to download a jar dependency manually.
Building a project including mentioned dependency creates a jar of 515 MBs or 251 MBs without it (system scope).
Thanks tgdavies for a hint with plugin. The thing that helped me was adding excludeGroupIds like below:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>SECRET</mainClass>
<excludeGroupIds>com.groupdocs</excludeGroupIds>
</configuration>
</plugin>

Excluding certain .jars from a Maven dependency from build by classifier

My project includes the nd4j-native-platform dependency, which includes .jars for windows, linux, and mac. The app is developed on windows/mac machines then deployed to Linux, so I'd like to save space on deployment by excluding these other platform jars that take up > 400 MB when the .war is built. Tl;dr, I want to exclude all the .jars that don't end with linux-x86_64.
Dependency in pom:
<dependency>
<groupId>org.nd4j</groupId>
<artifactId>nd4j-native-platform</artifactId>
<version>1.0.0-beta7</version>
<classifier>linux-x86_64</classifier>
</dependency>
I don't see any way to exclude them by classifier in the dependency tag, it seems you can only exclude by groupId and artifactId. I also tried using packagingExcludes and warSourceExcludes in the .war plugin, but that didn't do anything:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.3</version>
<configuration>
<packagingExcludes>
WEB-INF/lib/nd4j-native-1.0.0-beta7-windows-x86_64.jar,
WEB-INF/lib/nd4j-native-1.0.0-beta7-android-x86.jar,
WEB-INF/lib/nd4j-native-1.0.0-beta7-macosx-x86_64.jar,
WEB-INF/lib/nd4j-native-1.0.0-beta7-android-x86_64.jar,
WEB-INF/lib/nd4j-native-1.0.0-beta7-linux-ppc64le.jar,
WEB-INF/lib/nd4j-native-1.0.0-beta7-android-arm64.jar,
WEB-INF/lib/nd4j-native-1.0.0-beta7-android-arm.jar,
WEB-INF/lib/openblas-0.3.9-1-1.5.3-windows-x86_64.jar,
WEB-INF/lib/nd4j-native-1.0.0-beta7-linux-armhf.jar,
WEB-INF/lib/openblas-0.3.9-1-1.5.3-windows-x86.jar,
WEB-INF/lib/openblas-0.3.9-1-1.5.3-windows-x86.jar,
WEB-INF/lib/openblas-0.3.9-1-1.5.3-linux-armhf.jar,
WEB-INF/lib/openblas-0.3.9-1-1.5.3-linux-ppc64le.jar,
WEB-INF/lib/openblas-0.3.9-1-1.5.3-linux-arm64.jar
</packagingExcludes>
</configuration>
</plugin>
Using Maven 3.6.3.
The correct way to deal with this for most things that use JavaCPP is to set the javacpp.platform property.
When building with mvn -Djavacpp.platform=linux-x86_64 you will get only that specific platform and nothing else. This will also apply to all other transitive dependencies, e.g. opencv.
You can try running mvn -Djavacpp.platform=linux-x86_64 dependency:tree to see that it works.

Maven project doesn't recognize any classes from included sibling dependency [duplicate]

I am writing a project for acceptance testing and for various reasons this is dependent on another project which is packaged as a WAR. I have managed to unpack the WAR using the maven-dependency-plugin, but I cannot get my project to include the unpacked WEB-INF/lib/*.jar and WEB-INF/classes/* to be included on the classpath so the build fails. Is there a way to include these files into the classpath, or is there a better way of depending on a WAR?
Many thanks.
There's another option since maven-war-plugin 2.1-alpha-2. In your WAR project:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<attachClasses>true</attachClasses>
</configuration>
</plugin>
This creates a classes artifact which you can use in the acceptance tests project with:
<dependency>
<groupId>your-group-id</groupId>
<artifactId>your-artifact-id</artifactId>
<version>your-version</version>
<classifier>classes</classifier>
</dependency>
Indeed, by design, Maven doesn't resolve transitive dependencies of a war declared as dependency of a project. There is actually an issue about that, MNG-1991, but it won't be solved in Maven 2.x and I'm not sure that I don't know if overlays allow to workaround this issue. My understanding of the suggested solution is to duplicate the dependencies, for example in a project of type pom.
(EDIT: After some more digging, I found something interesting in this thread that I'm quoting below:
I have been helping out with the development of the AppFuse project over
the last month where we make heavy use of the war overlay feature in the
Maven war plugin. It is a really nifty feature!
To get max power with war overlays I have developed the Warpath plugin
that allows projects to use war artifacts as fully fledged dependencies.
In brief:
1) The contents of the /WEB-INF/classes directory in the war dependency
artifacts can be included in the project's classpath for normal compile,
etc tasks.
2) Transitive dependencies from the war dependency artifacts become
available for use by other plugins, e.g. compile and ear - so no more
having to include all the dependencies when creating skinny wars!
The plugin has now been actively used in the AppFuse project for the
last few months, and I feel it is at a point where it is both usable and
stable.
Would the war plugin team be interested in including the warpath
functionality inside the war plugin? It would seem to be the most
natural place to host it.
So, I don't have any experience with it, but the maven warpath plugin actually looks nice and simple and is available in the central repo. To use it,include the following plugin configuration element in your pom.xml file:
[...]
<build>
<plugins>
<plugin>
<groupId>org.appfuse</groupId>
<artifactId>maven-warpath-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>add-classes</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
And add the war dependencies you want included in the classpath as warpath type dependencies:
[...]
<dependencies>
<dependency>
<groupId>org.appfuse</groupId>
<artifactId>appfuse-web</artifactId>
<version>2.0</version>
<type>war</type>
</dependency>
<dependency>
<groupId>org.appfuse</groupId>
<artifactId>appfuse-web</artifactId>
<version>2.0</version>
<type>warpath</type>
</dependency>
</dependencies>
[...]
Both the war and warpath dependency types are needed: the war type is used by the Maven war plugin to do the war overlay, the warpath type is used by the Warpath plugin to determine the correct list of artifacts for inclusion in the project classpath.
I'd give it a try.)
Use overlays. First, your test project need to have also packaging war.
Declare dependency of war project you want to test:
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>your-project-arftifactId</artifactId>
<version>${project.version}</version>
<type>war</type>
<scope>test</scope>
</dependency>
then configure maven-war-plugin overlay:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webResources>
<resource>
<directory>${basedir}/src/main/webresources</directory>
<filtering>true</filtering>
</resource>
</webResources>
<overlays>
<overlay/>
<overlay>
<groupId>your.group</groupId>
<artifactId>your-project-artifactId</artifactId>
</overlay>
</overlays>
</configuration>
</plugin>
In the above example in test project I overwrite webresources configuration files (like conxtext etc.).
EDIT: This solution wasn't tested with Maven 3.
Good point, Justin. That got me actually solving my problem, namely: including a war into an assembly AND including all its transitive dependencies.
I could not duplicate the war-dependency as 'jar' as you suggested since the assembly plugin would not find a jar referenced by that groupId/artefactId, but
duplicating the war-dependency as type pom
works!
The war and its transitive dependencies are not included in the assembly.
To exclude the (now also appearing) pom file I had to add an exclude element like this:
<excludes>
<exclude>*:pom</exclude>
</excludes>
into my assembly.xml file.
I think this could also be a workaround for the original question of this thread.
If you list the dependency on the war project as a jar dependency it seems to pickup the required jars/resources. I'm using Maven 2.2 + m2eclipse.

maven-rar-plugin includes all Dependencies with configuration set to false

I am using maven-rar-plugin and following is my configuration in POM file. includeDependencies is set to false. But all the dependent and dependent project's sub dependencies are all packaged into rar.
<plugin>
<artifactId>maven-rar-plugin</artifactId>
<version>2.4</version>
<configuration>
<raXmlFile>src/main/resources/META-INF/ra.xml</raXmlFile>
<includeDependencies>false</includeDependencies>
<archive>
<addMavenDescriptor>true</addMavenDescriptor>
</archive>
</configuration>
</plugin>
I cannot use exclusion in dependencies as it would lead to compilatin errors.
<dependencies>
<dependency>
<groupId>com.fi.ps</groupId>
<artifactId>frm-fl</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
Is this a bug in the Maven plugin or is there a different way of configuring for rar packaging?
There is no includeDependencies parameter for the maven-rar-plugin and, from reading the source code, it isn't currently possible to exclude dependencies of the project. A possible work-around would be to declare the dependencies to exclude with the provided scope: they will be present during compilation but excluded when building the RAR file.
But why do you want to exclude dependencies in the first place? The maven-rar-plugin is used to build a Resource Adapter Archive file for the Java 2 Connector Architecture. Dependencies are supposed to be included, otherwise it won't work. Beware that, as stated in the FAQ, this plugin does not create compressed file like WinRar.

default maven compiler setting

Right now, I'm writing a small java application by my own, with few maven pom.xml files. I want to make all my maven packages to compile with jdk 1.6, and I can't find a good way to do it without manually setting it on every single POMs - I'm sick of copy-and-pasting
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
in every single pom.xml file I generate.
Is there a simpler way to resolve this issue?
Create a pom-only (<packaging>pom</packaging>) project that has the compiler settings (and any other default settings) you want. You give treat it like any other project (release it; deploy it to your Maven repo, etc.).
Put a parent declaration at the top of your pom files:
<parent>
<groupId><!-- parent's group id --></groupId>
<artifactId><!-- parent's artifact id --></artifactId>
<version><!-- parent's version --></version>
</parent>
It doesn't help much if all you want to set is compiler settings. But if you find yourself configuring lots of plugins, reports and dependencies in the same way across project, you can create one parent to rule them all.
BTW - be careful about declaring dependencies and plugins in your parent pom file. Usually you'll want to favor dependencyManagement and pluginManagement. See the documentation for more details.
You could specify this plugin and configuration in your ~/.m2/settings.xml, which will then apply it to all projects.
However this has the downside of making your projects no longer portable - attempting to build the same code with the same pom.xml will fail on other machines that don't have the same settings.xml values as you.
I'm sick of copy-and-pasting
Yes, and you should use POM inheritance to avoid this and configure the maven-compiler-plugin in the parent POM.
Another option would be to use the solution suggested by #matt (and he nailed down pros and cons of the use of settings.xml).
In both cases, this is typically a setting that I like to check using the maven-enforcer-plugin and its requireJavaVersion rule that you would configure like this:
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<executions>
<execution>
<id>enforce-versions</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireJavaVersion>
<version>1.6</version>
</requireJavaVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
But it can do more (like checking the maven version). Very useful.
I want to make all my maven packages to compile with jdk 1.6
If this is multi-module project just put these settings to top-level POM under pluginManagement.
If you have many independent project just copy-and-paste this configuration. Beware of "smart" solutions like setting this somewhere globally. Some day you will want to use different compiler settings for one or two of your projects and the nightmare will begin :-)
Remember...
Keep things as simple as possible, but no simpler.

Categories