diff --git a/docs/reference-manual/native-image/BuildOptions.md b/docs/reference-manual/native-image/BuildOptions.md index a5ba94f3c59e..1514266d6c7d 100644 --- a/docs/reference-manual/native-image/BuildOptions.md +++ b/docs/reference-manual/native-image/BuildOptions.md @@ -69,7 +69,6 @@ Run `native-image --help` for help on build options. * `--pgo`: provide a comma-separated list of files from which to read the data collected for Profile-guided optimization of AOT-compiled code (reads from _default.iprof_ if nothing is specified). Each file must contain a single `PGOProfiles` object, serialized in JSON format, optionally compressed by gzip. (Not available in GraalVM Community Edition.) * `--pgo-instrument`: instrument AOT-compiled code to collect data for Profile-guided optimization into the _default.iprof_ file. (Not available in GraalVM Community Edition.) * `--pgo-sampling`: perform profiling by sampling the AOT compiled code to collect data for Profile-guided optimization. (Not available in GraalVM Community Edition.) -* `--report-unsupported-elements-at-runtime`: report the usage of unsupported methods and fields at run time when they are accessed the first time, instead of an error during executable's building * `--shared`: build a shared library * `--silent`: silence build output * `--static`: build a statically-linked executable (requires `libc` and `zlib` static libraries) diff --git a/substratevm/CHANGELOG.md b/substratevm/CHANGELOG.md index 7a000f12ff3d..9e94b2597f85 100644 --- a/substratevm/CHANGELOG.md +++ b/substratevm/CHANGELOG.md @@ -20,6 +20,7 @@ This changelog summarizes major changes to GraalVM Native Image. * (GR-52534) Change the digest (used e.g. for symbol names) from SHA-1 encoded as a hex string (40 bytes) to 128-bit Murmur3 as a Base-62 string (22 bytes). * (GR-52578) Print information about embedded resources into `embedded-resources.json` using the `-H:+GenerateEmbeddedResourcesFile` option. * (GR-51172) Add support to catch OutOfMemoryError exceptions on native image if there is no memory left. +* (GR-43837) `--report-unsupported-elements-at-runtime` is now enabled by default and the option is deprecated. ## GraalVM for JDK 22 (Internal Version 24.0.0) * (GR-48304) Red Hat added support for the JFR event ThreadAllocationStatistics. diff --git a/substratevm/mx.substratevm/mx_substratevm_benchmark.py b/substratevm/mx.substratevm/mx_substratevm_benchmark.py index 12e78a0f4859..f2655a02de1f 100644 --- a/substratevm/mx.substratevm/mx_substratevm_benchmark.py +++ b/substratevm/mx.substratevm/mx_substratevm_benchmark.py @@ -77,12 +77,10 @@ def list_jars(path): io.netty.util.internal.PlatformDependent0,io.netty.util,io.netty.bootstrap,io.netty.channel,io.netty.buffer,io.netty.resolver,io.netty.handler.codec.CodecOutputList' _RENAISSANCE_EXTRA_IMAGE_BUILD_ARGS = { 'als' : [ - '--report-unsupported-elements-at-runtime', force_buildtime_init_slf4j_1_7_73, force_runtime_init_netty_4_1_72 ], 'chi-square' : [ - '--report-unsupported-elements-at-runtime', force_buildtime_init_slf4j_1_7_73, force_buildtime_init_slf4j_1_7_73_spark, force_buildtime_init_netty_4_1_72, @@ -99,12 +97,10 @@ def list_jars(path): force_runtime_init_netty_4_1_72 ], 'log-regression' : [ - '--report-unsupported-elements-at-runtime', force_buildtime_init_slf4j_1_7_73, force_runtime_init_netty_4_1_72 ], 'movie-lens' : [ - '--report-unsupported-elements-at-runtime', force_buildtime_init_slf4j_1_7_73, force_buildtime_init_slf4j_1_7_73_spark, force_buildtime_init_netty_4_1_72, @@ -114,12 +110,10 @@ def list_jars(path): '-H:ReflectionConfigurationFiles=' + movie_lens_reflection_config ], 'dec-tree' : [ - '--report-unsupported-elements-at-runtime', force_buildtime_init_slf4j_1_7_73, force_runtime_init_netty_4_1_72 ], 'page-rank' : [ - '--report-unsupported-elements-at-runtime', force_buildtime_init_slf4j_1_7_73, force_buildtime_init_slf4j_1_7_73_spark, force_buildtime_init_netty_4_1_72, @@ -128,12 +122,10 @@ def list_jars(path): force_runtime_init_slf4j_1_7_73 ], 'naive-bayes' : [ - '--report-unsupported-elements-at-runtime', force_buildtime_init_slf4j_1_7_73, force_runtime_init_netty_4_1_72 ], 'gauss-mix' : [ - '--report-unsupported-elements-at-runtime', force_buildtime_init_slf4j_1_7_73, force_buildtime_init_slf4j_1_7_73_spark, force_buildtime_init_netty_4_1_72, @@ -142,7 +134,6 @@ def list_jars(path): force_runtime_init_slf4j_1_7_73 ], 'neo4j-analytics': [ - '--report-unsupported-elements-at-runtime', force_buildtime_init_slf4j_1_7_73, force_runtime_init_netty_4_1_72 ], @@ -352,8 +343,7 @@ def _empty_file(): 'pmd': [], # org.apache.crimson.parser.Parser2 is force initialized at build-time due to non-determinism in class initialization # order that can lead to runtime issues. See GR-26324. - 'xalan': ['--report-unsupported-elements-at-runtime', - '--initialize-at-build-time=org.apache.crimson.parser.Parser2,org.apache.crimson.parser.Parser2$Catalog,org.apache.crimson.parser.Parser2$NullHandler,org.apache.xml.utils.res.CharArrayWrapper'], + 'xalan': ['--initialize-at-build-time=org.apache.crimson.parser.Parser2,org.apache.crimson.parser.Parser2$Catalog,org.apache.crimson.parser.Parser2$NullHandler,org.apache.xml.utils.res.CharArrayWrapper'], # There are two main issues with fop: # 1. LoggingFeature is enabled by default, causing the LogManager configuration to be parsed at build-time. However # DaCapo Harness sets the `java.util.logging.config.file` property at run-time. Therefore, we set @@ -362,8 +352,7 @@ def _empty_file(): # not exist and would fail the benchmark when assertions are enabled. # 2. Native-image picks a different service provider than the JVM for javax.xml.transform.TransformerFactory. # We can simply remove the jar containing that provider as it is not required for the benchmark to run. - 'fop': ['--report-unsupported-elements-at-runtime', - f"-Djava.util.logging.config.file={_empty_file()}", + 'fop': [f"-Djava.util.logging.config.file={_empty_file()}", '--initialize-at-run-time=org.apache.fop.render.rtf.rtflib.rtfdoc.RtfList'], 'batik': [] } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageOptions.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageOptions.java index 10f0ee1798a3..becf945b942d 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageOptions.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageOptions.java @@ -33,13 +33,7 @@ import java.util.Date; import java.util.concurrent.ForkJoinPool; -import com.oracle.svm.util.LogUtils; import org.graalvm.collections.EconomicMap; -import jdk.graal.compiler.options.Option; -import jdk.graal.compiler.options.OptionKey; -import jdk.graal.compiler.options.OptionStability; -import jdk.graal.compiler.options.OptionValues; -import jdk.graal.compiler.serviceprovider.GraalServices; import com.oracle.graal.pointsto.reports.ReportUtils; import com.oracle.svm.core.SubstrateOptions; @@ -52,8 +46,15 @@ import com.oracle.svm.core.util.UserError; import com.oracle.svm.hosted.classinitialization.ClassInitializationOptions; import com.oracle.svm.hosted.util.CPUType; +import com.oracle.svm.util.LogUtils; import com.oracle.svm.util.StringUtil; +import jdk.graal.compiler.options.Option; +import jdk.graal.compiler.options.OptionKey; +import jdk.graal.compiler.options.OptionStability; +import jdk.graal.compiler.options.OptionValues; +import jdk.graal.compiler.serviceprovider.GraalServices; + public class NativeImageOptions { public static final int DEFAULT_MAX_ANALYSIS_SCALING = 16; @@ -142,9 +143,9 @@ protected void onValueUpdate(EconomicMap, Object> values, Boolean o @Option(help = "Allow MethodTypeFlow to see @Fold methods")// public static final HostedOptionKey AllowFoldMethods = new HostedOptionKey<>(false); - @APIOption(name = "report-unsupported-elements-at-runtime")// - @Option(help = "Report usage of unsupported methods and fields at run time when they are accessed the first time, instead of as an error during image building", type = User)// - public static final HostedOptionKey ReportUnsupportedElementsAtRuntime = new HostedOptionKey<>(false); + @APIOption(name = "report-unsupported-elements-at-runtime", deprecated = "The option is deprecated and will be removed in the future. The use of unsupported elements is always reported at run time.")// + @Option(help = "Report usage of unsupported methods and fields at run time when they are accessed the first time, instead of as an error during image building", type = Debug)// + public static final HostedOptionKey ReportUnsupportedElementsAtRuntime = new HostedOptionKey<>(true); @APIOption(name = "allow-incomplete-classpath", deprecated = "Allowing an incomplete classpath is now the default. Use --link-at-build-time to report linking errors at image build time for a class or package.")// @Option(help = "Deprecated", type = User)// diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/AnnotationSubstitutionProcessor.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/AnnotationSubstitutionProcessor.java index 29f9d731b83f..507ca45ea482 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/AnnotationSubstitutionProcessor.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/AnnotationSubstitutionProcessor.java @@ -585,23 +585,35 @@ private static boolean hasDefaultValue(Field annotatedField) { private void handleDeletedClass(Class originalClass, Delete deleteAnnotation) { if (NativeImageOptions.ReportUnsupportedElementsAtRuntime.getValue()) { + ResolvedJavaType type = metaAccess.lookupJavaType(originalClass); + + try { + type.link(); + } catch (LinkageError ignored) { + /* + * Ignore any linking errors. A type that cannot be linked doesn't need elements + * replaced: it will simply fail at runtime with the same linkage error before + * reaching those elements. + */ + return; + } + /* * We register all methods and fields as deleted. That still allows usage of the type in * type checks. */ - for (Executable m : originalClass.getDeclaredMethods()) { - ResolvedJavaMethod method = metaAccess.lookupJavaMethod(m); + for (ResolvedJavaMethod method : type.getDeclaredMethods()) { registerAsDeleted(null, method, deleteAnnotation); } - for (Executable m : originalClass.getDeclaredConstructors()) { - ResolvedJavaMethod method = metaAccess.lookupJavaMethod(m); - registerAsDeleted(null, method, deleteAnnotation); + for (ResolvedJavaMethod constructor : type.getDeclaredConstructors()) { + registerAsDeleted(null, constructor, deleteAnnotation); } - for (Field f : originalClass.getDeclaredFields()) { - ResolvedJavaField field = metaAccess.lookupJavaField(f); - registerAsDeleted(null, field, deleteAnnotation); + for (ResolvedJavaField f : type.getInstanceFields(false)) { + registerAsDeleted(null, f, deleteAnnotation); + } + for (ResolvedJavaField f : type.getStaticFields()) { + registerAsDeleted(null, f, deleteAnnotation); } - } else { deleteAnnotations.put(metaAccess.lookupJavaType(originalClass), deleteAnnotation); }