-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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-32289] Programmatic serialization registration from inside features #3050
[GR-32289] Programmatic serialization registration from inside features #3050
Conversation
4dc8d37
to
87a1c27
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please rebase once #3060 is on master
d323592
to
f64be27
Compare
rebased & ready for review |
Current conflicts are caused by the introduction of the serialization-deny-config.json file, and I would like some pointers on what the preferred resolution is, as there are a couple of possibilities:
|
Hi @kkriske
There is no value in adding to the deny-list via Feature API. Passing BTW, I will be off from next week until January. It is very likely I won't find the time to merge this before. |
e238f57
to
acea686
Compare
Should you still find the time, it is again ready for review. Happy holidays. |
0128724
to
561fc00
Compare
|
||
public interface RuntimeSerializationSupport { | ||
|
||
default void register(Class<?>... classes) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having a default method here just to save a few lines of code over here
Line 98 in 561fc00
new SerializationRegistryAdapter((clazz, checkSums) -> deniedClasses.put(clazz, true), imageClassLoader)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/RuntimeSerialization.java
Show resolved
Hide resolved
@@ -209,6 +200,28 @@ static void println(String str) { | |||
System.out.println(str); | |||
// Checkstyle: resume | |||
} | |||
|
|||
private class RuntimeSerializationSupportImpl extends SerializationSupport implements RuntimeSerializationSupport { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RuntimeSerializationSupportImpl
must not be an inner class of hosted class SerializationFeature
. It extends com.oracle.svm.reflect.serialize.SerializationSupport
which holds data that will be part of an image. We do not allow any hosted classes to get built into an image. If you build an image that uses serialization with image builder assertions enabled (native-image -J-ea
) you would run into issues with com.oracle.svm.hosted.NativeImageGenerator#checkName
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is no longer an inner class.
I was however unable to recreate any issues with -J-ea
with the previous implementation, so couldn't check if the current implementation mitigates that issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comments above.
9cef9bd
to
c1e8cfe
Compare
...com.oracle.svm.reflect/src/com/oracle/svm/reflect/serialize/hosted/SerializationFeature.java
Outdated
Show resolved
Hide resolved
...om.oracle.svm.reflect/src/com/oracle/svm/reflect/serialize/hosted/SerializationRegistry.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comments
f1c7dad
to
95dbeae
Compare
@kkriske serialization support got shipped as part of |
@kkriske had to add kkriske@05f48f7 because |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great contribution, thank you!
*/ | ||
|
||
@Platforms(Platform.HOSTED_ONLY.class) | ||
package com.oracle.svm.reflect.serialize.hosted; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this already match our hosted-only package filter?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fine. It's the same as in svm/reflect/proxy/hosted/package-info.java:26
} | ||
} | ||
|
||
@AutomaticFeature |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's dangerous to have a test-specific feature as an @AutomaticFeature
like this because it might be enabled for other tests or on an even broader scope. Please use @RequiredFeatures
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately @RequiredFeatures
is part of com.oracle.svm.enterprise.test.runner.RequiredFeatures
I suggested using @AutomaticFeature
because we are also using it in src/com/oracle/svm/test/NativeImageResourceFileSystemProviderTest.java
.
@kkriske alternatively to @peter-hofer s suggestion we can do the following:
- Remove the
@AutomaticFeature
annotation here - Add
--features=com.oracle.svm.test.SerializationRegistrationTestFeature
toArgs
insubstratevm/src/com.oracle.svm.test/src/META-INF/native-image/com.oracle.svm.test/native-image.properties
This has the same effect as using @AutomaticFeature
without the risk of having that feature enabled in other context then testing.
void registerWithTargetConstructorClass(Class<?> clazz, Class<?> customTargetConstructorClazz); | ||
|
||
void registerWithTargetConstructorClass(String className, String customTargetConstructorClassName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If these are not exposed through RuntimeSerialization
, we should move them to an internal subinterface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kkriske please also add these two to org.graalvm.nativeimage.hosted.RuntimeSerialization
. There are cases were users have to use them and I guess they would be happy if they could it via the API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't the first one be enough? The (String, String)
method is mostly there to facilitate the config files. When called from RuntimeSerialization
it will crash if the String arguments do not resolve to an actual class so you might as well resolve them first before calling the (Class<?>, Class<?>)
version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes the first one is enough.
@kkriske for any new changes on this PR please add new commits instead of rebasing your existing commits so that we can keep track of what was added when by whom. |
@kkriske our CI run found one more issue where I can observe the following stacktrace:
I'm trying to reproduce this locally now. |
Lines 63 to 64 in 1b212eb
Adding a |
Yes that would be preferred. @Override
public int compareTo(SerializationConfigurationType other) {
int res = qualifiedJavaName.compareTo(other.qualifiedJavaName);
if (res != 0) {
return res;
}
Comparator<String> nullsFirstCompare = Comparator.nullsFirst(Comparator.naturalOrder());
return nullsFirstCompare.compare(qualifiedCustomTargetConstructorJavaName, other.qualifiedCustomTargetConstructorJavaName);
} |
…in SerializationConfigurationType sorting
I have no idea what the special case that requires |
E.g. apache.spark makes direct use of ReflectionFactory.newConstructorForSerialization with a customTargetConstructorClass. Providing a test that covers this special case is beyond the scope of this PR. |
@kkriske your PR passed our CI and is now in the merge queue (eta early next week). |
`SerializationRegistry` has been moved from `com.oracle.svm.core.jdk.serialize` to `com.oracle.svm.reflect.serialize` in Graal oracle/graal#3050 Closes quarkusio#19338
`SerializationRegistry` class has been moved from `com.oracle.svm.core.jdk.serialize` to `com.oracle.svm.reflect.serialize` `addReflections` method moved from `com.oracle.svm.reflect.serialize.hosted.SerializationFeature` to `com.oracle.svm.reflect.serialize.hosted.SerializationBuilder` and became `private` See oracle/graal#3050 Note: oracle/graal#3050 also introduces `SerializationFeature.register(Class<?>... classes)` which should be a better alternative to the generated by Quarkus `registerSerializationForClass` method. Closes quarkusio#19338
oracle/graal#3050 introduces a number of changes around the internal APIs that are being used by Quarkus to register classes for serialization thus breaking serialization support when using 21.3-dev These changes are: 1. `SerializationRegistry` class has been moved from `com.oracle.svm.core.jdk.serialize` to `com.oracle.svm.reflect.serialize` 2. `addReflections` method moved from `com.oracle.svm.reflect.serialize.hosted.SerializationFeature` to `com.oracle.svm.reflect.serialize.hosted.SerializationBuilder` and became `private` oracle/graal#3050 also introduces `SerializationFeature.register(Class<?>... classes)` which is available as a public API (not internal) and can save us from having to keep up with the internal APIs as new releases come out. This PR leverages the new API to register classes for serialization when using GraalVM/Mandrel >=21.3. Closes quarkusio#19338
oracle/graal#3050 introduces a number of changes around the internal APIs that are being used by Quarkus to register classes for serialization thus breaking serialization support when using 21.3-dev These changes are: 1. `SerializationRegistry` class has been moved from `com.oracle.svm.core.jdk.serialize` to `com.oracle.svm.reflect.serialize` 2. `addReflections` method moved from `com.oracle.svm.reflect.serialize.hosted.SerializationFeature` to `com.oracle.svm.reflect.serialize.hosted.SerializationBuilder` and became `private` oracle/graal#3050 also introduces `SerializationFeature.register(Class<?>... classes)` which is available as a public API (not internal) and can save us from having to keep up with the internal APIs as new releases come out. This PR leverages the new API to register classes for serialization when using GraalVM/Mandrel >=21.3. Closes quarkusio#19338
oracle/graal#3050 introduces a number of changes around the internal APIs that are being used by Quarkus to register classes for serialization thus breaking serialization support when using 21.3-dev These changes are: 1. `SerializationRegistry` class has been moved from `com.oracle.svm.core.jdk.serialize` to `com.oracle.svm.reflect.serialize` 2. `addReflections` method moved from `com.oracle.svm.reflect.serialize.hosted.SerializationFeature` to `com.oracle.svm.reflect.serialize.hosted.SerializationBuilder` and became `private` oracle/graal#3050 also introduces `SerializationFeature.register(Class<?>... classes)` which is available as a public API (not internal) and can save us from having to keep up with the internal APIs as new releases come out. This PR leverages the new API to register classes for serialization when using GraalVM/Mandrel >=21.3. Closes quarkusio#19338
oracle/graal#3050 introduces a number of changes around the internal APIs that are being used by Quarkus to register classes for serialization thus breaking serialization support when using 21.3-dev These changes are: 1. `SerializationRegistry` class has been moved from `com.oracle.svm.core.jdk.serialize` to `com.oracle.svm.reflect.serialize` 2. `addReflections` method moved from `com.oracle.svm.reflect.serialize.hosted.SerializationFeature` to `com.oracle.svm.reflect.serialize.hosted.SerializationBuilder` and became `private` oracle/graal#3050 also introduces `SerializationFeature.register(Class<?>... classes)` which is available as a public API (not internal) and can save us from having to keep up with the internal APIs as new releases come out. This PR leverages the new API to register classes for serialization when using GraalVM/Mandrel >=21.3. Closes quarkusio#19338 (cherry picked from commit 4921b9f)
RuntimeSerialization#registerIncludingAssociatedClasses was introduced in GraalVM 21.3 by oracle#3050
RuntimeSerialization#registerIncludingAssociatedClasses was introduced in GraalVM 21.3 by #3050
It is only possible to add serialization registrations from
serialization-config.json
files, these changes would add aRuntimeSerialization
class which is accessible from within feature implementations so during image building, classes can be registered for serialization programatically usingRuntimeSerialization.register(YourClass.class)
.This PR does 3 things:
org.example.ClassName[]
instead of[org.example.ClassName;