Skip to content

Commit 70044a1

Browse files
committed
Predicated serialization configuration
1 parent fa44a85 commit 70044a1

File tree

15 files changed

+136
-112
lines changed

15 files changed

+136
-112
lines changed

sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/RuntimeSerialization.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import org.graalvm.nativeimage.ImageSingletons;
4444
import org.graalvm.nativeimage.Platform;
4545
import org.graalvm.nativeimage.Platforms;
46+
import org.graalvm.nativeimage.impl.ConfigurationPredicate;
4647
import org.graalvm.nativeimage.impl.RuntimeSerializationSupport;
4748

4849
/**
@@ -60,7 +61,7 @@ public final class RuntimeSerialization {
6061
* @since 21.3
6162
*/
6263
public static void register(Class<?>... classes) {
63-
ImageSingletons.lookup(RuntimeSerializationSupport.class).register(classes);
64+
ImageSingletons.lookup(RuntimeSerializationSupport.class).register(ConfigurationPredicate.objectPredicate(), classes);
6465
}
6566

6667
/**
@@ -75,7 +76,7 @@ public static void register(Class<?>... classes) {
7576
* @since 21.3
7677
*/
7778
public static void registerWithTargetConstructorClass(Class<?> clazz, Class<?> customTargetConstructorClazz) {
78-
ImageSingletons.lookup(RuntimeSerializationSupport.class).registerWithTargetConstructorClass(clazz, customTargetConstructorClazz);
79+
ImageSingletons.lookup(RuntimeSerializationSupport.class).registerWithTargetConstructorClass(ConfigurationPredicate.objectPredicate(), clazz, customTargetConstructorClazz);
7980
}
8081

