4

When running mvn versions:display-dependency-updates for the Version Maven Plugin I see lots of things like this:

[INFO]   org.slf4j:slf4j-api ........................... 1.7.36 -> 2.0.0-alpha7

But just because I'm not using the alpha version of a later version doesn't mean I'm not using the latest available release version. Another Stack Overflow answer indicated that I can set up a rules.xml file to ignore versions like *.-alpha*, putting something like this in my POM:

<configuration>
  <rulesUri>file:///${project.basedir}/rules.xml</rulesUri>
</configuration>

My question: is this rules.xml file inheritable? If I put it in a separate project in a parent POM of <packaging>pom</packaging>, published to Maven Central, will the child POMs pick it up? Or will the child projects look for a rules.xml file in the child project directory?

I want to configure the versions-maven-plugin in the parent POM (as I do already) and run mvn versions:display-dependency-updates on any child POM or descendant POM. How can I set up the ignore rules in the parent POM so that these version ignore rules will be picked up when I check for dependency updates in a child POM? (Is there no way to include the rule within the POM itself?)

Garret Wilson
  • 18,219
  • 30
  • 144
  • 272

3 Answers3

2

Or will the child projects look for a rules.xml file in the child project directory?

Yes, if you define the rules.xml file via ${project.basedir} it will resolve to the current local base directory of the child project. I've verified this with a simple parent-child pom setup. So that will not work, unless you duplicate the rules file in every project.

If you wish to include the plugin configuration and ruleset in the parent pom without duplicating the rules file, you have two options:

If you have your ruleset xml file hosted at, for example, http://www.mycompany.com/maven-version-rules.xml then the following configuration in your corporate pom would ensure that all projects use this rule set.

<configuration>
    <rulesUri>http://www.mycompany.com/maven-version-rules.xml</rulesUri>
</configuration>

or

You can provide your ruleset xml file also within a jar, if you want to distribute your ruleset xml as Maven artifact. Therefore you have to declare the containing jar as direct dependency of the versions-maven-plugin and to use classpath as protocol.

<configuration>
  <rulesUri>classpath:///package/foo/bar/rules.xml</rulesUri>
</configuration>
<dependencies>
    <dependency>
        <groupId>com.mycompany</groupId>
        <artifactId>version-rules</artifactId>
        <version>1.0</version>
    </dependency>
</dependencies>

Source:

The configuration in the pom only has rudimentary includes and excludes filters. Those will allow you to exclude any dependency as a whole, but not specific update versions. As far as i can tell from the available documentation there is no way to define version rules in any other way.

See

Update 09-2022

In the github ticket we found in the comments we can see the following update:

It looks like a feature like this has recently been implemented by #369. Please see #318 where it's possible to provide inclusion and exclusion filters for determining which dependency patterns will be considered. Thanks to that, you can rule out patterns such as .*-beta. or .*_ALPHA, albeit not using regexp, but simple asterisk wildcards.

This will land in today's release (2.12.0).

This will add the following features:

Version 2.12.0 will introduce new arguments: dependencyIncluded, dependencyExcludes, dependencyManagementIncludes, dependencyManagementExcludes.

With the following example configuration in pom.xml given:

<profile>
  <id>display-dependency-updates</id>
  <build>
    <plugins>
      <plugin>
        <groupId>${project.groupId}</groupId>
        <artifactId>${project.artifactId}</artifactId>
        <version>${project.version}</version>
        <executions>
          <execution>
            <phase>validate</phase>
            <goals>
              <goal>display-dependency-updates</goal>
            </goals>
            <configuration>
              <dependencyIncludes>org.apache.maven.*:doxia*</dependencyIncludes>
              <dependencyManagementIncludes>com.puppy*:*</dependencyManagementIncludes>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</profile>

This will also be implemented for filtering plugin and pluginManagement, but that will probably be added in a later release:

So, I've just added the missing plugin- and plugin management filtering which works likewise. I really doubt it will land into today's release though.

