Why does Maven2 check for updates of stax-ex at every build? - maven-2

Maven2 checks for updates of stax-ex at every build. And it's just checking this single dependency, all other dependencies are updated only once per day.
Maven2 output:
artifact org.jvnet.staxex:stax-ex: checking for updates from java.net
stax-ex (groupid: org.jvnet.staxex, version: 1.2) is included as part of jaxws-rt (groupid: com.sun.xml.ws, version: 2.1.3). We have an artifactory repository as intermediary.
What could I do? ( Building offline would be an unpopular work-around.)

I had the same problem, and wanted to get to the bottom of it!
The problem is in the pom.xml file of streambuffer (a dependency of jaxws-rt), which doesn't specify a version for stax-ex. Instead, it uses RELEASE, meaning the latest released version:
<dependency>
<groupId>org.jvnet.staxex</groupId>
<artifactId>stax-ex</artifactId>
<version>RELEASE</version>
</dependency>
This forces Maven to check constantly for the latest release of stax-ex (even if jaxws-rt itself requests version 1.2), by downloading its corresponding maven-metadata.xml.
An easy workaround is to force the version of stax-ex in a dependencyManagement section of your pom.xm:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jvnet.staxex</groupId>
<artifactId>stax-ex</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
</dependencyManagement>
And then Maven will stop bothering you about this warning...

It looks like you have remote repository declarations in your POMs that bypass your enterprise repository. If you are using Artifactory you can either have remote repository references in POMs automatically stripped off on a virtual repository level, or configure mirror-any in your settings to enforce artifact resolution go strictly through your Artifactory.

Related

Resolving depending war file with shrinkwrap maven resolver

I'm working on setup of arquillian testing. I want to deploy a WAR to JBoss using arquillian. This war is defined as a dependency in my pom.xml:
<dependency>
<groupId>my.project</groupId>
<artifactId>mywar</artifactId>
<version>1.0</version>
<type>war</type>
<scope>runtime</scope>
</dependency>
But when I try to resove this dependency using shrinkwrap, it throws a NoResolvedResultException:
PomEquippedResolveStage resolver = Maven.configureResolver().workOffline().loadPomFromFile("pom.xml");
File war = resolver.resolve("my.project:mywar:war").withoutTransitivity().asSingleFile();
It seems that somehow the resolver isn't able to deal with war files. I experminted with org.jboss.shrinkwrap.resolver.api.ResolveWithRangeSupportStage.resolveVersionRange(String) as well and it seems to interpret the ":war" in the coordinates as the version - which obviously won't work.
If I supply the version, it works:
Maven.resolver().resolve("my.project:mywar:war:1.0").withoutTransitivity().asSingleFile();
But I need to make it work without the version because this will change by the time and I don't want to adapt the version on each release.
Any ideas?
Since your artifact is not JAR, I think you have to add a question mark. Your resolver should look like: .resolve("my.project:mywar:war:?")

How to bundle JNLP API with Maven Project

