If you run CI at a company with a long tail of platforms, you may know this one. I've worked on CI and Jenkins for years, and I keep seeing the same problem in the community and among peers.

The squeeze

A lot of enterprise software ships on many platforms. Besides mainstream Linux there is AIX, HP-UX, Solaris, and RHEL 6 machines (sometimes RHEL 5) that have been building releases for years and that nobody wants to touch. They are Jenkins agents, and every platform build comes from them.

On these systems, Java stops at 8:

  • AIX 7.1 tops out at IBM Java 8. IBM Semeru 17 and 21 need AIX 7.2 or 7.3.
  • HP-UX has HPE's JDK 8.
  • Solaris 10 has Java 8; Solaris 11 stops at JDK 11.
  • Current JDKs don't support RHEL 6 any more.

Jenkins, meanwhile, keeps raising its Java baseline, and the requirement covers agents, not only the controller:

  • Jenkins 2.361.1 LTS (2022): Java 11 for controller and agents.
  • 2.479.1 LTS (2024): Java 17.
  • Today: Java 21 or 25. The last LTS that ran on Java 8 was 2.346.3, from 2022.

And then the security scan arrives. An old controller is a list of CVEs, and IT does not negotiate.

So you pick one:

  • Upgrade the controller. The audit passes, and every AIX, HP-UX, Solaris and old RHEL agent can no longer connect.
  • Don't upgrade. The old agents keep working, and the whole Jenkins stays on a release nobody patches, with an exception request every audit cycle.

What teams usually end up doing: keep a second, old Jenkins just for those platforms (two systems to run, two sets of CVEs), or build those platforms by hand. Some drive the old hosts over SSH from a modern agent with an SSH plugin. It works on paper, but logs, aborts, workspaces and artifacts are all yours to wire up, and the host is no longer a real node.

There was no good open-source answer, so I set out to build one.

The idea: make agent.jar itself run on Java 8

A Jenkins agent is agent.jar (Jenkins Remoting). It refuses old Java only because its bytecode targets new Java. So: downgrade the bytecode.

JvmDowngrader rewrites class files to an older version and supplies stand-ins for newer JDK APIs. That gets you started, not finished:

  1. The controller sends classes at runtime (FilePath, junit, stash, plugin code). Those have to be downgraded as they load.
  2. Downgrading adds synthetic members, which changes the default serialVersionUID. The controller then rejects every call, so the UIDs have to be pinned first.
  3. Java 8 has no serial form for List.of, Map.of or Stream.toList(). It has to be added.
  4. IBM's OpenJ9 differs from HotSpot internally, and some stand-ins break on it.

With those handled, you get Agent8 for Jenkins:

👉 https://github.com/keelinfra/agent8

A Jenkins agent that runs on Java 8 (builds for Java 11 and 17 too) and connects to a current Jenkins controller on Java 21+. The old host stays an ordinary node: labels, executors, sh, file steps, junit, stash, aborts and the script console all work as on any other agent.

Using it

On the build host, with the Java it already has:

sh install.sh --url https://jenkins.example.com/ --replace /path/to/agent.jar 

install.sh asks the controller for its remoting version, downloads the matching agent8 build, verifies it against sha256sums.txt, test-starts it on the host's Java, keeps your original jar as agent.jar.before-agent8, and swaps agent8 in. Restart the agent with the command you already use. --restore puts the original back.

The script is plain POSIX sh for the old shells on AIX, Solaris and HP-UX. For a fleet there is an Ansible playbook that needs no Python on the hosts. Offline hosts use --from DIR.

One controller setting: if the Versions Node Monitors (versioncolumn) plugin is installed, its JVM Version monitor disconnects agents whose Java is older than the controller's. Set it to not disconnect (the README has the JCasC snippet).

Where it stands, honestly

  • Tested in CI on every change and weekly, against the current LTS and weekly: Linux with HotSpot 8 (CentOS 6.10), OpenJ9 8 (the JVM family of IBM Java 8 on AIX), and HotSpot 11. Pipeline builds, Git checkout, withCredentials, aborts and an agent restart mid-build are all covered.
  • Experimental on real AIX, Solaris and HP-UX: not fully run on real hardware yet. OpenJ9 covers the JVM, not AIX itself.
  • Inbound agents only. Agents launched by the SSH Build Agents plugin aren't supported yet (it copies its own remoting.jar and checks the Java version).
  • Not an official Jenkins project.

If you have AIX 7.1, Solaris, HP-UX or old RHEL build hosts, I'd love for you to try it and tell me how it went in the issues, whether it worked or broke. Which plugins you use and where it failed is exactly what I need.

If your situation is bigger (many platforms, many plugins, a migration someone has to own), you can also reach out to me directly.