Skip to content

Conversation

jeromepochat
Copy link
Contributor

@jeromepochat jeromepochat commented Jul 11, 2025

See JENKINS-75622.

When using Apache Maven Daemon as Maven tool, the withMaven pipeline step is looking for mvn executable instead of mvnd. This results in warning log and MVN_CMD not valued.

Build log (before the fix):

$ /bin/sh -c "which mvn"
[withMaven] WARNING: You are running an old version of Maven (UNKNOWN), you should update to at least 3.8.x
[Pipeline] ...
[Pipeline] End of Pipeline
Also:   org.jenkinsci.plugins.workflow.actions.ErrorAction$ErrorId: b7188c8a-71da-4f47-9b58-1bf897b38854
groovy.lang.MissingPropertyException: No such property: MVN_CMD for class: groovy.lang.Binding

This PR adds "mvnd" to the executable candidates searched by MavenInstallation.

Build log (after the fix):

+ /home/jerome/devel/jenkinsci/jenkins/war/work/workspace/job1@tmp/withMavenfb7d168d/mvnd --version
Jul 11, 2025 4:15:20 PM org.jline.utils.Log logr
WARNING: Unable to create a system terminal, creating a dumb terminal (enable debug logging for more information)
[main] WARNING org.jline - Unable to create a system terminal, creating a dumb terminal (enable debug logging for more information)
Apache Maven Daemon (mvnd) 1.0.2 linux-amd64 native client (cccc1ec8a5b741c62b29f9fb04d37b1678a029bb)
Terminal: org.jline.terminal.impl.DumbTerminal
Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937)
Maven home: /home/jerome/devel/jenkinsci/jenkins/war/work/tools/hudson.tasks.Maven_MavenInstallation/M3/maven-mvnd-1.0.2-linux-amd64/mvn
  • With Maven 3.9.10 (automatic installation)
+ /home/jerome/devel/jenkinsci/jenkins/war/work/workspace/job1@tmp/withMaven35061a3b/mvn --version
Picked up JAVA_TOOL_OPTIONS: -Dmaven.ext.class.path="/home/jerome/devel/jenkinsci/jenkins/war/work/workspace/job1@tmp/withMaven35061a3b/pipeline-maven-spy.jar" -Dorg.jenkinsci.plugins.pipeline.maven.reportsFolder="/home/jerome/devel/jenkinsci/jenkins/war/work/workspace/job1@tmp/withMaven35061a3b" 
Apache Maven 3.9.10 (5f519b97e944483d878815739f519b2eade0a91d)
Maven home: /home/jerome/devel/jenkinsci/jenkins/war/work/tools/hudson.tasks.Maven_MavenInstallation/M3

Testing notes

  • Check that there is neither mvn nor mvnd in the system PATH
  • Configure M3 tool using Maven Daemon 1.0.2
  • Configure the pipeline that uses $MVN_CMD and triggers the build
pipeline {
    agent any

    tools {
        maven "M3"
    }

    stages {
        stage('Build') {
            steps {
                withMaven {
                    sh "$MVN_CMD --version"
                }
            }
        }
    }
}

Proposed changelog entries

  • bug: withMaven pipeline step sets MVN_CMD variable to mvnd instead of mvn when using Apache Maven Daemon.

Proposed changelog category

/label

Proposed upgrade guidelines

N/A

Submitter checklist

  • The Jira issue, if it exists, is well-described.
  • The changelog entries and upgrade guidelines are appropriate for the audience affected by the change (users or developers, depending on the change) and are in the imperative mood (see examples). Fill in the Proposed upgrade guidelines section only if there are breaking changes or changes that may require extra steps from users during upgrade.
  • There is automated testing or an explanation as to why this change has no tests.
  • New public classes, fields, and methods are annotated with @Restricted or have @since TODO Javadocs, as appropriate.
  • New deprecations are annotated with @Deprecated(since = "TODO") or @Deprecated(forRemoval = true, since = "TODO"), if applicable.
  • New or substantially changed JavaScript is not defined inline and does not call eval to ease future introduction of Content Security Policy (CSP) directives (see documentation).
  • For dependency updates, there are links to external changelogs and, if possible, full differentials.
  • For new APIs and extension points, there is a link to at least one consumer.

Desired reviewers

@mention

Before the changes are marked as ready-for-merge:

Maintainer checklist

  • There are at least two (2) approvals for the pull request and no outstanding requests for change.
  • Conversations in the pull request are over, or it is explicit that a reviewer is not blocking the change.
  • Changelog entries in the pull request title and/or Proposed changelog entries are accurate, human-readable, and in the imperative mood.
  • Proper changelog labels are set so that the changelog can be generated automatically.
  • If the change needs additional upgrade steps from users, the upgrade-guide-needed label is set and there is a Proposed upgrade guidelines section in the pull request title (see example).
  • If it would make sense to backport the change to LTS, a Jira issue must exist, be a Bug or Improvement, and be labeled as lts-candidate to be considered (see query).

@jeromepochat
Copy link
Contributor Author

/label bug

@comment-ops-bot comment-ops-bot bot added the bug For changelog: Minor bug. Will be listed after features label Jul 11, 2025
@jeromepochat jeromepochat changed the title [JENKINS-75622] Resolve mvnd executable [JENKINS-75622] Maven Daemon support Jul 11, 2025
@jeromepochat jeromepochat marked this pull request as ready for review July 11, 2025 22:15
Copy link

