Skip to content

[GR-57814] Prevent emission of typeReachable in reachability-metadata.json #9664

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

Closed
wants to merge 6 commits into from
Closed
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
2 changes: 2 additions & 0 deletions substratevm/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ This changelog summarizes major changes to GraalVM Native Image.
* (GR-49770) Add support for glob patterns in resource-config files in addition to regexp. The Tracing Agent now prints entries in the glob format.
* (GR-46386) Throw missing registration errors for JNI queries when the query was not included in the reachability metadata.
* (GR-51479) Implement cgroup support in native code. See the [README](src/com.oracle.svm.native.libcontainer/README.md) and the [PR description](https://github.com/oracle/graal/pull/8989).
* (GR-54241) Streamline Native Image reachability metadata into a single `reachability-metadata.json`. The formerly-used individual metadata files (`reflection-config.json`, `resource-config.json`, etc.) are now deprecated, but will still be accepted.
Native Image will only output `reachability-metadata.json` files, and those will be readable on the previous LTS versions of GraalVM. See the [documentation](../docs/reference-manual/native-image/ReachabilityMetadata.md).

## GraalVM for JDK 22 (Internal Version 24.0.0)
* (GR-48304) Red Hat added support for the JFR event ThreadAllocationStatistics.
Expand Down
5 changes: 4 additions & 1 deletion substratevm/mx.substratevm/mx_substratevm.py
Original file line number Diff line number Diff line change
Expand Up @@ -1285,7 +1285,9 @@ def _native_image_launcher_extra_jvm_args():
build_args=driver_build_args + [
'--features=com.oracle.svm.agent.NativeImageAgent$RegistrationFeature',
'--enable-url-protocols=jar',
],
] + svm_experimental_options([
'-H:+TreatAllTypeReachableConditionsAsTypeReached',
]),
headers=False,
home_finder=False,
),
Expand Down Expand Up @@ -1574,6 +1576,7 @@ def _native_image_configure_extra_jvm_args():
main_class='com.oracle.svm.configure.ConfigurationTool',
build_args=svm_experimental_options([
'-H:-ParseRuntimeOptions',
'-H:+TreatAllTypeReachableConditionsAsTypeReached',
]),
extra_jvm_args=_native_image_configure_extra_jvm_args(),
home_finder=False,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,14 @@
import jdk.graal.compiler.util.json.JsonWriter;

