-
Notifications
You must be signed in to change notification settings - Fork 80
Description
At the moment, when native-image-agent is injected into JVM processes that are spawned for test executions we are specifying its output directory as a fixed path.
In Maven plugin this is done here:
Lines 86 to 90 in 5ac47c6
| static String buildAgentArgument(String baseDir, Context context, List<String> agentOptions) { | |
| List<String> options = new ArrayList<>(agentOptions); | |
| options.add("config-output-dir=" + agentOutputDirectoryFor(baseDir, context)); | |
| return "-agentlib:native-image-agent=" + String.join(",", options); | |
| } |
In Gradle:
Lines 77 to 93 in b14f07b
| @Override | |
| public Iterable<String> asArguments() { | |
| if (getEnabled().get()) { | |
| File outputDir = getOutputDirectory().getAsFile().get(); | |
| List<String> agentOptions = new ArrayList<>(getAgentOptions().getOrElse(Collections.emptyList())); | |
| if (agentOptions.stream().map(s -> s.split("=")[0]).anyMatch(s -> s.contains("config-output-dir"))) { | |
| throw new IllegalStateException("config-output-dir cannot be supplied as an agent option"); | |
| } | |
| agentOptions.add("config-output-dir=" + outputDir.getAbsolutePath()); | |
| return Arrays.asList( | |
| "-agentlib:native-image-agent=" + String.join(",", agentOptions), | |
| "-Dorg.graalvm.nativeimage.imagecode=agent" | |
| ); | |
| } | |
| return Collections.emptyList(); | |
| } | |
| } |
An issue that arises from this approach is that each parallel test execution overwrites older configuration.
Trivial solution for this would be change the invocation parameter to config-merge-dir, but that would (AFAIK) require that tests are being run sequentially which would hinder performance significantly. Potentially we could hack the agent itself to wait on some kind of file lock if user opted-in to that, but that won't land in a release anytime soon.
Proper solution would be to use {pid} and {datetime} placeholders for output directory (as described in this section of the documentation)
export JAVA_TOOL_OPTIONS="-agentlib:native-image-agent=config-output-dir=/path/to/config-output-dir-{pid}-{datetime}/"
and then merge configuration using native-image-configure tool after test execution is done.
Unfortunately, as documentation points out:
Note: The Native Image Configure Tool is only available if native-image is built via mx.
This configuration tool is not part of any GraalVM distribution by default.
We might be able to provide ConfigurationTool as a separate Maven artifact, or re-implement it entirely using off-the-shelf JSON libraries (like what we are doing in Gradle currently in order to filter out Gradle internal classes that are leaking into configuration).
cc: @peter-hofer
Another consideration is whether we should switch to JAVA_TOOL_OPTIONS environment variable for agent configuration or is the current approach sufficient (e.g. is every JVM process that we spawn configured correctly?). On pro side that would massively simplify Maven configuration (that is currently manipulating xml dom to inject nodes), but this option might (?) be Hotspot specific and could as such prevent things like running tests using Espresso further down the line.