4

I have a Maven multi-module project in Eclipse.

Each time I want to update the version, I go to Run As -> Run Configurations..., change the parameter newVersion of the goal versions:set to a higher number and then run the goal.

Is there something more direct?

Note that I cannot use the CI-friendly versions because they clash with the Maven release plugin.

J Fabian Meier
  • 33,516
  • 10
  • 64
  • 142

3 Answers3

2

Following the idea of https://stackoverflow.com/a/34091470/927493,

I configured the newVersion parameter to be ${string_prompt:newVersion} as shown in the image below

Eclipse Maven Run Dialogue

Then I get prompted for the version number which works fine.

J Fabian Meier
  • 33,516
  • 10
  • 64
  • 142
2

Based on the answer from JF Meijer, here's a Launch Configuration explanation for M2E, which I suspect you already have installed, which does exactly what you're asking.

Launch Create Dialog

  1. Open "Run Configurations..."
  2. Select "Maven Build"
  3. Click "New Launch Configuration" (in the top left)
  4. Give it a name (Like "Set Version")
  5. Click "Workspace..." And select the parent pom project
  6. Enter "versions:set" under Goals
  7. scroll down (can be hidden)
  8. Under "Parameters" select Add... on the right
  9. Add a Parameter with
    • Name = newVersion
    • Value = ${string_prompt:"New Version":0.0.1-SNAPSHOT}

so, to expand on what JP Meijer already pointed out, the variable string_prompt, as shown under step 9, supports a distinct name, like "New Version", and a default value, in this case 0.0.1-SNAPSHOT.

Now, Apply, Save, and Run!

Randy Wallace
  • 131
  • 1
  • 5
1

Here is a script that checks if the maven build system needs updates. By running this script, you will get all the updates (but none of them will be applied). This lets you change all, some or none, as you see fit.

mvn versions:display-plugin-updates
mvn versions:display-parent-updates
mvn versions:display-dependency-updates

I typically save this script in a top-level check-versions.sh or check-versions.cmd (adjusting for the scripting language).

For this script to work, in /project/build/plugins you'll need the org.codehaus.mojo:versions-maven-plugin:2.7 or greater. I typically configure the plugin like so

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>versions-maven-plugin</artifactId>
  <version>2.7</version>
  <configuration>
    <generateBackupPoms>false</generateBackupPoms>
  </configuration>
</plugin>

As this doesn't make backup pom.xml files which pollute my git history.

The first few times you run this, you might notice that the inherited plugins show themselves to be out of date (as they are effectively built-in to the defaults in the maven default parent pom.xml). You will have to explicitly define the defaults to a newer release to get them to stop reporting.

In addition, you will find that a lot of the plugins will still report because it isn't clear what is the minimum required version of Java and the minimum required version of Apache Maven. To encode these requirements into the pom.xml, you will use the Maven Enforcer plugin. An example of mine that forces Maven version 3.5.4 and Java version 11 is

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-enforcer-plugin</artifactId>
  <version>3.0.0-M3</version>
    <executions>
      <execution>
        <id>enforce-maven</id>
          <goals>
            <goal>enforce</goal>
          </goals>
          <configuration>
            <rules>
            <requireMavenVersion>
              <version>3.5.4</version>
            </requireMavenVersion>
            <requireJavaVersion>
              <version>11</version>
            </requireJavaVersion>
          </rules>
        </configuration>
      </execution>
    </executions>
  </plugin>

With these tools in place, I currently get the output on one of my projects

