How to upgrade agents to java 17, but keep java version for builds at java 8, 11, ..?

Hi folks, I just read the following instructions:

As far as I understand, this will upgrade the build agents completely to the new java version.

We will skip java 11 and try to upgrade all machines to java 17 directly (master and all slaves), but some of our builds still need older java versions.

So far we had a seperate build agents for each java version. So when a job was running on an agent labeled “java8”, it was expected that any java or javac calls would run with the java 8 versions.

But how would this work now on an agent which has java 17 installed? Are there config params to distinguish between the agent version and the build tools version of java?

All machines are VMs, no docker containers (so far).

Here is a video from @darinpope that describes the configuration of multiple JDK versions:

As a reminder, the term “slave” to refer to an agent has been deprecated since 2016. Please refer to On Jenkins Terminology Updates for more details. We request you update your post.

Mark Waite


Short of it is - java used for builds is, in most cases, unrelated to java used for controller/agents. You can use the Tool system to install right versions of JDK as needed. That said, I was under impression that Jenkins did not yet support 17 for running Controller/Agent (you can use it for builds though)


Thanks for the video and the link about the terminology, didn’t know that so far!

I just saw the information here about 11 or 17 being mandatory:

Starting with the weekly release line 2.353, Java 11 or Java 17 will be required to use Jenkins.

And one of our build agents is already running java 17, so I assumed it’s already supported in the current release.

Checking the release notes, I found this, sounds to me like it is supported now?

What’s new in 2.346.1 (2022-06-22)

Allow running on Java 17 without --enable-future-java

We will see, but good point to check that first!

The next lts will require 11 and should support 17. Some say 17 is more stable but not recommended for Lts yet as it’s gotten less testing

If your using weeklies (only two version numbers) then yea 17 should be fine.

After the next lts (very soon now) java 8 support will be dropped and only 11 and 17 will work.

Two more questions arise from this:

Is it possible to bind the JDK to an agent or a label?
Currently each agent has a label like “java8”, “java11”, …
I can set the JAVA_PATH in the agent configuration, but this will be used for the agent, right?
So in our case, should point to the JDK 17?

We are not using pipeline jobs like shown in the video.
Is it still possible to set the tools jdk in a freestyle or maven job?

A label can be assigned to an agent. The label can be used the represent the availability of a specific tool version on that agent. Labels could be java8, java11, and java17 to indicate that those Java versions are available on the agent. Labels could be linux, windows, macOS, FreeBSD, or OpenBSD to indicate the operating system hosting the agent. Labels could be git-1.8 or git-2.36 to indicate the specific version of a tool that is installed on the agent.

If your controller is running Java 17, then your agents should run Java 17. Running Java 17 does not prevent you from installing Java 8 and Java 11 (and other Java versions) on the agent. If they are installed, then jobs can use those other Java installations.

Thanks, I understand now.

But we have over 300 jobs now and “then jobs can use those other Java installations” means I would have to modify all 300 jobs to do exactly that. Currently they all have the label set to the Java version they need, e.g. “java8”.

I have looked at the node configurations we have and I saw something interesting:
One of the agents has this set:

Under “Launch method” → “Advanced” → “JavaPath” it has:

This java Path will be used to start the jvm. (/mycustomjdkpath/bin/java ) If empty Jenkins will search java command in the agent
Expressions such as $key or ${key} may be declared in the java Path and will be expanded to values of matching keys declared in the list of environment variables of this node, or if not present, in the list of global environment variables.
(from SSH Build Agents plugin)

Node Properties → Environment Variables:
JAVA_HOME = /usr/local/jdk-11.0.1/

Environment variables defined here will be made available to every build executed by this agent, and will override any environment variables that have the same Name as those defined on the Configure System page.
Using the syntax $NAME or ${NAME} (%NAME% on Windows), these variables can be used in job configurations, or from process launched by a build.

Does this mean if I set the JavaPath to the Java 17 installation, I can use the JAVA_HOME for the Java 8/11/14 installation? Or am I missing something important here?

I’m just trying to avoid to modify so many jobs all containing different technologies for the build.
Or even worse, to tell people to convert every job to a pipeline jobs just to configure the jdk.

As far as I can tell from your descriptions, your job definitions are tightly coupled to the Java version that is running the agent. The Jenkins documentation states that agents should be run with the same Java version that runs the controller. You can’t have jobs that are tightly coupled to the Java version (in your case Java 8 and Java 11), run the controller on Java 17, and also comply with the requirement that agents must run the same Java version as the controller.

I believe that your options are:

  • Redefine the jobs so that they are not tightly coupled to the Java version running the agent
  • Remain with Java 8 on the controller and the agents, accepting that you’re locking yourself into a Java version that the Jenkins project is dropping from support

To add to that, the easiest way to go is to use java “tools” definitions, - Jenkins tool system can happily install the right version of Java on the agent you are running when it is missing, instead of creating a dedicated agent for every java version and the jumping versions.