Skip to content
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

Enhance message system with StaticType #1289

Draft
wants to merge 4 commits into
base: develop
Choose a base branch
from

Conversation

AutonomicPerfectionist
Copy link
Contributor

@AutonomicPerfectionist AutonomicPerfectionist commented May 24, 2023

This PR enhances the messaging system with the new StaticType class. It allows sendBlocking() return values to be deserialized to the expected return type, simultaneously type-checking the return value. An example:

Currently, to call a remote method and get the return value you would do something like this:

List<Registration> registrations = (List<Registration>) sendBlocking("runtime", "getServiceList");

Assuming getServiceList() returned the expected list, this would work just fine thanks to the virtual class field embedded in the JSON. However, if this method changed to return a list of ServiceInterface or something, this would still succeed since casting can't check generics at runtime. It would only blow up upon accessing the list, with a ClassCastException, potentially several message hops away.

Now, one would do this:

List<Registration> registrations = sendBlocking("runtime", "getServiceList", new StaticType<>(){});

Note the lack of a cast and the new StaticType parameter. This "reifies" the expected return type, allowing it to be accessed at runtime. It is then accessed by CodecUtils when deserializing a message, informing the deserializer of the requested type. If the object is not of the expected return type (or an allowed alternative like a subclass), then the deserialization fails. This ensures we don't pass bad data around before crashing with a hard-to-debug ClassCastException

Fixes #1226

NOTE:
This does not work for return types with non-concrete generic parameters. For example:

List<T> registrations = sendBlocking("runtime", "getServiceList", new StaticType<>(){});

This will fail even if T is defined by a class or method generic parameter. This is because StaticType cannot reify non-concrete generic type parameters even if they are defined somewhere else.

I also do not know how wildcards will function with this. For example:

List<? extends Registration> registrations = sendBlocking("runtime", "getServiceList", new StaticType<>(){});

This may or may not fail, but if it does fail, it will do so during construction of the StaticType. More testing is needed for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Edge case in virtual class field deserialization
1 participant