From 5d326cd265ac492b4060e1b99696060ee4728677 Mon Sep 17 00:00:00 2001 From: Raphael Fakhri <153192858+RaphaelFakhri@users.noreply.github.com> Date: Thu, 22 Oct 2026 12:28:48 +0000 Subject: [PATCH 1/2] Fix JVM tool bootstrap check with program arguments containing slashes --- CHANGELOG.next-release.md | 2 +- .../elastic/apm/agent/premain/JvmToolBootstrapCheck.java | 7 +++++-- .../apm/agent/premain/JvmToolBootstrapCheckTest.java | 5 +++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.next-release.md b/CHANGELOG.next-release.md index 91ab0d62d03..6850e010886 100644 --- a/CHANGELOG.next-release.md +++ b/CHANGELOG.next-release.md @@ -9,7 +9,7 @@ This file contains all changes which are not released yet. # Fixes - +- Fix JVM tool bootstrap check when program arguments contain slashes - [#4269](https://github.com/elastic/apm-agent-java/issues/4269) # Features and enhancements diff --git a/elastic-apm-agent-premain/src/main/java/co/elastic/apm/agent/premain/JvmToolBootstrapCheck.java b/elastic-apm-agent-premain/src/main/java/co/elastic/apm/agent/premain/JvmToolBootstrapCheck.java index b5728f6271c..998be506647 100644 --- a/elastic-apm-agent-premain/src/main/java/co/elastic/apm/agent/premain/JvmToolBootstrapCheck.java +++ b/elastic-apm-agent-premain/src/main/java/co/elastic/apm/agent/premain/JvmToolBootstrapCheck.java @@ -51,14 +51,17 @@ public static void checkJdkTool(String jvmCmd, BootstrapCheckResult result) { return; } + // only the main class or module part is relevant, program arguments may contain slashes + String mainClass = parts.length > 0 ? parts[0] : jvmCmd; + boolean isJdkTool = false; - parts = jvmCmd.split("/"); + parts = mainClass.split("/"); if (parts.length == 2) { // JDK with module system isJdkTool = parts[0].startsWith("jdk.") || parts[0].startsWith("java."); } else if (parts.length == 1) { - isJdkTool = jvmCmd.startsWith("sun.") || jvmCmd.startsWith("com.sun.") || jvmCmd.startsWith("jdk."); + isJdkTool = mainClass.startsWith("sun.") || mainClass.startsWith("com.sun.") || mainClass.startsWith("jdk."); } else { result.addWarn("Unexpected JVM command line syntax: " + jvmCmd); } diff --git a/elastic-apm-agent-premain/src/test/java/co/elastic/apm/agent/premain/JvmToolBootstrapCheckTest.java b/elastic-apm-agent-premain/src/test/java/co/elastic/apm/agent/premain/JvmToolBootstrapCheckTest.java index f5fd226f3b2..3f23b0f809f 100644 --- a/elastic-apm-agent-premain/src/test/java/co/elastic/apm/agent/premain/JvmToolBootstrapCheckTest.java +++ b/elastic-apm-agent-premain/src/test/java/co/elastic/apm/agent/premain/JvmToolBootstrapCheckTest.java @@ -92,6 +92,9 @@ class JvmToolBootstrapCheckTest { "sun.tools.jstat.Jstat", "sun.tools.native2ascii.Main", "sun.tools.serialver.SerialVer", + // with program arguments containing slashes + "java.base/sun.security.tools.keytool.Main -list -keystore /tmp/keystore.jks", + "sun.security.tools.keytool.Main -list -keystore /tmp/keystore.jks", }) void testJdkTool(String cmd) { BootstrapCheck.BootstrapCheckResult result = new BootstrapCheck.BootstrapCheckResult(); @@ -115,6 +118,8 @@ void checkNotJdkTool() { checkNotJdkTool("/target/app.jar"); // java -jar /target/app.jar checkNotJdkTool("/target/app.jar with some arguments"); // java -jar /target/app.jar with arguments checkNotJdkTool("app.Main"); // java app.Main + checkNotJdkTool("org.example.Main --file /my/path/containing/slashes/file.txt"); // java org.example.Main --file /my/path/... + checkNotJdkTool("my.module/org.example.Main --file /my/path/file.txt"); // java -m my.module/org.example.Main --file /my/path/file.txt checkNotJdkTool(System.getProperty("sun.java.command")); // Maven/IDE JUnit runner } From a0fa7deb42ce87f271777f58dc9359b86a423a00 Mon Sep 17 00:00:00 2001 From: Raphael Fakhri <153192858+RaphaelFakhri@users.noreply.github.com> Date: Fri, 23 Oct 2026 15:45:10 +0000 Subject: [PATCH 2/2] Do not flag the GlassFish/Payara bootstrap class as a JVM tool --- .../co/elastic/apm/agent/premain/JvmToolBootstrapCheck.java | 5 ++++- .../elastic/apm/agent/premain/JvmToolBootstrapCheckTest.java | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/elastic-apm-agent-premain/src/main/java/co/elastic/apm/agent/premain/JvmToolBootstrapCheck.java b/elastic-apm-agent-premain/src/main/java/co/elastic/apm/agent/premain/JvmToolBootstrapCheck.java index 998be506647..83d2c29b99b 100644 --- a/elastic-apm-agent-premain/src/main/java/co/elastic/apm/agent/premain/JvmToolBootstrapCheck.java +++ b/elastic-apm-agent-premain/src/main/java/co/elastic/apm/agent/premain/JvmToolBootstrapCheck.java @@ -61,7 +61,10 @@ public static void checkJdkTool(String jvmCmd, BootstrapCheckResult result) { // JDK with module system isJdkTool = parts[0].startsWith("jdk.") || parts[0].startsWith("java."); } else if (parts.length == 1) { - isJdkTool = mainClass.startsWith("sun.") || mainClass.startsWith("com.sun.") || mainClass.startsWith("jdk."); + // com.sun.enterprise.* is the GlassFish/Payara bootstrap, an application server rather than a JDK tool + isJdkTool = mainClass.startsWith("sun.") || + (mainClass.startsWith("com.sun.") && !mainClass.startsWith("com.sun.enterprise.")) || + mainClass.startsWith("jdk."); } else { result.addWarn("Unexpected JVM command line syntax: " + jvmCmd); } diff --git a/elastic-apm-agent-premain/src/test/java/co/elastic/apm/agent/premain/JvmToolBootstrapCheckTest.java b/elastic-apm-agent-premain/src/test/java/co/elastic/apm/agent/premain/JvmToolBootstrapCheckTest.java index 3f23b0f809f..90c8b4ce27c 100644 --- a/elastic-apm-agent-premain/src/test/java/co/elastic/apm/agent/premain/JvmToolBootstrapCheckTest.java +++ b/elastic-apm-agent-premain/src/test/java/co/elastic/apm/agent/premain/JvmToolBootstrapCheckTest.java @@ -120,6 +120,7 @@ void checkNotJdkTool() { checkNotJdkTool("app.Main"); // java app.Main checkNotJdkTool("org.example.Main --file /my/path/containing/slashes/file.txt"); // java org.example.Main --file /my/path/... checkNotJdkTool("my.module/org.example.Main --file /my/path/file.txt"); // java -m my.module/org.example.Main --file /my/path/file.txt + checkNotJdkTool("com.sun.enterprise.glassfish.bootstrap.ASMain -upgrade false -domaindir /opt/payara/glassfish/domains/domain1"); // Payara checkNotJdkTool(System.getProperty("sun.java.command")); // Maven/IDE JUnit runner }