slindenau
  • 1,091
  • 2
  • 11
  • 18
  • "You can provide your ruleset xml file also within a jar …" **Follow-up Question 1:** But can this be in the same JAR as the parent POM? Or do I have to create yet another project with `jar` packaging instead of `pom` packaging to distribute the rules? **Follow-up Question 2:** And then wouldn't the rules XML suddenly be distributed with every child project, even though it's only needed at build time (and not even that — it's only need when I check the dependency versions)? Or can I somehow set the scope so it's not included in the build? – Garret Wilson May 29 '22 at 13:29
  • @GarretWilson can you elaborate on your parent-child structure? You’re talking about the parent jar, but distributing a project packaged as pom results only in a pom file, not a jar. If your child projects and parent are always checked out together (multi module pom?) you can perhaps use a relative path. If you get the parent from maven, you will indeed need to include the xml in a jar file. If you dont want to distribute this xml file with your final project build, then it needs to be a separate jar. Plugins and their dependencies are not included in the project build. – slindenau May 29 '22 at 14:01
  • " You’re talking about the parent jar, but distributing a project packaged as pom results only in a pom file, not a jar." You're correct. The parent POM in question is e.g. `com.globalmentor:globalmentor-root:0.8.9`, and I just confirmed it is distributed as a POM; I was mistaken in thinking it was distributed in a JAR. So I will have to create a completely separate project to get the XML file in a JAR. It's good that plugin dependencies are not included in the project build, but seriously, what an outrageous amount of work for something that should have been in the POM plugin configuration. – Garret Wilson May 29 '22 at 14:18
  • @GarretWilson i see you’re not happy with the result. If this was a standard multi module [this](https://stackoverflow.com/questions/26120704/maven-versions-plugin-reference-a-rule-xml-from-a-maven-dependency) would be an option. Considering the rules xml was almost [removed](https://github.com/mojohaus/versions-maven-plugin/issues/157), it seems to be a low priority point. You could try to show your support [here](https://github.com/mojohaus/versions-maven-plugin/issues/258). If there is a hack around this, i’d be interested to see it in action as well. – slindenau Jun 06 '22 at 16:00
  • Hosting it at some internal URL is also not an option for you? – slindenau Jun 06 '22 at 16:04
  • Hosting at an internal URL is not an option. This is a public parent POM that all our projects use not just internally, but possibly third-party public open-source projects as well. Why should I need to host a build configuration? If I want to check that the project has the latest versions, why should I be distracted that version 99.9-alpha-4 is available, if it's not _really_ a newer version that is released? Most plugins simply allow configuration in the POM. Why should this one be any different? Why must I jump through all these extra hoops just to configure a plugin? – Garret Wilson Jun 07 '22 at 02:15
  • 1
    An alpha version **is** a new version. "New version" in this context means any non-snapshot version. I understand you do not want an alpha, but this answer shows you workarounds. I think the extra JAR is OK, just you also distribute your parent POM and maybe a BoM as separate artifacts. BTW, some projects like Maven Surefire distribute stable versions as milestones, but for some reason some uninformed people are afraid to use them, waiting for years for the next final major. It might be unfortunate naming, but you really need to check on a per-project basis, so the rules file is a good idea. – kriegaex Jun 11 '22 at 07:44
  • "An alpha version **is** a new version." But I want to restrict the check to new _release_ versions. See https://stackoverflow.com/a/53856626 . "I think the extra JAR is OK." And I don't think it is OK. Imagine if every plugin required an extra JAR for its settings. "[Y]ou really need to check on a per-project basis …" That is completely your opinion. I vehemently disagree. It's OK that we disagree, but that's exactly what configurations are for --- to allow me to configure the behavior to my opinions, not yours. I want all our dozens of projects to be consistent without requiring another JAR. – Garret Wilson Jun 12 '22 at 23:56
  • slindenau, the bounty is about to expire and I haven't received a better answer (unfortunately probably because no better answer exists at the moment). I'll assign the bounty to you as appreciation for your time in providing at one workaround, even though it is far from ideal. – Garret Wilson Jun 12 '22 at 23:58
  • @GarretWilson thanks. I see the ticket on github was assigned the `enhancement` label, so eventually the feature might make it into a next release. – slindenau Jun 13 '22 at 07:10
1

Pasting my answer here from Github, because I think it might benefit others.

Provided you have a directory called rules-test in your project containing the rules template file:

<ruleset comparisonMethod="maven"
         xmlns="http://mojo.codehaus.org/versions-maven-plugin/rule/2.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://mojo.codehaus.org/versions-maven-plugin/rule/2.0.0
         https://www.mojohaus.org/versions-maven-plugin/xsd/rule-2.0.0.xsd">
    <ignoreVersions>
        <ignoreVersion type="regex">${ignoredVersions}</ignoreVersion>
    </ignoreVersions>
</ruleset>

Then, in your main project, create the following profile:

<profile>
  <id>rules-test</id>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-resources-plugin</artifactId>
        <version>3.3.0</version>
        <executions>
          <execution>
            <phase>validate</phase>
            <goals>
              <goal>copy-resources</goal>
            </goals>
            <configuration>
              <resources>
                <resource>
                  <directory>rules-test</directory>
                  <filtering>true</filtering>
                </resource>
              </resources>
              <outputDirectory>${project.basedir}</outputDirectory>
            </configuration>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>versions-maven-plugin</artifactId>
        <version>2.12.0</version>
        <executions>
          <execution>
            <phase>validate</phase>
            <goals>
              <goal>display-dependency-updates</goal>
            </goals>
            <configuration>
              <rulesUri>file://${project.basedir}/compiled-rules.xml</rulesUri>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</profile>

If you then execute the following Maven target:

mvn -P rules-test "-DignoredVersions=.*-(M\d*|.*-SNAPSHOT)" clean validate

then you will get a dependencies report using the filter in the -DignoredVersions argument (filtering out both *-M* and *-SNAPSHOT).

And if you put your ignoredVerions property in your project instead of passing it as a -D argument, then it will be inheritable!

1

Happy this is now available natively in the plugin; see Issue #684. I recommended using at least v2.16.0 because of Issue #959.

Garret Wilson
  • 18,219
  • 30
  • 144
  • 272