8182
private RuntimeSerialization() {

sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/ConfigurationPredicate.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242

4343
import java.util.Objects;
4444

45-
public final class ConfigurationPredicate {
45+
public final class ConfigurationPredicate implements Comparable<ConfigurationPredicate> {
4646
private final String typeName;
4747
private static final ConfigurationPredicate OBJECT_PREDICATE = new ConfigurationPredicate(Object.class.getTypeName());
4848

@@ -51,6 +51,7 @@ public static ConfigurationPredicate objectPredicate() {
5151
}
5252

5353
public static ConfigurationPredicate create(String typeReachability) {
54+
Objects.requireNonNull(typeReachability);
5455
if (OBJECT_PREDICATE.typeName.equals(typeReachability)) {
5556
return OBJECT_PREDICATE;
5657
}
@@ -82,4 +83,8 @@ public int hashCode() {
8283
return Objects.hash(typeName);
8384
}
8485

86+
@Override
87+
public int compareTo(ConfigurationPredicate o) {
88+
return this.typeName.compareTo(o.typeName);
89+
}
8590
}

sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/RuntimeSerializationSupport.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,10 @@
4242

4343
public interface RuntimeSerializationSupport {
4444

45-
void register(Class<?>... classes);
45+
void register(ConfigurationPredicate predicate, Class<?>... classes);
4646

47-
void registerWithTargetConstructorClass(Class<?> clazz, Class<?> customTargetConstructorClazz);
47+
void registerWithTargetConstructorClass(ConfigurationPredicate predicate, Class<?> clazz, Class<?> customTargetConstructorClazz);
48+
49+
void registerWithTargetConstructorClass(ConfigurationPredicate predicate, String className, String customTargetConstructorClassName);
4850

49-
void registerWithTargetConstructorClass(String className, String customTargetConstructorClassName);
5051
}

substratevm/src/com.oracle.svm.configure.test/src/com/oracle/svm/configure/test/config/OmitPreviousConfigTests.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,9 @@ private static void doTestResourceConfig(ResourceConfiguration resourceConfig) {
195195
}
196196

197197
private static void doTestSerializationConfig(SerializationConfiguration serializationConfig) {
198-
Assert.assertFalse(serializationConfig.contains("seenType", null));
199-
Assert.assertTrue(serializationConfig.contains("unseenType", null));
198+
ConfigurationPredicate predicate = ConfigurationPredicate.objectPredicate();
199+
Assert.assertFalse(serializationConfig.contains(predicate, "seenType", null));
200+
Assert.assertTrue(serializationConfig.contains(predicate, "unseenType", null));
200201
}
201202

202203
private static ConfigurationType getConfigTypeOrFail(TypeConfiguration typeConfig, String typeName) {

substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ConfigurationPredicatePrintable.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
*/
2525
package com.oracle.svm.configure.config;
2626

27+
import static com.oracle.svm.core.configure.ConfigurationParser.PREDICATE_KEY;
28+
import static com.oracle.svm.core.configure.ConfigurationParser.TYPE_REACHABLE_KEY;
29+
2730
import java.io.IOException;
2831

2932
import org.graalvm.nativeimage.impl.ConfigurationPredicate;
@@ -33,8 +36,8 @@
3336
final class ConfigurationPredicatePrintable {
3437
static void printPredicateAttribute(ConfigurationPredicate predicate, JsonWriter writer) throws IOException {
3538
if (!predicate.equals(ConfigurationPredicate.objectPredicate())) {
36-
writer.append("\"predicate\":{");
37-
writer.append("\"whenTypeReachable\":").quote(predicate.getTypeName());
39+
writer.quote(PREDICATE_KEY).append(":{");
40+
writer.quote(TYPE_REACHABLE_KEY).append(':').quote(predicate.getTypeName());
3841
writer.append("},").newline();
3942
}
4043
}

substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/SerializationConfiguration.java

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,11 @@
3232
import java.util.Set;
3333
import java.util.concurrent.ConcurrentHashMap;
3434

35+
import org.graalvm.nativeimage.impl.ConfigurationPredicate;
36+
import org.graalvm.nativeimage.impl.RuntimeSerializationSupport;
37+
3538
import com.oracle.svm.configure.ConfigurationBase;
3639
import com.oracle.svm.configure.json.JsonWriter;
37-
import org.graalvm.nativeimage.impl.RuntimeSerializationSupport;
3840

3941
public class SerializationConfiguration implements ConfigurationBase, RuntimeSerializationSupport {
4042

@@ -51,8 +53,8 @@ public void removeAll(SerializationConfiguration other) {
5153
serializations.removeAll(other.serializations);
5254
}
5355

54-
public boolean contains(String serializationTargetClass, String customTargetConstructorClass) {
55-
return serializations.contains(createConfigurationType(serializationTargetClass, customTargetConstructorClass));
56+
public boolean contains(ConfigurationPredicate predicate, String serializationTargetClass, String customTargetConstructorClass) {
57+
return serializations.contains(createConfigurationType(predicate, serializationTargetClass, customTargetConstructorClass));
5658
}
5759

5860
@Override
@@ -71,30 +73,30 @@ public void printJson(JsonWriter writer) throws IOException {
7173
}
7274

7375
@Override
74-
public void register(Class<?>... classes) {
76+
public void register(ConfigurationPredicate predicate, Class<?>... classes) {
7577
for (Class<?> clazz : classes) {
76-
registerWithTargetConstructorClass(clazz, null);
78+
registerWithTargetConstructorClass(predicate, clazz, null);
7779
}
7880
}
7981

8082
@Override
81-
public void registerWithTargetConstructorClass(Class<?> clazz, Class<?> customTargetConstructorClazz) {
82-
registerWithTargetConstructorClass(clazz.getName(), customTargetConstructorClazz == null ? null : customTargetConstructorClazz.getName());
83+
public void registerWithTargetConstructorClass(ConfigurationPredicate predicate, Class<?> clazz, Class<?> customTargetConstructorClazz) {
84+
registerWithTargetConstructorClass(predicate, clazz.getName(), customTargetConstructorClazz == null ? null : customTargetConstructorClazz.getName());
8385
}
8486

8587
@Override
86-
public void registerWithTargetConstructorClass(String className, String customTargetConstructorClassName) {
87-
serializations.add(createConfigurationType(className, customTargetConstructorClassName));
88+
public void registerWithTargetConstructorClass(ConfigurationPredicate predicate, String className, String customTargetConstructorClassName) {
89+
serializations.add(createConfigurationType(predicate, className, customTargetConstructorClassName));
8890
}
8991

9092
@Override
9193
public boolean isEmpty() {
9294
return serializations.isEmpty();
9395
}
9496

95-
private static SerializationConfigurationType createConfigurationType(String className, String customTargetConstructorClassName) {
97+
private static SerializationConfigurationType createConfigurationType(ConfigurationPredicate predicate, String className, String customTargetConstructorClassName) {
9698
String convertedClassName = SignatureUtil.toInternalClassName(className);
9799
String convertedCustomTargetConstructorClassName = customTargetConstructorClassName == null ? null : SignatureUtil.toInternalClassName(customTargetConstructorClassName);
98-
return new SerializationConfigurationType(convertedClassName, convertedCustomTargetConstructorClassName);
100+
return new SerializationConfigurationType(predicate, convertedClassName, convertedCustomTargetConstructorClassName);
99101
}
100102
}

substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/SerializationConfigurationType.java

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,39 +24,37 @@
2424
*/
2525
package com.oracle.svm.configure.config;
2626

27-
import com.oracle.svm.configure.json.JsonPrintable;
28-
import com.oracle.svm.configure.json.JsonWriter;
29-
import com.oracle.svm.core.configure.SerializationConfigurationParser;
30-
3127
import java.io.IOException;
3228
import java.util.Comparator;
3329
import java.util.Objects;
3430

35-
public class SerializationConfigurationType implements JsonPrintable, Comparable<SerializationConfigurationType> {
31+
import org.graalvm.nativeimage.impl.ConfigurationPredicate;
3632

33+
import com.oracle.svm.configure.json.JsonPrintable;
34+
import com.oracle.svm.configure.json.JsonWriter;
35+
import com.oracle.svm.core.configure.SerializationConfigurationParser;
36+
37+
public class SerializationConfigurationType implements JsonPrintable, Comparable<SerializationConfigurationType> {
38+
private final ConfigurationPredicate predicate;
3739
private final String qualifiedJavaName;
3840
private final String qualifiedCustomTargetConstructorJavaName;
3941

40-
public SerializationConfigurationType(String qualifiedJavaName, String qualifiedCustomTargetConstructorJavaName) {
42+
public SerializationConfigurationType(ConfigurationPredicate predicate, String qualifiedJavaName, String qualifiedCustomTargetConstructorJavaName) {
4143
assert qualifiedJavaName.indexOf('/') == -1 : "Requires qualified Java name, not internal representation";
4244
assert !qualifiedJavaName.startsWith("[") : "Requires Java source array syntax, for example java.lang.String[]";
4345
assert qualifiedCustomTargetConstructorJavaName == null || qualifiedCustomTargetConstructorJavaName.indexOf('/') == -1 : "Requires qualified Java name, not internal representation";
4446
assert qualifiedCustomTargetConstructorJavaName == null || !qualifiedCustomTargetConstructorJavaName.startsWith("[") : "Requires Java source array syntax, for example java.lang.String[]";
47+
Objects.requireNonNull(predicate);
48+
this.predicate = predicate;
49+
Objects.requireNonNull(qualifiedJavaName);
4550
this.qualifiedJavaName = qualifiedJavaName;
4651
this.qualifiedCustomTargetConstructorJavaName = qualifiedCustomTargetConstructorJavaName;
4752
}
4853

49-
public String getQualifiedJavaName() {
50-
return qualifiedJavaName;
51-
}
52-
53-
public String getQualifiedCustomTargetConstructorJavaName() {
54-
return qualifiedCustomTargetConstructorJavaName;
55-
}
56-
5754
@Override
5855
public void printJson(JsonWriter writer) throws IOException {
5956
writer.append('{').indent().newline();
57+
ConfigurationPredicatePrintable.printPredicateAttribute(predicate, writer);
6058
writer.quote(SerializationConfigurationParser.NAME_KEY).append(':').quote(qualifiedJavaName);
6159
if (qualifiedCustomTargetConstructorJavaName != null) {
6260
writer.append(',').newline();
@@ -75,13 +73,14 @@ public boolean equals(Object o) {
7573
return false;
7674
}
7775
SerializationConfigurationType that = (SerializationConfigurationType) o;
78-
return Objects.equals(qualifiedJavaName, that.qualifiedJavaName) &&
76+
return predicate.equals(that.predicate) &&
77+
qualifiedJavaName.equals(that.qualifiedJavaName) &&
7978
Objects.equals(qualifiedCustomTargetConstructorJavaName, that.qualifiedCustomTargetConstructorJavaName);
8079
}
8180

8281
@Override
8382
public int hashCode() {
84-
return Objects.hash(qualifiedJavaName, qualifiedCustomTargetConstructorJavaName);
83+
return Objects.hash(predicate, qualifiedJavaName, qualifiedCustomTargetConstructorJavaName);
8584
}
8685

8786
@Override
@@ -90,6 +89,10 @@ public int compareTo(SerializationConfigurationType other) {
9089
if (compareName != 0) {
9190
return compareName;
9291
}
92+
int comparePredicate = predicate.compareTo(other.predicate);
93+
if (comparePredicate != 0) {
94+
return comparePredicate;
95+
}
9396
Comparator<String> nullsFirstCompare = Comparator.nullsFirst(Comparator.naturalOrder());
9497
return nullsFirstCompare.compare(qualifiedCustomTargetConstructorJavaName, other.qualifiedCustomTargetConstructorJavaName);
9598
}

substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/TypeConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public ConfigurationType getOrCreateType(ConfigurationPredicate predicate, Strin
8383
@Override
8484
public void printJson(JsonWriter writer) throws IOException {
8585
List<ConfigurationType> typesList = new ArrayList<>(this.types.values());
86-
typesList.sort(Comparator.comparing(ConfigurationType::getQualifiedJavaName));
86+
typesList.sort(Comparator.comparing(ConfigurationType::getQualifiedJavaName).thenComparing(ConfigurationType::getPredicate));
8787

8888
writer.append('[');
8989
String prefix = "";

substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/trace/SerializationProcessor.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import java.util.List;
2929
import java.util.Map;
3030

31+
import org.graalvm.nativeimage.impl.ConfigurationPredicate;
32+
3133
import com.oracle.svm.configure.config.SerializationConfiguration;
3234

3335
public class SerializationProcessor extends AbstractProcessor {
@@ -46,6 +48,7 @@ public SerializationConfiguration getSerializationConfiguration() {
4648
@Override
4749
void processEntry(Map<String, ?> entry) {
4850
boolean invalidResult = Boolean.FALSE.equals(entry.get("result"));
51+
ConfigurationPredicate predicate = ConfigurationPredicate.objectPredicate();
4952
if (invalidResult) {
5053
return;
5154
}
@@ -58,7 +61,7 @@ void processEntry(Map<String, ?> entry) {
5861
return;
5962
}
6063

61-
serializationConfiguration.registerWithTargetConstructorClass((String) args.get(0), (String) args.get(1));
64+
serializationConfiguration.registerWithTargetConstructorClass(predicate, (String) args.get(0), (String) args.get(1));
6265
}
6366
}
6467
}

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

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,13 @@
3636
import java.util.Map;
3737
import java.util.Set;
3838

39+
import org.graalvm.nativeimage.impl.ConfigurationPredicate;
40+
3941
import com.oracle.svm.core.util.json.JSONParserException;
4042

4143
public abstract class ConfigurationParser {
44+
public static final String PREDICATE_KEY = "predicate";
45+
public static final String TYPE_REACHABLE_KEY = "whenTypeReachable";
4246
private final Map<String, Set<String>> seenUnknownAttributesByType = new HashMap<>();
4347
private final boolean strictConfiguration;
4448

@@ -97,7 +101,7 @@ protected void warnOrFail(String message) {
97101
throw new JSONParserException(message);
98102
} else {
99103
// Checkstyle: stop
100-
System.err.println("WARNING: " + message);
104+
System.err.println("Warning: " + message);
101105
// Checkstyle: resume
102106
}
103107
}
@@ -140,4 +144,19 @@ protected static long asLong(Object value, String propertyName) {
140144
}
141145
throw new JSONParserException("Invalid long value '" + value + "' for element '" + propertyName + "'");
142146
}
147+
148+
protected ConfigurationPredicate parsePredicate(Map<String, Object> data) {
149+
Object predicateData = data.get(PREDICATE_KEY);
150+
if (predicateData != null) {
151+
Map<String, Object> predicateObject = asMap(predicateData, "Attribute 'predicate' must be an object");
152+
Object predicateType = predicateObject.get(TYPE_REACHABLE_KEY);
153+
if (predicateType instanceof String) {
154+
return ConfigurationPredicate.create((String) predicateType);
155+
} else {
156+
warnOrFail("'" + TYPE_REACHABLE_KEY + "' should be of type string");
157+
}
158+
}
159+
return ConfigurationPredicate.objectPredicate();
160+
}
161+
143162
}

0 commit comments

Comments
 (0)