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

Throw exception when serializing or deserializing anonymous or local classes #2189

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

Marcono1234
Copy link
Collaborator

@Marcono1234 Marcono1234 commented Sep 2, 2022

Resolves #1510 (but does not implement that feature request)

Backward incompatible changes:

  • Previously Gson did not throw an exception but simply used null; this was pretty error-prone and difficult to debug for users.
    With these changes it is still possible to achieve this behavior by registering a custom ExclusionStrategy which excludes anonymous and local classes.
  • Previously Gson ignored whether the type had a custom adapter registered; now Gson only throws an exception when no adapter has been registered and reflection would be used.
    This behavior seems reasonable because the issue with anonymous and local classes exists only for reflection-based serialization and deserialization. For what it's worth, this now also supports serializing anonymous classes created with "double brace initialization" (let's not discuss here though whether that concept is a good idea).
    Note that this differs from the intended behavior shown by the tests added by b0531e1. Maybe it wasn't even explicitly intended this way back then, but just happened to behave like this because annonymous and local class handling was implemented for the Excluder.

…classes

Backward incompatible changes:
- Previously Gson did not throw an exception but simply used null; this was
  pretty error-prone and difficult to debug for users
- Previously Gson ignored whether the type had a custom adapter registered;
  now Gson only throws an exception when no adapter has been registered and
  reflection would be used
@@ -155,7 +155,8 @@ BagOfPrimitives obj2 = gson.fromJson(json, BagOfPrimitives.class);
* While serializing, a null field is omitted from the output.
* While deserializing, a missing entry in JSON results in setting the corresponding field in the object to its default value: null for object types, zero for numeric types, and false for booleans.
* If a field is _synthetic_, it is ignored and not included in JSON serialization or deserialization.
* Fields corresponding to the outer classes in inner classes, anonymous classes, and local classes are ignored and not included in serialization or deserialization.
* Fields corresponding to the outer classes in inner classes are ignored and not included in serialization or deserialization.
* Reflection-based serialization and deserialization of anonymous and local classes is not supported; an exception will be thrown. Convert the classes to `static` nested classes or register a custom `TypeAdapter` for them to enable serialization and deserialization.

### <a name="TOC-Nested-Classes-including-Inner-Classes-"></a>Nested Classes (including Inner Classes)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The notes below for non-static inner classes a few lines below are a bit incorrect, should they be adjusted?

@@ -291,7 +291,20 @@ public GsonBuilder enableComplexMapKeySerialization() {
}

/**
* Configures Gson to exclude inner classes during serialization.
* Configures Gson to exclude inner classes (= non-{@code static} nested classes) during serialization
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interestingly this method affects both serialization and deserialization.

}

@Override public void write(JsonWriter out, T value) throws IOException {
throw new UnsupportedOperationException("Serialization of anonymous or local class " + type.getName() + " is not supported. "
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if UnsupportedOperationException fits well here. Ideally we should really create a proper exception hierarchy for Gson at some point.

At least the exact exception type is not specified so I guess we can change it later, if necessary.

Comment on lines 31 to 23
public class FieldExclusionTest extends TestCase {
public class InnerClassesTest extends TestCase {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed this because it only seems to cover inner classes.

Comment on lines +117 to +118
} catch (JsonSyntaxException e) {
fail("Unexpected exception; test has to be run with `--illegal-access=deny`");
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not directly related to this PR, but it makes test failures for this test method when not running with --illegal-access=deny easier to understand.

@eamonnmcmanus
Copy link
Member

Thanks for this! I commented at length in #1510. In short, I don't think we'll be able to make this change as is.

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.

Allow serialization of anonymous classes
2 participants