[INFO] Scanning for projects...
[INFO]
[INFO] ---------------< com.edwbuck.parserhelp:pascal-adapter >----------------
[INFO] Building pascal-adapter 1.0.0
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- versions-maven-plugin:2.7:display-plugin-updates (default-cli) @ pascal-adapter ---
[INFO] artifact com.github.sevntu-checkstyle:dsm-maven-plugin: checking for updates from central
[INFO] artifact net.nicoulaj.maven.plugins:checksum-maven-plugin: checking for updates from central
[INFO]
[INFO] The following plugin updates are available:
[INFO]   maven-project-info-reports-plugin .................... 2.6 -> 3.0.0
[INFO]
[INFO] All plugins have a version specified.
[INFO]
[INFO] Project inherits minimum Maven version as: 3.5.4
[INFO] Plugins require minimum Maven version of: 3.2.1
[INFO]
[INFO] No plugins require a newer version of Maven than specified by the pom.
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.976 s
[INFO] Finished at: 2020-04-16T07:52:12-05:00
[INFO] ------------------------------------------------------------------------
[INFO] Scanning for projects...
[INFO]
[INFO] ---------------< com.edwbuck.parserhelp:pascal-adapter >----------------
[INFO] Building pascal-adapter 1.0.0
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- versions-maven-plugin:2.7:display-parent-updates (default-cli) @ pascal-adapter ---
[INFO] Project does not have a parent.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.325 s
[INFO] Finished at: 2020-04-16T07:52:15-05:00
[INFO] ------------------------------------------------------------------------
[INFO] Scanning for projects...
[INFO]
[INFO] ---------------< com.edwbuck.parserhelp:pascal-adapter >----------------
[INFO] Building pascal-adapter 1.0.0
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- versions-maven-plugin:2.7:display-dependency-updates (default-cli) @ pascal-adapter ---
[INFO] artifact com.edwbuck.parserhelp:pascal_client: checking for updates from central
[INFO] artifact org.junit.jupiter:junit-jupiter-engine: checking for updates from central
[INFO] artifact org.junit.jupiter:junit-jupiter-api: checking for updates from central
[INFO] artifact org.influxdb:influxdb-java: checking for updates from central
[INFO] The following dependencies in Dependencies have newer versions:
[INFO]   org.junit.jupiter:junit-jupiter-api ................... 5.6.0 -> 5.6.2
[INFO]   org.junit.jupiter:junit-jupiter-engine ................ 5.6.0 -> 5.6.2
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.848 s
[INFO] Finished at: 2020-04-16T07:52:18-05:00
[INFO] ------------------------------------------------------------------------

which indicates I need to update my maven-project-info-reports-plugin and my org.junit.jupiter:junit-jupiter-api and org.junit.jupiter:junit-jupiter-engine plugins.

Normally I don't use the maven versions plugin to actually do the update in the pom.xml file, because text editors are fast, if you're doing all the updates you want to do in the pom.xml at one time.

Currently the maven versions plugin offered by codehaus doesn't have an command line option to automatically update more than one version at a time. The reasons it is not there is simple. To use the versions:update-properties plugin, one needs to either:

  1. Define the update policy (what to update / what not to update) in the pom.xml.
  2. Define the update policy (what to update / what not to update) on the command line.

These policies are verbose as they cover the entire project. Yes, they can use glob matching, but they're still verbose. For my personal projects, I notice that for them to give me proper handling, I update them too often, so I leave them out of the picture, instead deciding what to update or not update at the time I work on the output of my check-updates script.

That's because it is not always safe to automatically update plugins and dependencies. Sometimes the next version of a plugin requires code changes to the project. For example, projects shifting from Java 8 to Java 9 require alterations to how they are built and linked. The same goes for dependencies, if you want to keep the code bound to non-deprecated APIs.

