Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GR-52314] Make MissingRegistrationReportingMode a runtime option #8473

Merged
merged 1 commit into from
Mar 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions docs/reference-manual/native-image/ReachabilityMetadata.md
Original file line number Diff line number Diff line change
Expand Up @@ -468,14 +468,14 @@ The Native Image agent does not support custom implementations of `ResourceBundl

This mode will be made the default behavior of Native Image in a future release. We encourage you to start transitioning your code as soon as possible.
The [Native Image agent](AutomaticMetadataCollection.md) outputs JSON files that conform to both the default and strict modes of operation.
The following options are useful for debugging issues during the transition to the strict mode:

* `-H:ThrowMissingRegistrationErrors=<package list>`: limits `MissingReflectionRegistrationError` to be thrown from a defined list of packages.
This is useful when using some library code that has not been ported to the new mode yet;
* `-H:MissingRegistrationReportingMode`: sets how `MissingReflectionRegistrationError` is reported:
* `Throw` is the default. The error is simply thrown as a Java exception;
* `Warn` outputs a small stack trace for every error encountered, which results in a report of all the places the tested code is going to throw when the strict mode is enabled;
* `Exit` exits the program when encountering the error. This is useful to detect blanket `catch (Throwable t) {` blocks that would otherwise silence the error.
Native Image also provides some useful options for debugging issues during the transition to the strict mode:

* To make sure that the reflection for your image is configured correctly you can add `-H:ThrowMissingRegistrationErrors=` to the native-image build arguments.
If the resulting image fails in libraries that are not under your control, you can add a package prefix to the option to limit the errors to operations called from classes within the specified packages: `-H:ThrowMissingRegistrationErrors=<package-prefix>`.
* The default behavior under `-H:ThrowMissingRegistrationErrors=` is to throw an error, which will potentially end the program execution.
To get an overview of all places in your code where missing registrations occur, including a small stack trace, without committing to the strict behavior you can add `-XX:MissingRegistrationReportingMode=Warn` to the program invocation.
To detect places where the application accidentally swallows a missing registration error (such as with blanket `catch (Throwable t)` blocks), you can add `-XX:MissingRegistrationReportingMode=Exit` to the program invocation.
The application will then unconditionally print the error message and stack trace and exit immediately without throwing.

### Further Reading

Expand Down
1 change: 1 addition & 0 deletions substratevm/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ This changelog summarizes major changes to GraalVM Native Image.
* (GR-47712) Using the `--static` option without the `--libc=musl` option causes the build process to fail (and reports the appropriate error). Static linking is currently only supported with musl.
* (GR-50434) Introduce a `"type"` field in reflection and JNI configuration files to support more than simple named types.
* (GR-51053) Use [`vswhere`](https://github.com/microsoft/vswhere) to find Visual Studio installations more reliably and in non-standard installation locations.
* (GR-52314) `-XX:MissingRegistrationReportingMode` can now be used on program invocation instead of as a build option, to avoid a rebuild when debugging missing registration errors.

## GraalVM for JDK 22 (Internal Version 24.0.0)
* (GR-48304) Red Hat added support for the JFR event ThreadAllocationStatistics.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,10 @@
*/
package com.oracle.svm.core;

import static com.oracle.svm.core.SubstrateOptions.ReportingMode.Warn;

import java.io.Serial;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;

import com.oracle.svm.core.util.ExitStatus;

Expand All @@ -46,7 +45,7 @@ public static SubstrateOptions.ReportingMode missingRegistrationReportingMode()

private static final int CONTEXT_LINES = 4;

private static final Set<String> seenOutputs = SubstrateOptions.MissingRegistrationReportingMode.getValue() == Warn ? ConcurrentHashMap.newKeySet() : null;
private static final AtomicReference<Set<String>> seenOutputs = new AtomicReference<>(null);

public static void report(Error exception, StackTraceElement responsibleClass) {
if (responsibleClass != null && !MissingRegistrationSupport.singleton().reportMissingRegistrationErrors(responsibleClass)) {
Expand Down Expand Up @@ -93,13 +92,13 @@ public static void report(Error exception, StackTraceElement responsibleClass) {
break;
}
}
if (seenOutputs.isEmpty()) {
if (seenOutputs.get() == null && seenOutputs.compareAndSet(null, ConcurrentHashMap.newKeySet())) {
/* First output, we print an explanation message */
System.out.println("Note: this run will print partial stack traces of the locations where a " + exception.getClass().toString() + " would be thrown " +
"when the -H:+ThrowMissingRegistrationErrors option is set. The trace stops at the first entry of JDK code and provides " + CONTEXT_LINES + " lines of context.");
}
String output = sb.toString();
if (seenOutputs.add(output)) {
if (seenOutputs.get().add(output)) {
System.out.print(output);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1041,7 +1041,7 @@ public enum ReportingMode {
"\"Throw\" (default): Throw a MissingReflectionRegistrationError;",
"\"Exit\": Call System.exit() to avoid accidentally catching the error;",
"\"Warn\": Print a message to stdout, including a stack trace to see what caused the issue."})//
public static final HostedOptionKey<ReportingMode> MissingRegistrationReportingMode = new HostedOptionKey<>(
public static final RuntimeOptionKey<ReportingMode> MissingRegistrationReportingMode = new RuntimeOptionKey<>(
ReportingMode.Throw);

@Option(help = "Instead of warning, throw IOExceptions for link-at-build-time resources at build time")//
Expand Down