Skip to content

Commit c71766b

Browse files
committed
Fix error messages for JSON config
1 parent f760369 commit c71766b

File tree

5 files changed

+73
-52
lines changed

5 files changed

+73
-52
lines changed

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ConfigurationFiles.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,12 @@ public static final class Options {
8181
public static final HostedOptionKey<LocatableMultiOptionValue.Strings> SerializationDenyConfigurationResources = new HostedOptionKey<>(
8282
LocatableMultiOptionValue.Strings.buildWithCommaDelimiter());
8383

84-
@Option(help = "Files describing Java resources to be included in the image.", type = OptionType.User)//
84+
@Option(help = "Files describing Java resources to be included in the image according to the schema at " +
85+
"https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/assets/resource-config-schema-v1.0.0.json", type = OptionType.User)//
8586
@BundleMember(role = BundleMember.Role.Input)//
8687
public static final HostedOptionKey<LocatableMultiOptionValue.Paths> ResourceConfigurationFiles = new HostedOptionKey<>(LocatableMultiOptionValue.Paths.buildWithCommaDelimiter());
87-
@Option(help = "Resources describing Java resources to be included in the image.", type = OptionType.User)//
88+
@Option(help = "Resources describing Java resources to be included in the image according to the schema at " +
89+
"https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/assets/resource-config-schema-v1.0.0.json", type = OptionType.User)//
8890
public static final HostedOptionKey<LocatableMultiOptionValue.Strings> ResourceConfigurationResources = new HostedOptionKey<>(LocatableMultiOptionValue.Strings.buildWithCommaDelimiter());
8991

9092
@Option(help = "Files describing program elements to be made accessible via JNI (for syntax, see ReflectionConfigurationFiles)", type = OptionType.User)//
@@ -93,18 +95,20 @@ public static final class Options {
9395
@Option(help = "Resources describing program elements to be made accessible via JNI (see JNIConfigurationFiles).", type = OptionType.User)//
9496
public static final HostedOptionKey<LocatableMultiOptionValue.Strings> JNIConfigurationResources = new HostedOptionKey<>(LocatableMultiOptionValue.Strings.buildWithCommaDelimiter());
9597

96-
@Option(help = "Files describing predefined classes that can be loaded at runtime.", type = OptionType.User)//
98+
@Option(help = "Files describing predefined classes that can be loaded at runtime according to the schema at " +
99+
"https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/assets/predefined-classes-config-schema-v1.0.0.json", type = OptionType.User)//
97100
@BundleMember(role = BundleMember.Role.Input)//
98101
public static final HostedOptionKey<LocatableMultiOptionValue.Paths> PredefinedClassesConfigurationFiles = new HostedOptionKey<>(LocatableMultiOptionValue.Paths.buildWithCommaDelimiter());
99-
@Option(help = "Resources describing predefined classes that can be loaded at runtime.", type = OptionType.User)//
102+
@Option(help = "Resources describing predefined classes that can be loaded at runtime according to the schema at " +
103+
"https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/assets/predefined-classes-config-schema-v1.0.0.json", type = OptionType.User)//
100104
public static final HostedOptionKey<LocatableMultiOptionValue.Strings> PredefinedClassesConfigurationResources = new HostedOptionKey<>(
101105
LocatableMultiOptionValue.Strings.buildWithCommaDelimiter());
102106

103-
@Option(help = "When configuration files don't match the schema, abort the image build instead of emitting a warning.")//
107+
@Option(help = "When configuration files do not match their schema, abort the image build instead of emitting a warning.")//
104108
public static final HostedOptionKey<Boolean> StrictConfiguration = new HostedOptionKey<>(false);
105109

106-
@Option(help = "When configuration files don't match the schema, abort the image build instead of emitting a warning.", type = OptionType.Expert)//
107-
public static final HostedOptionKey<Boolean> PrintMissingMetadataElements = new HostedOptionKey<>(false);
110+
@Option(help = "Warn when reflection and JNI configuration files have elements that could not be found on the classpath or modulepath.", type = OptionType.Expert)//
111+
public static final HostedOptionKey<Boolean> WarnAboutMissingReflectionOrJNIMetadataElements = new HostedOptionKey<>(false);
108112
}
109113

110114
public static List<Path> findConfigurationFiles(String fileName) {
Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,26 @@
11
One or several (comma-separated) paths to JSON files that specify lists of interfaces that define Java proxy classes.
2-
The structure is an array of arrays of fully qualified interface names.
2+
The JSON structure is described in the following schema:
33

4-
Example:
4+
https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/assets/proxy-config-schema-v1.0.0.json
5+
6+
An example file contents follows:
57

68
[
7-
["java.lang.AutoCloseable", "java.util.Comparator"],
8-
["java.util.Comparator"],
9-
["java.util.List"]
9+
{
10+
"condition" : {
11+
"typeReachable" : "org.example.CallingClass"
12+
},
13+
"interfaces" : [
14+
"java.lang.AutoCloseable",
15+
"java.util.Comparator"
16+
]
17+
},
18+
{
19+
"condition" : {
20+
"typeReachable" : "org.example.CallingClass"
21+
},
22+
"interfaces" : [
23+
"java.util.Comparator"
24+
]
25+
}
1026
]

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/doc-files/ReflectionConfigurationFilesHelp.txt

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,25 @@
11
One or several (comma-separated) paths to JSON files that specify which program elements should be made available via reflection.
2-
The JSON object schema is:
2+
The JSON object schema is described at:
33

4-
{
5-
String name; // fully qualified class name
6-
boolean allDeclaredConstructors; // include all declared constructors, see Class.getDeclaredConstructors()
7-
boolean allPublicConstructors; // include all public constructors, see Class.getConstructors()
8-
boolean allDeclaredMethods; // include all declared methods, see Class.getDeclaredMethods()
9-
boolean allPublicMethods; // include all public methods, see Class.getMethods()
10-
boolean allDeclaredFields; // include all declared fields, see Class.getDeclaredFields()
11-
boolean allPublicFields; // include all public fields, see Class.getFields()
12-
{
13-
String name; // method name
14-
String[] parameterTypes; // parameter types (optional, use if ambiguous)
15-
}[] methods;
16-
{
17-
String name; // field name
18-
}[] fields;
19-
}[];
4+
https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/assets/reflect-config-schema-v1.0.0.json
205

216
Example:
227

238
[
249
{
10+
"condition" : {
11+
"typeReachable" : "org.example.CallingClass"
12+
},
2513
"name" : "java.lang.Class",
2614
"allDeclaredConstructors" : "true",
2715
"allPublicConstructors" : "true",
2816
"allDeclaredMethods" : "true",
2917
"allPublicMethods" : "true"
3018
},
3119
{
20+
"condition" : {
21+
"typeReachable" : "org.example.CallingClass"
22+
},
3223
"name" : "java.lang.String",
3324
"fields" : [
3425
{ "name" : "value" },
@@ -42,6 +33,9 @@ Example:
4233
]
4334
},
4435
{
36+
"condition" : {
37+
"typeReachable" : "org.example.CallingClass"
38+
},
4539
"name" : "java.lang.String$CaseInsensitiveComparator",
4640
"methods" : [
4741
{ "name" : "compare" }
Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,31 @@
11
One or several (comma-separated) paths to JSON files that specify lists of serialization configurations.
2-
The structure is an array of elements specifying the target serialization/deserialization class.
2+
The structure is described in the following schema:
3+
4+
https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/assets/serialization-config-schema-v1.0.0.json
35

46
Example:
57

68
[
79
{
8-
"condition":{"typeReachable":"app.DataSerializer"},
9-
"name":"java.util.ArrayList"
10+
"condition" : {
11+
"typeReachable" : "app.DataSerializer"
12+
},
13+
"name" : "java.util.ArrayList"
1014
}
1115
]
1216

1317
For deserializing lambda classes, the capturing class of the lambda needs to be specified in a separate section of the configuration file, for example:
1418

1519
[
16-
"types": [
17-
{"name":"java.lang.Object"}
20+
"types" : [
21+
{
22+
"name" : "java.lang.Object"
23+
}
1824
],
19-
"lambdaCapturingTypes": [
20-
{"name":"java.util.Comparator"}
25+
"lambdaCapturingTypes" : [
26+
{
27+
"name" : "java.util.Comparator"
28+
}
2129
]
2230
]
2331

@@ -35,8 +43,10 @@ serialization-config.json:
3543

3644
[
3745
{
38-
"condition":{"typeReachable":"org.apache.spark.SparkContext"},
39-
"name":"org.apache.spark.SparkContext$$anonfun$hadoopFile$1",
40-
"customTargetConstructorClass":"java.lang.Object"
46+
"condition" : {
47+
"typeReachable" : "org.apache.spark.SparkContext"
48+
},
49+
"name" : "org.apache.spark.SparkContext$$anonfun$hadoopFile$1",
50+
"customTargetConstructorClass" : "java.lang.Object"
4151
}
4252
]

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/config/ConfigurationParserUtils.java

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424
*/
2525
package com.oracle.svm.hosted.config;
2626

27-
import static com.oracle.svm.common.option.CommonOptions.PrintFlags;
28-
2927
import java.io.IOException;
3028
import java.net.URI;
3129
import java.net.URISyntaxException;
@@ -49,7 +47,6 @@
4947
import com.oracle.svm.core.configure.ReflectionConfigurationParser;
5048
import com.oracle.svm.core.option.HostedOptionKey;
5149
import com.oracle.svm.core.option.LocatableMultiOptionValue;
52-
import com.oracle.svm.core.option.SubstrateOptionsParser;
5350
import com.oracle.svm.core.util.UserError;
5451
import com.oracle.svm.hosted.ImageClassLoader;
5552

@@ -58,8 +55,7 @@ public final class ConfigurationParserUtils {
5855
public static ReflectionConfigurationParser<ConditionalElement<Class<?>>> create(ReflectionRegistry registry, ImageClassLoader imageClassLoader) {
5956
return new ReflectionConfigurationParser<>(RegistryAdapter.create(registry, imageClassLoader),
6057
ConfigurationFiles.Options.StrictConfiguration.getValue(),
61-
ConfigurationFiles.Options.PrintMissingMetadataElements.getValue()
62-
);
58+
ConfigurationFiles.Options.WarnAboutMissingReflectionOrJNIMetadataElements.getValue());
6359
}
6460

6561
/**
@@ -76,12 +72,11 @@ public static int parseAndRegisterConfigurations(ConfigurationParser parser, Ima
7672

7773
List<Path> paths = configFilesOption.getValue().values();
7874
List<String> resourceValues = configResourcesOption.getValue().values();
79-
var configFilesOptionName = configFilesOption.getName();
80-
return parseAndRegisterConfigurations(parser, classLoader, featureName, configFilesOptionName, configResourcesOption.getName(), directoryFileName, paths, resourceValues);
75+
return parseAndRegisterConfigurations(parser, classLoader, featureName, directoryFileName, paths, resourceValues);
8176
}
8277

8378
public static int parseAndRegisterConfigurations(ConfigurationParser parser, ImageClassLoader classLoader,
84-
String featureName, String configFilesOptionName, String configResourcesOptionName,
79+
String featureName,
8580
String directoryFileName, List<Path> paths,
8681
List<String> resourceValues) {
8782
int parsedCount = 0;
@@ -91,7 +86,7 @@ public static int parseAndRegisterConfigurations(ConfigurationParser parser, Ima
9186
if (!Files.exists(path)) {
9287
throw UserError.abort("The %s configuration file \"%s\" does not exist.", featureName, path);
9388
}
94-
doParseAndRegister(parser, featureName, path, configFilesOptionName);
89+
doParseAndRegister(parser, featureName, path);
9590
return 1;
9691
}).sum();
9792

@@ -118,13 +113,13 @@ public boolean tryAdvance(Consumer<? super URL> action) {
118113
});
119114
Stream<URL> resources = Stream.concat(configResourcesFromOption, ConfigurationFiles.findConfigurationResources(directoryFileName, classLoader.getClassLoader()).stream());
120115
parsedCount += resources.mapToInt(url -> {
121-
doParseAndRegister(parser, featureName, url, configResourcesOptionName);
116+
doParseAndRegister(parser, featureName, url);
122117
return 1;
123118
}).sum();
124119
return parsedCount;
125120
}
126121

127-
private static void doParseAndRegister(ConfigurationParser parser, String featureName, Object location, String optionName) {
122+
private static void doParseAndRegister(ConfigurationParser parser, String featureName, Object location) {
128123
try {
129124
URI uri;
130125
if (location instanceof Path) {
@@ -138,8 +133,10 @@ private static void doParseAndRegister(ConfigurationParser parser, String featur
138133
if (errorMessage == null || errorMessage.isEmpty()) {
139134
errorMessage = e.toString();
140135
}
141-
throw UserError.abort("Error parsing %s configuration in %s:%n%s%nVerify that the configuration matches the schema described in the %s output for option %s.",
142-
featureName, location, errorMessage, SubstrateOptionsParser.commandArgument(PrintFlags, "+"), optionName);
136+
throw UserError.abort(
137+
"Error parsing %s configuration in %s:%n%s%nVerify that the configuration matches the corresponding schema at " +
138+
"https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/assets/",
139+
featureName, location, errorMessage);
143140
}
144141
}
145142
}

0 commit comments

Comments
 (0)