final class ConfigurationConditionPrintable {
static void printConditionAttribute(UnresolvedConfigurationCondition condition, JsonWriter writer) throws IOException {
static void printConditionAttribute(UnresolvedConfigurationCondition condition, JsonWriter writer, boolean combinedFile) throws IOException {
if (!condition.isAlwaysTrue()) {
writer.quote(CONDITIONAL_KEY).appendFieldSeparator().appendObjectStart();
writer.quote(condition.isRuntimeChecked() ? TYPE_REACHED_KEY : TYPE_REACHABLE_KEY).appendFieldSeparator().quote(condition.getTypeName());
/*
* typeReachable conditions are emitted as typeReached in reachability-metadata.json.
* typeReached conditions are emitted as typeReachable in resource-config.json
*/
writer.quote(combinedFile ? TYPE_REACHED_KEY : TYPE_REACHABLE_KEY).appendFieldSeparator().quote(condition.getTypeName());
writer.appendObjectEnd().appendSeparator();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ public synchronized void setAllPublicConstructors(ConfigurationMemberAccessibili
@Override
public synchronized void printJson(JsonWriter writer) throws IOException {
writer.appendObjectStart();
ConfigurationConditionPrintable.printConditionAttribute(condition, writer);
ConfigurationConditionPrintable.printConditionAttribute(condition, writer, true);
writer.quote("type").appendFieldSeparator();
typeDescriptor.printJson(writer);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,73 +103,73 @@ public void registerConstructor(UnresolvedConfigurationCondition condition, bool

@Override
public void registerPublicClasses(UnresolvedConfigurationCondition condition, ConfigurationType type) {
VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type");
VMError.guarantee(condition.isAlwaysTrue() || condition.equals(type.getCondition()), "condition is already a part of the type");
type.setAllPublicClasses();
}

@Override
public void registerDeclaredClasses(UnresolvedConfigurationCondition condition, ConfigurationType type) {
VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type");
VMError.guarantee(condition.isAlwaysTrue() || condition.equals(type.getCondition()), "condition is already a part of the type");
type.setAllDeclaredClasses();
}

@Override
public void registerRecordComponents(UnresolvedConfigurationCondition condition, ConfigurationType type) {
VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type");
VMError.guarantee(condition.isAlwaysTrue() || condition.equals(type.getCondition()), "condition is already a part of the type");
type.setAllRecordComponents();
}

@Override
public void registerPermittedSubclasses(UnresolvedConfigurationCondition condition, ConfigurationType type) {
VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type");
VMError.guarantee(condition.isAlwaysTrue() || condition.equals(type.getCondition()), "condition is already a part of the type");
type.setAllPermittedSubclasses();
}

@Override
public void registerNestMembers(UnresolvedConfigurationCondition condition, ConfigurationType type) {
VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type");
VMError.guarantee(condition.isAlwaysTrue() || condition.equals(type.getCondition()), "condition is already a part of the type");
type.setAllNestMembers();
}

@Override
public void registerSigners(UnresolvedConfigurationCondition condition, ConfigurationType type) {
VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type");
VMError.guarantee(condition.isAlwaysTrue() || condition.equals(type.getCondition()), "condition is already a part of the type");
type.setAllSigners();
}

@Override
public void registerPublicFields(UnresolvedConfigurationCondition condition, boolean queriedOnly, ConfigurationType type) {
VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type");
VMError.guarantee(condition.isAlwaysTrue() || condition.equals(type.getCondition()), "condition is already a part of the type");
type.setAllPublicFields(queriedOnly ? ConfigurationMemberAccessibility.QUERIED : ConfigurationMemberAccessibility.ACCESSED);
}

@Override
public void registerDeclaredFields(UnresolvedConfigurationCondition condition, boolean queriedOnly, ConfigurationType type) {
VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type");
VMError.guarantee(condition.isAlwaysTrue() || condition.equals(type.getCondition()), "condition is already a part of the type");
type.setAllDeclaredFields(queriedOnly ? ConfigurationMemberAccessibility.QUERIED : ConfigurationMemberAccessibility.ACCESSED);
}

@Override
public void registerPublicMethods(UnresolvedConfigurationCondition condition, boolean queriedOnly, ConfigurationType type) {
VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type");
VMError.guarantee(condition.isAlwaysTrue() || condition.equals(type.getCondition()), "condition is already a part of the type");
type.setAllPublicMethods(queriedOnly ? ConfigurationMemberAccessibility.QUERIED : ConfigurationMemberAccessibility.ACCESSED);
}

@Override
public void registerDeclaredMethods(UnresolvedConfigurationCondition condition, boolean queriedOnly, ConfigurationType type) {
VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type");
VMError.guarantee(condition.isAlwaysTrue() || condition.equals(type.getCondition()), "condition is already a part of the type");
type.setAllDeclaredMethods(queriedOnly ? ConfigurationMemberAccessibility.QUERIED : ConfigurationMemberAccessibility.ACCESSED);
}

@Override
public void registerPublicConstructors(UnresolvedConfigurationCondition condition, boolean queriedOnly, ConfigurationType type) {
VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type");
VMError.guarantee(condition.isAlwaysTrue() || condition.equals(type.getCondition()), "condition is already a part of the type");
type.setAllPublicConstructors(queriedOnly ? ConfigurationMemberAccessibility.QUERIED : ConfigurationMemberAccessibility.ACCESSED);
}

@Override
public void registerDeclaredConstructors(UnresolvedConfigurationCondition condition, boolean queriedOnly, ConfigurationType type) {
VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type");
VMError.guarantee(condition.isAlwaysTrue() || condition.equals(type.getCondition()), "condition is already a part of the type");
type.setAllDeclaredConstructors(queriedOnly ? ConfigurationMemberAccessibility.QUERIED : ConfigurationMemberAccessibility.ACCESSED);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,25 +110,30 @@ public void printJson(JsonWriter writer) throws IOException {
public static void printProxyInterfaces(JsonWriter writer, List<ConditionalElement<List<String>>> lists) throws IOException {
lists.sort(ConditionalElement.comparator(ProxyConfiguration::compareList));

writer.append('[');
writer.indent();
String prefix = "";
writer.appendArrayStart();
boolean firstProxy = true;
for (ConditionalElement<List<String>> list : lists) {
writer.append(prefix).newline();
writer.append('{').indent().newline();
ConfigurationConditionPrintable.printConditionAttribute(list.condition(), writer);
writer.quote("interfaces").append(":").append('[');
String typePrefix = "";
if (firstProxy) {
firstProxy = false;
} else {
writer.appendSeparator();
}
writer.appendObjectStart();
ConfigurationConditionPrintable.printConditionAttribute(list.condition(), writer, false);
writer.quote("interfaces").appendFieldSeparator().appendArrayStart();
boolean firstType = true;
for (String type : list.element()) {
writer.append(typePrefix).quote(type);
typePrefix = ",";
if (firstType) {
firstType = false;
} else {
writer.appendSeparator();
}
writer.quote(type);
}
writer.append(']').unindent().newline();
writer.append('}');
prefix = ",";
writer.appendArrayEnd();
writer.appendObjectEnd();
}
writer.unindent().newline();
writer.append(']');
writer.appendArrayEnd();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -342,19 +342,19 @@ public boolean anyBundleMatches(UnresolvedConfigurationCondition condition, Stri
@Override
public void printJson(JsonWriter writer) throws IOException {
printGlobsJson(writer, true);
writer.appendSeparator().newline();
printBundlesJson(writer);
writer.appendSeparator();
printBundlesJson(writer, true);
}

@Override
public void printLegacyJson(JsonWriter writer) throws IOException {
writer.appendObjectStart().indent().newline();
writer.appendObjectStart();
printResourcesJson(writer);
writer.appendSeparator().newline();
printBundlesJson(writer);
writer.appendSeparator().newline();
writer.appendSeparator();
printBundlesJson(writer, false);
writer.appendSeparator();
printGlobsJson(writer, false);
writer.unindent().newline().appendObjectEnd();
writer.appendObjectEnd();
}

void printResourcesJson(JsonWriter writer) throws IOException {
Expand All @@ -369,24 +369,24 @@ void printResourcesJson(JsonWriter writer) throws IOException {
writer.appendObjectEnd();
}

void printBundlesJson(JsonWriter writer) throws IOException {
void printBundlesJson(JsonWriter writer, boolean combinedFile) throws IOException {
writer.quote(BUNDLES_KEY).appendFieldSeparator();
JsonPrinter.printCollection(writer, bundles.keySet(), ConditionalElement.comparator(), (p, w) -> printResourceBundle(bundles.get(p), w));
JsonPrinter.printCollection(writer, bundles.keySet(), ConditionalElement.comparator(), (p, w) -> printResourceBundle(bundles.get(p), w, combinedFile));
}

void printGlobsJson(JsonWriter writer, boolean useResourcesFieldName) throws IOException {
writer.quote(useResourcesFieldName ? RESOURCES_KEY : GLOBS_KEY).appendFieldSeparator();
JsonPrinter.printCollection(writer, addedGlobs, ConditionalElement.comparator(ResourceEntry.comparator()), ResourceConfiguration::conditionalGlobElementJson);
void printGlobsJson(JsonWriter writer, boolean combinedFile) throws IOException {
writer.quote(combinedFile ? RESOURCES_KEY : GLOBS_KEY).appendFieldSeparator();
JsonPrinter.printCollection(writer, addedGlobs, ConditionalElement.comparator(ResourceEntry.comparator()), (p, w) -> conditionalGlobElementJson(p, w, combinedFile));
}

@Override
public ConfigurationParser createParser(boolean strictMetadata) {
return ResourceConfigurationParser.create(strictMetadata, ConfigurationConditionResolver.identityResolver(), new ResourceConfiguration.ParserAdapter(this), true);
}

private static void printResourceBundle(BundleConfiguration config, JsonWriter writer) throws IOException {
private static void printResourceBundle(BundleConfiguration config, JsonWriter writer, boolean combinedFile) throws IOException {
writer.appendObjectStart();
ConfigurationConditionPrintable.printConditionAttribute(config.condition, writer);
ConfigurationConditionPrintable.printConditionAttribute(config.condition, writer, combinedFile);
writer.quote("name").appendFieldSeparator().quote(config.baseName);
if (!config.locales.isEmpty()) {
writer.appendSeparator().quote("locales").appendFieldSeparator();
Expand Down Expand Up @@ -417,11 +417,11 @@ public boolean supportsCombinedFile() {
return true;
}

private static void conditionalGlobElementJson(ConditionalElement<ResourceEntry> p, JsonWriter w) throws IOException {
private static void conditionalGlobElementJson(ConditionalElement<ResourceEntry> p, JsonWriter w, boolean combinedFile) throws IOException {
String pattern = p.element().pattern();
String module = p.element().module();
w.appendObjectStart();
ConfigurationConditionPrintable.printConditionAttribute(p.condition(), w);
ConfigurationConditionPrintable.printConditionAttribute(p.condition(), w, combinedFile);
if (module != null) {
w.quote("module").appendFieldSeparator().quote(module).appendSeparator();
}
Expand All @@ -431,7 +431,7 @@ private static void conditionalGlobElementJson(ConditionalElement<ResourceEntry>

private static void conditionalRegexElementJson(ConditionalElement<String> p, JsonWriter w) throws IOException {
w.appendObjectStart();
ConfigurationConditionPrintable.printConditionAttribute(p.condition(), w);
ConfigurationConditionPrintable.printConditionAttribute(p.condition(), w, false);
w.quote("pattern").appendFieldSeparator().quote(p.element());
w.appendObjectEnd();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public String getQualifiedJavaName() {
@Override
public void printJson(JsonWriter writer) throws IOException {
writer.append('{').indent().newline();
ConfigurationConditionPrintable.printConditionAttribute(condition, writer);
ConfigurationConditionPrintable.printConditionAttribute(condition, writer, false);

writer.quote(SerializationConfigurationParser.NAME_KEY).append(":").quote(qualifiedJavaName);
writer.unindent().newline().append('}');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
import jdk.graal.compiler.util.json.JsonPrintable;
import jdk.graal.compiler.util.json.JsonWriter;

import static com.oracle.svm.core.configure.ConfigurationParser.NAME_KEY;
import static com.oracle.svm.core.configure.ConfigurationParser.TYPE_KEY;

public class SerializationConfigurationType implements JsonPrintable, Comparable<SerializationConfigurationType> {
private final UnresolvedConfigurationCondition condition;
private final String qualifiedJavaName;
Expand Down Expand Up @@ -66,17 +69,17 @@ public UnresolvedConfigurationCondition getCondition() {

@Override
public void printJson(JsonWriter writer) throws IOException {
printJson(writer, SerializationConfigurationParser.TYPE_KEY);
printJson(writer, true);
}

public void printLegacyJson(JsonWriter writer) throws IOException {
printJson(writer, SerializationConfigurationParser.NAME_KEY);
printJson(writer, false);
}

private void printJson(JsonWriter writer, String key) throws IOException {
private void printJson(JsonWriter writer, boolean combinedFile) throws IOException {
writer.appendObjectStart();
ConfigurationConditionPrintable.printConditionAttribute(condition, writer);
writer.quote(key).appendFieldSeparator().quote(qualifiedJavaName);
ConfigurationConditionPrintable.printConditionAttribute(condition, writer, combinedFile);
writer.quote(combinedFile ? TYPE_KEY : NAME_KEY).appendFieldSeparator().quote(qualifiedJavaName);
if (qualifiedCustomTargetConstructorJavaName != null) {
writer.appendSeparator();
writer.quote(SerializationConfigurationParser.CUSTOM_TARGET_CONSTRUCTOR_CLASS_KEY).appendFieldSeparator()
Expand Down
Loading