@A1exKH A1exKH left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@daniel-beck
Copy link
Member

This change should be documented in some manner on the UI. I'd be surprised to learn mvnd was supported by this feature, when nothing in the UI tells me about it.

It seems unexpected that M2_HOME etc. will be set to a directory that does not actually contain mvn at the expected path.

(Nit-picking) Why is lack of support of an entire different project a bug?

Copy link
Member

@oleg-nenashev oleg-nenashev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I declare a potential conflict of interest, but I would be also surprised if Jenkins started silently using the daemon executable, even as a fallback to mvn in the home.

P.S: I guess, the same call should ideally check mvnw, too

@krisstern krisstern requested a review from a team July 21, 2025 10:31
@daniel-beck
Copy link
Member

P.S: I guess, the same call should ideally check mvnw, too

mvnw doesn't need an install directory though, so it would not apply here?

@jeromepochat
Copy link
Contributor Author

jeromepochat commented Jul 31, 2025

This change should be documented in some manner on the UI. I'd be surprised to learn mvnd was supported by this feature, when nothing in the UI tells me about it.

AFAIU, all the help messages from Tools UI are generic and I can't see any place to add information about Maven Deamon support. The messages are even not Maven specific and are generic for any tool.

image

It seems unexpected that M2_HOME etc. will be set to a directory that does not actually contain mvn at the expected path.

I tried first to not assign M2_HOME and MAVEN_HOME for mvnd case but this causes $MVN_CMD --version to fail. IIUC, one of the two variables is required by withMaven step to compute MVN_CMD.

So 023efd4 adjusts the environment variables to embedded Maven subdirectory:

M2_HOME=${mvnd.home}/mvn/
MAVEN_HOME=${mvnd.home}/mvn/

FTR, Maven Daemon directory tree (filtered):

${mvnd.home}
├── bin
│   ├── mvnd
│   ├── mvnd.cmd
│   ├── mvnd.sh
├── mvn (=> Maven 3.9.9)
│   ├── bin
│   │   ├── mvn
│   │   ├── mvnDebug
│   │   ├── mvnDebug.cmd

Notice that PATH+MAVEN is not adjusted to embedded Maven subdirectory as it is used to reach MVN_CMD (could be mvn or mvnd).

Tested using:

withMaven {
   sh "$MVN_CMD --version"
   sh "echo MAVEN_HOME=$MAVEN_HOME"
}

Resulting log:

[Pipeline] sh
+ /home/jerome/devel/jenkinsci/jenkins/war/work/workspace/job1@tmp/withMaven5ac2aac9/mvn --version
Picked up JAVA_TOOL_OPTIONS: -Dmaven.ext.class.path="/home/jerome/devel/jenkinsci/jenkins/war/work/workspace/job1@tmp/withMaven5ac2aac9/pipeline-maven-spy.jar" -Dorg.jenkinsci.plugins.pipeline.maven.reportsFolder="/home/jerome/devel/jenkinsci/jenkins/war/work/workspace/job1@tmp/withMaven5ac2aac9" 
Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937)
Maven home: /home/jerome/devel/jenkinsci/jenkins/war/work/tools/hudson.tasks.Maven_MavenInstallation/M3/maven-mvnd-1.0.2-linux-amd64/mvn
Java version: 21.0.8, vendor: Eclipse Adoptium, runtime: /home/jerome/.sdkman/candidates/java/21.0.8-tem
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "6.8.0-64-generic", arch: "amd64", family: "unix"
[Pipeline] sh
+ echo MAVEN_HOME=/home/jerome/devel/jenkinsci/jenkins/war/work/tools/hudson.tasks.Maven_MavenInstallation/M3/maven-mvnd-1.0.2-linux-amd64/mvn
MAVEN_HOME=/home/jerome/devel/jenkinsci/jenkins/war/work/tools/hudson.tasks.Maven_MavenInstallation/M3/maven-mvnd-1.0.2-linux-amd

Copy link
Member

@jtnord jtnord left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After the fix...

/home/jerome/devel/jenkinsci/jenkins/war/work/workspace/job1@tmp/withMavenfb7d168d/mvnd --version

This starts a maven daemon (if one does not already exist). I'm not convinced that would be expected and certainly nothing would be attempting to close it down would it?

The daemon has the JENKINS_COOKIE in its environment so it will be killed at the end of use by the ProcessTreeKiller / process cleanup code. I expect this to cause issues when you have multiple executors per agent, as an agent will be killed when it could be in use elsewhere.

I'm not actually sure you even need any changes - you have the "optional directory of the downloaded and unpacked archive" in the case of mvnd it is just mvn isn't it?

// Maven 2.x and earlier
return exe.getPath();
}
exe = getExeFile("mvnd", rawHome);
Copy link
Member

@jtnord jtnord Aug 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this to me is strange. this is not maven it is maven-deamon and is a different thing.
if you want this to be a maven installation when it is not - it should still return the mvn from the sub directory.

starting maven daemon (and indeed shutting it down) would not be performed (correctly) by any calling code without changes, nor is the output expected to be the same.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug For changelog: Minor bug. Will be listed after features
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants