Skip to content

Commit 585781d

Browse files
committed
Attempt to fix the JvmOptions in native-image
1 parent 67ecceb commit 585781d

File tree

2 files changed

+58
-16
lines changed

2 files changed

+58
-16
lines changed

components/environment/src/main/java/datadog/environment/JvmOptions.java

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import java.nio.file.Paths;
1616
import java.util.ArrayList;
1717
import java.util.List;
18-
import java.util.ListIterator;
1918
import java.util.StringTokenizer;
2019

2120
/** Fetches and captures the JVM options. */
@@ -41,28 +40,35 @@ private String[] readProcFsCmdLine() {
4140
return null;
4241
}
4342

44-
@SuppressForbidden // Class.forName() as backup
4543
private List<String> findVmOptions() {
44+
return findVmOptions(PROCFS_CMDLINE);
45+
}
46+
47+
@SuppressForbidden // Class.forName() as backup
48+
// Visible for testing
49+
List<String> findVmOptions(String[] procfsCmdline) {
4650
// Try ProcFS on Linux
47-
if (PROCFS_CMDLINE != null) {
51+
// Be aware that when running a native image, the command line in /proc/self/cmdline is just the
52+
// executable
53+
if (procfsCmdline != null) {
54+
// Create list of VM options
55+
List<String> vmOptions = new ArrayList<>();
4856
// Start at 1 to skip "java" command itself
4957
int index = 1;
5058
// Look for main class or "-jar", end of VM options
51-
for (; index < PROCFS_CMDLINE.length; index++) {
52-
if (!PROCFS_CMDLINE[index].startsWith("-") || "-jar".equals(PROCFS_CMDLINE[index])) {
53-
break;
59+
// Simultaneously, collect all arguments in the VM options
60+
for (; index < procfsCmdline.length; index++) {
61+
String argument = procfsCmdline[index];
62+
if (argument.startsWith("@")) {
63+
vmOptions.addAll(getArgumentsFromFile(argument));
64+
} else {
65+
vmOptions.add(argument);
5466
}
55-
}
56-
// Create list of VM options
57-
List<String> vmOptions = new ArrayList<>(asList(PROCFS_CMDLINE).subList(1, index + 1));
58-
ListIterator<String> iterator = vmOptions.listIterator();
59-
while (iterator.hasNext()) {
60-
String vmOption = iterator.next();
61-
if (vmOption.startsWith("@")) {
62-
iterator.remove();
63-
for (String argument : getArgumentsFromFile(vmOption)) {
64-
iterator.add(argument);
67+
if (!argument.startsWith("-") || "-jar".equals(argument)) {
68+
if (index + 1 < procfsCmdline.length) {
69+
vmOptions.add(procfsCmdline[index + 1]); // jar file or the main class
6570
}
71+
break;
6672
}
6773
}
6874
// Insert JDK_JAVA_OPTIONS at the start if present and supported

components/environment/src/test/java/datadog/environment/JvmOptionsTest.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,42 @@ void testFindVmOptions(
105105
assertEquals(expectedArguments.jvmOptions, result.jvmOptions, "Failed to get JVM options");
106106
}
107107

108+
@MethodSource
109+
private static Stream<Arguments> procFsCmdLine() {
110+
// spotless:off
111+
return Stream.of(
112+
arguments(
113+
"No arguments",
114+
new String[0],
115+
emptyList()
116+
),
117+
arguments(
118+
"Native image launcher",
119+
new String[]{"native-image-launcher", "-Xmx512m"},
120+
singletonList("-Xmx512m")
121+
),
122+
arguments(
123+
"Java with JAR and options",
124+
new String[]{"java", "-Xmx512m", "-Xms256m", "-jar", "app.jar"},
125+
asList("-Xmx512m", "-Xms256m", "-jar", "app.jar")
126+
),
127+
arguments(
128+
"Java from class and options",
129+
new String[]{"java", "-Xmx512m", "-Xms256m", "-cp", "app.jar", "Main"},
130+
asList("-Xmx512m", "-Xms256m", "-cp", "app.jar", "Main")
131+
));
132+
// spotless:on
133+
}
134+
135+
@ParameterizedTest(name = "[{index}] {0}")
136+
@MethodSource("procFsCmdLine")
137+
void testFindVmOptionsWithProcFsCmdLine(
138+
String useCase, String[] procfsCmdline, List<String> expected) throws Exception {
139+
JvmOptions vmOptions = new JvmOptions();
140+
List<String> found = vmOptions.findVmOptions(procfsCmdline);
141+
assertEquals(expected, found);
142+
}
143+
108144
private void skipJdkJavaOptionsOnJava8(Map<String, String> environmentVariables) {
109145
assumeTrue(
110146
JavaVirtualMachine.isJavaVersionAtLeast(9)

0 commit comments

Comments
 (0)