I have a project where I need the JNLP API. I did not find an artifact for that on Maven Central, so I added an external Repository which offers that to my pom. That repository went offline this weekend. This is the second time something like this happened to me.
I know this is pretty much what Maven is not about, but really I just want that tiny jnlp-api-1.5.0.jar file to be
In my SCM (I don't want to roll my own Maven repository for just one dependency).
In the compile scope when the project builds.
Which knobs do I have to turn to accomplish this?
As of JDK 7.0, the JNLP API is being provided by the javaws.jar file in your JRE's lib directory, i.e., ${java.home}/lib/javaws.jar. It is possible to use the maven dependency scope system.
<project>
...
<dependencies>
<dependency>
<groupId>javax.jnlp</groupId>
<artifactId>jnlp-api</artifactId>
<version>7.0</version>
<scope>system</scope>
<systemPath>${java.home}/lib/javaws.jar</systemPath>
</dependency>
</dependencies>
...
</project>
You can put the JAR in your local repository using the install-file goal of the maven-install-plugin and reference it as you normally would in your POM. The command would be:
mvn install:install-file -Dfile=/path/to/jnlp-api-1.5.0.jar -DgroupId=<group-id> -DartifactId=<artifact-id> -Dversion=1.5.0 -Dpackaging=<packaging>
Place this command in a script and check it into your SCM. That way, you (and anyone else working on this project) can install it easily to the local repo.

Using Maven, how can I assemble several modules into one artifact?

We have a mother-ship project with several modules:
foo
+ foo-core
+ foo-resource
+ foo-util
+ foo-whatever
I want to allow developers to include the core, resource, and util modules as dependencies (excluding the -whatever module). I know that I can specify that they include each dependency, but it would be nice to allow for them to just specify something like
<artifactId>foo-sdk</artifactId>
And get everything that they need to develop a foo. This has the added advantage that it gives us the power to add (or remove) what goes into the sdk.
It would be best if foo-sdk was not just a jar with the other jars jammed in it. I'd rather it be a pom that simply points to the other artifacts.
I feel like I've seen this done before but can't find instructions to do it. I checked out Maven Assembly Plugin but it doesn't look like this is its intended use.
You can group dependencies in a project with a packaging of type pom. From the Maven book:
3.6.1. Grouping Dependencies
If you have a set of dependencies
which are logically grouped together.
You can create a project with pom
packaging that groups dependencies
together. For example, let's assume
that your application uses Hibernate,
a popular Object-Relational mapping
framework. Every project which uses
Hibernate might also have a dependency
on the Spring Framework and a MySQL
JDBC driver. Instead of having to
include these dependencies in every
project that uses Hibernate, Spring,
and MySQL you could create a special
POM that does nothing more than
declare a set of common dependencies.
You could create a project called
persistence-deps (short for
Persistence Dependencies), and have
every project that needs to do
persistence depend on this convenience
project:
Example 3.11. Consolidating Dependencies in a Single POM Project
<project>
<groupId>org.sonatype.mavenbook</groupId>
<artifactId>persistence-deps</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>${hibernateVersion}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>${hibernateAnnotationsVersion}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-hibernate3</artifactId>
<version>${springVersion}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysqlVersion}</version>
</dependency>
</dependencies>
<properties>
<mysqlVersion>(5.1,)</mysqlVersion>
<springVersion>(2.0.6,)</springVersion>
<hibernateVersion>3.2.5.ga</hibernateVersion>
<hibernateAnnotationsVersion>3.3.0.ga</hibernateAnnotationsVersion>
</properties>
</project>
If you create this project in a
directory named persistence-deps, all
you need to do is create this
pom.xml and run mvn install. Since
the packaging type is pom, this POM
is installed in your local repository.
You can now add this project as a
dependency and all of its dependencies
will be added as transitive
dependencies to your project. When you
declare a dependency on this
persistence-deps project, don't
forget to specify the dependency type
as pom.
Example 3.12. Declaring a Dependency on a POM
<project>
<description>This is a project requiring JDBC</description>
...
<dependencies>
...
<dependency>
<groupId>org.sonatype.mavenbook</groupId>
<artifactId>persistence-deps</artifactId>
<version>1.0</version>
<type>pom</type>
</dependency>
</dependencies>
</project>
If you later decide to switch to a
different JDBC driver (for example,
JTDS), just replace the dependencies
in the persistence-deps project to use
net.sourceforge.jtds:jtds instead of
mysql:mysql-java-connector and update
the version number. All projects
depending on persistence-deps will use
JTDS if they decide to update to the
newer version. Consolidating related
dependencies is a good way to cut down
on the length of pom.xml files that
start having to depend on a large
number of dependencies. If you need to
share a large number of dependencies
between projects, you could also just
establish parent-child relationships
between projects and refactor all
common dependencies to the parent
project, but the disadvantage of the
parent-child approach is that a
project can have only one parent.
Sometimes it makes more sense to group
similar dependencies together and
reference a pom dependency. This way,
your project can reference as many of
these consolidated dependency POMs as
it needs. Note
Maven uses the depth of a dependency
in the tree when resolving conflicts
using a nearest-wins approach. Using
the dependency grouping technique
above pushes those dependencies one
level down in the tree. Keep this in
mind when choosing between grouping in
a pom or using dependencyManagement
in a parent POM
Wouldn't this just be another sub-module foo-sdk with packaging pom and dependencies on foo-{core,resource,util}?

Activate profile in depended-on POM?

