|
15 | 15 | import java.util.ArrayList; |
16 | 16 | import java.util.Arrays; |
17 | 17 | import java.util.List; |
| 18 | +import java.util.ListIterator; |
18 | 19 | import java.util.StringTokenizer; |
19 | 20 |
|
20 | 21 | /** Fetches and captures the JVM options. */ |
@@ -55,18 +56,27 @@ private List<String> findVmOptions() { |
55 | 56 | break; |
56 | 57 | } |
57 | 58 | } |
58 | | - String[] vmOptions = new String[index - 1]; |
59 | | - System.arraycopy(PROCFS_CMDLINE, 1, vmOptions, 0, vmOptions.length); |
60 | | - |
61 | | - // TODO ARGFILES Need to be substituted |
62 | | - |
63 | | - // TODO JAVA_TOOLS_OPTIONS Need to be inserted before. |
64 | | - // String javaToolOptions = EnvironmentVariables.getOrDefault("JAVA_TOOL_OPTIONS", null); |
65 | | - // if (javaToolOptions != null) { |
66 | | - // parts.addAll(0, Arrays.asList(javaToolOptions.split(" "))); |
67 | | - // } |
68 | | - |
69 | | - return Arrays.asList(vmOptions); |
| 59 | + // Create list of VM options |
| 60 | + String[] vmOptionsArray = new String[index - 1]; |
| 61 | + System.arraycopy(PROCFS_CMDLINE, 1, vmOptionsArray, 0, vmOptionsArray.length); |
| 62 | + List<String> vmOptions = Arrays.asList(vmOptionsArray); |
| 63 | + // Substitute @argfile by their content |
| 64 | + ListIterator<String> iterator = vmOptions.listIterator(); |
| 65 | + while (iterator.hasNext()) { |
| 66 | + String vmOption = iterator.next(); |
| 67 | + if (vmOption.startsWith("@")) { |
| 68 | + iterator.remove(); |
| 69 | + for (String argument : getArgumentsFromFile(vmOption)) { |
| 70 | + iterator.add(argument); |
| 71 | + } |
| 72 | + } |
| 73 | + } |
| 74 | + // Insert JAVA_TOOL_OPTIONS at the start if present |
| 75 | + List<String> toolOptions = getToolOptions(); |
| 76 | + if (!toolOptions.isEmpty()) { |
| 77 | + vmOptions.addAll(0, toolOptions); |
| 78 | + } |
| 79 | + return vmOptions; |
70 | 80 | } |
71 | 81 |
|
72 | 82 | // Try Oracle-based |
@@ -144,6 +154,52 @@ private static List<String> getArgumentsFromFile(String argFile) { |
144 | 154 | } |
145 | 155 | } |
146 | 156 |
|
| 157 | + private static List<String> getToolOptions() { |
| 158 | + String javaToolOptions = EnvironmentVariables.getOrDefault("JAVA_TOOL_OPTIONS", ""); |
| 159 | + return javaToolOptions.isEmpty() ? emptyList() : parseToolOptions(javaToolOptions); |
| 160 | + } |
| 161 | + |
| 162 | + /** |
| 163 | + * Parse the JAVA_TOOL_OPTIONS environment variable according the JVMTI specifications |
| 164 | + * |
| 165 | + * @param javaToolOptions The JAVA_TOOL_OPTIONS environment variable. |
| 166 | + * @return The parsed JVM options. |
| 167 | + * @see <a |
| 168 | + * href="https://docs.oracle.com/en/java/javase/21/docs/specs/jvmti.html#tooloptions">JVMTI |
| 169 | + * specifications</a> |
| 170 | + */ |
| 171 | + static List<String> parseToolOptions(String javaToolOptions) { |
| 172 | + List<String> options = new ArrayList<>(); |
| 173 | + StringBuilder option = new StringBuilder(); |
| 174 | + boolean inQuotes = false; |
| 175 | + char quoteChar = 0; |
| 176 | + |
| 177 | + for (int i = 0; i < javaToolOptions.length(); i++) { |
| 178 | + char c = javaToolOptions.charAt(i); |
| 179 | + if (inQuotes) { |
| 180 | + if (quoteChar == c) { |
| 181 | + inQuotes = false; |
| 182 | + } else { |
| 183 | + option.append(c); |
| 184 | + } |
| 185 | + } else if (c == '"' || c == '\'') { |
| 186 | + inQuotes = true; |
| 187 | + quoteChar = c; |
| 188 | + } else if (Character.isWhitespace(c)) { |
| 189 | + if (option.length() > 0) { |
| 190 | + options.add(option.toString()); |
| 191 | + option.setLength(0); |
| 192 | + } |
| 193 | + } else { |
| 194 | + option.append(c); |
| 195 | + } |
| 196 | + } |
| 197 | + if (option.length() > 0) { |
| 198 | + options.add(option.toString()); |
| 199 | + } |
| 200 | + return options; |
| 201 | + } |
| 202 | + |
147 | 203 | private static List<String> split(String str, String delimiter) { |
148 | 204 | List<String> parts = new ArrayList<>(); |
149 | 205 | StringTokenizer tokenizer = new StringTokenizer(str, delimiter); |
|
0 commit comments