Edwin Buck
  • 69,361
  • 7
  • 100
  • 138
  • I'm not sure it's the best way, there might be a better way out there. That said, I can update the modules very quickly, and it is simple to maintain, once you set it up. Finally, it puts you in control, and since you edit the pom files by hand, you have full awareness of the decisions, including when not to update (which you can document into XML comments in the pom files, if necessary) – Edwin Buck Apr 16 '20 at 13:15
  • Thank you, this is interesting, although I do not see the connection to my question. I am sorry I obviously did not make myself clear. I am just interested in updating the version of my project and its modules, so effectively what `mvn versions:set -DnewVersion=1.2.3-SNAPSHOT` does. I just searched for a more convenient way to do this in Eclipse. – J Fabian Meier Apr 16 '20 at 13:58
  • Oh, well, if the versions all match, define it in the parent pom, and have all the children inherit their version number as the parent's verison number. Honestly, the maven commands here are likely to have more characters to type than just editing the parent pom. – Edwin Buck Apr 16 '20 at 14:22
  • They do. But for that, they need to have the correct version number of the parent. So AFAIK I cannot avoid to edit each and every module POM. Changing the project version from say `1.0.0-SNAPSHOT` to `1.1.0-SNAPSHOT` therefore requires changing this version number in 21 places for 20 modules which is error-prone and not really fun. – J Fabian Meier Apr 16 '20 at 14:23
  • Ok, so the modules aren't the same version as the parent. What I was trying to get at is that you shouldn't define the versions in the modules directly, but define the versions in the parent, only once, and then have the children de-reference the parent controlled version. For many child modules, you can do this through parent contained properties, same as you would do for sweeping "must match" library versions. – Edwin Buck Apr 16 '20 at 14:36
  • No, all versions of all modules are the same and also the same as the parent. – J Fabian Meier Apr 16 '20 at 14:37
  • But each module needs to reference its parent. Therefore it has to know the version number of the parent. Maybe I'm wrong. Then please show me how to define a module _without_ the version number of the parent. – J Fabian Meier Apr 16 '20 at 14:39
  • Ok, you can't set that connection dynamically, because to find the parent, it needs to look up the parent. "parent at some version" is not a reproducible build, as you can get a completely different build from the same sources. Maven is built to enforce reproducible builds, so if you want to not update the child's reference to the parent's version, the child will be on the "old" parent version. If you want the child to dynamically find the parent's latest version, you're using the wrong build system, and replacements that do so will eventually hurt you badly (experience talking here). – Edwin Buck Apr 16 '20 at 14:43
  • Yes, but then we are back at the beginning: If I want to change the project version, I need to change the version of the parent first, and then change it in each and every module. – J Fabian Meier Apr 16 '20 at 14:44
  • That's why all the tools I've been showing help you update the explicit versions, instead of dynamically find the latest. Latest version means what you build today might not build tomorrow because someone "out there" updated their project in a way that breaks yours. – Edwin Buck Apr 16 '20 at 14:44
  • I don't want anything like `LATEST`. – J Fabian Meier Apr 16 '20 at 14:45
  • So if the child is to discover the parent version, how will it discover the right parent version if you don't specify it explicitly? – Edwin Buck Apr 16 '20 at 14:46
  • I want to specify it explictly. – J Fabian Meier Apr 16 '20 at 14:46
  • Ok, I think I understand. You want one tool that updates a dozen or more child pom.xml files in one command, right? – Edwin Buck Apr 16 '20 at 14:46
  • Yes. Like `mvn versions:set -DnewVersion=1.2.3-SNAPSHOT` – J Fabian Meier Apr 16 '20 at 14:47
  • Yes, but more like "mvn versions:updateChildren -DsetParentVersion=1.2.3-SNAPSHOT", where you run it on the parent project. Or not exactly 100% that, but I think I get the idea. – Edwin Buck Apr 16 '20 at 14:48
  • `versions:set` replaces all the parent references correctly. You just need to run it on the parent project and it does what I want. – J Fabian Meier Apr 16 '20 at 14:50
  • I think you need to provide a clear example of the problem with pom.xml files in the question. This sounds suspiciously like my second approach described in comments with the ${revisions} parameter; but, maybe it isn't. – Edwin Buck Apr 16 '20 at 14:52
  • There is no problem with the `pom.xml` files. I am just looking for a convenient way to do in Eclipse what `versions:set` is already doing. – J Fabian Meier Apr 16 '20 at 14:54
  • The approach with `${revision}` doesn't work for us because it clashes with Maven release plugin. Otherwise it would be the ideal solution. – J Fabian Meier Apr 16 '20 at 14:55