My company writes companion products for project management software that uses that software's Java API. They release new API versions with new releases of their products, and also point releases for bug fixes etc. We need to support clients using various versions of their software (and by extension, their API). In order to do this without unnecessary code duplication, we have defined profiles in our products that include the necessary dependencies for each API version.
I have a war project built using this technique with the "api70" profile activated, and another project that depends on that war project with a type of pom, in order to pull in the war's dependencies. The problem is that when building this second project, the profile-specific dependencies are not being included, even though I'm defining -Papi70 on the maven command line when building the depending project.
Is there any way to get this to work?
In the war project:
<!-- API 7.0 profile. -->
<profile>
<id>api70</id>
<dependencies>
<dependency>
<groupId>com.bigcompany</groupId>
<artifactId>integrationlibrary</artifactId>
<version>7.0-a</version>
</dependency>
</dependencies>
<properties>
<apiversion>api70</apiversion>
</properties>
</profile>
In the depending project:
<!-- Depend on war as type=pom for dependency mediation. -->
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>warproject</artifactId>
<version>${warVersion}</version>
<type>pom</type>
</dependency>
Command line used for building depending project:
mvn -P api70 clean package
The resulting build does not include integrationlibrary or any of its transitive dependencies.
I think that your problem doesn't apply to profiles at all. It's about how transitive dependencies work for war packaging. By design they doesn't work :) War archive contain its dependencies in WEB-INF/lib folder or if it is packaged in ear it can share libraries with ear libs. More of the problem you can read on this wiki article. It's about Skinny Wars but topic relates also your problem.
For you interesting is also this JIRA issue.
Quick but not elegant solution is to change packaging form war to pom (or create duplicate pom with pom packaging).
Why don't you create an api70-deps pom project and let your war and dependant project both pull that in, profile activated or otherwise?
This approach works wonders for me... my poms become so much more tidier.

Maven classpath order issues

Does anyone know of a way to set a specific classpath order in Maven2, rather than the random ordering I appear to experience at the moment?
There are a number of legitimate reasons for wanting to do this:
A vendor has supplied a patch jar, which contains overriding classes for a previously released jar and therefore the patch jar must appear first in the classpath ordering.
Two jar's found on the classpath discovered by traversing pom dependencies contain the same class in the same package with different signitures. For example:
jboss
jbossall-client
4.2.0.GA
org.hibernate
hibernate
3.1
both contain:
org.hibernate.util.ReflectHelper.class, but the jbossall-client version is missing the getFastClass method.
From googling I see that this is perhaps a point of contention between maven enthusiasts and people facing this particular issue, but surely there are legitimate reasons for classpath ordering.
Any advice from anyone that has solved this particular quandary would be much appreciated!
Thanks
As of version 2.0.9 maven uses pom order for classpath, so you can actually manipulate it now. We mostly supress transitive dependencies to external libraries that we also include directly.
From the release notes of maven 2.0.9:
MNG-1412 / MNG-3111 introduced deterministic ordering of dependencies on the classpath. In the past, natural set ordering was used and this lead to odd results. The ordering is now preserved from your pom, with dependencies added by inheritence added last. In builds that had conflicting or duplicate dependencies, this may introduce a change to the output. In short, if you have weird issues with 2.0.9, take a look at the dependencies to see if you have conflicts somewhere.
Maven 2.0.9 adds correct ordering so you absolutely must have that version or higher for the below to work.
Secondly you need the an updated plugin. The Maven guys are working on a fix, its in their jira to fix but this is something I urgently needed. So in the meantime I have fixed this myself and you can pull the Modified plugin source code from github.
Edit: Refer to http://jira.codehaus.org/browse/MECLIPSE-388
There are two ways to install it, either pull my modified code and install it or download the prebuilt jar and just add it.
Building the plugin
Run maven install from the plugin directory you checked out and then add the following in your plugins section of your projects pom:
<build>
</plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.8-cpfix</version>
</plugin>
</plugins>
</build>
Download the jar
Alternatively if you don't want to download and compile yourself then you can just get hold of the jar file and install it yourself.
Once you have the file run
mvn install:install-file -Dfile=<path-to-file> -DgroupId=org.apache.maven.plugins \
-DartifactId=maven-eclipse-plugin -Dversion=2.8-cpfix -Dpackaging=jar
Regardless of how you installed it now when you run mvn eclipse:eclipse it will pick up the modified code and order the dependencies based on the order you defined in your pom file, no alphabetical ordering. It will also put the JRE container at the top of the dependencies.
Hopefully the real version of this code will come out soon, but in the meantime this fix has worked for me on my project and I hope it can help some others as well.
Rather a further qualification of the question than an answer:
under "Maven Dependencies" Eclipse does not seem to honour the POM-order.
(it does use the POM-order under "Java Build Path" & in the Classpath)
Is that the expected behaviour?
I'm using Eclipse 2021-09 (which has Maven 3.8.1 embedded) under Windows 10.
Here's the POM:
<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.group</groupId>
<artifactId>arty.fact</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Maven Dependency Order</name>
<properties>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>17</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>wsdl4j</groupId>
<artifactId>wsdl4j</artifactId>
<version>1.6.3</version>
<exclusions><exclusion><groupId>*</groupId><artifactId>*</artifactId></exclusion></exclusions>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.14.1</version>
<exclusions><exclusion><groupId>*</groupId><artifactId>*</artifactId></exclusion></exclusions>
</dependency>
</dependencies>
</project>
The Maven Dependencies looks like this:
If you have problem starting with IntelliJ IDEA, you can change the dependencies order from project structrue.