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

Allow serialization of anonymous and local classes #298

Closed
GoogleCodeExporter opened this issue Mar 19, 2015 · 17 comments
Closed

Allow serialization of anonymous and local classes #298

GoogleCodeExporter opened this issue Mar 19, 2015 · 17 comments

Comments

@GoogleCodeExporter
Copy link

What steps will reproduce the problem?

        Gson gson = new Gson();
        String json = gson.toJson(new Object() {
            String url = "http://localhost:10080/live/list";
            String[] names = new String[] {"dsc0001","dsc0002","dsc0003"};
        });
        System.out.println(json);

What is the expected output?
{"url":"http://localhost:10080/live/list","name":[{"dsc0001","dsc0002","dsc0003"
]}

What do you see instead?
blank line

What version of the product are you using? On what operating system?
1.6

Please provide any additional information below.
I understand that there are default exclusion strategies that prevent the 
serialization of objects belonging to an anonymous or local class, but it would 
be great if these could be bypassed to allow the above notation.


Original issue reported on code.google.com by robby...@gmail.com on 17 Mar 2011 at 2:14

@GoogleCodeExporter
Copy link
Author

I have the same doubt. Are there any specific reasons why anonymous or local 
classes should be excluded?

I tried to disable the DEFAULT_ANON_LOCAL_CLASS_EXCLUSION_STRATEGY. It does not 
seem producing any problems

Original comment by lindap...@gmail.com on 14 Apr 2011 at 2:43

@GoogleCodeExporter
Copy link
Author

And inner class will trigger problems using a type adapter is specified for the 
class since it generated an implicit reference to the outer class/instance 
which causes a circular reference. I do not recall the reason as to why we skip 
anonymous classes.

I will discuss this with Inder, but I do think that this is a valid feature 
that we should support.

Original comment by joel.leitch@gmail.com on 16 Apr 2011 at 5:59

@GoogleCodeExporter
Copy link
Author

Issue 196 has been merged into this issue.

Original comment by joel.leitch@gmail.com on 16 Apr 2011 at 9:54

@GoogleCodeExporter
Copy link
Author

Issue 346 has been merged into this issue.

Original comment by limpbizkit on 2 Oct 2011 at 3:38

@GoogleCodeExporter
Copy link
Author

I respectfully disagree.

I'm doing something like this.

I have an interface, TFlat. I registered a custom serializer for that interface.

I have:

class O {
  TFlat p = new TFlat(){ int field1 = 3; int field2 = 4; }
  ...
}

And I'm trying to serialize an instance of O.

May be the exclusion strategy should pass out anonymous/local classes that 
would have be serialized in a custom way?

Thanks,
  Pawel.

Original comment by pawel.ve...@gmail.com on 12 Jan 2012 at 8:58

@GoogleCodeExporter
Copy link
Author

Pawel, that's interesting I'll take a look. What do you think should happen 
when this is deserialized?

Original comment by limpbizkit on 13 Jan 2012 at 2:35

@GoogleCodeExporter
Copy link
Author

Jesse,

I don't think this is particularly useful for deserializing.
If we were to stretch this, deserialization can see that the field is 
initialized, and if the incoming JSON fragment is an object, map the properties 
of the fragment to the fields of the object. IMO, right now, GSon always 
attempts to instantiate classes that are declared for each field (or use a 
custom deserializer to do so).

custom deserialization can create its own anonymous class that will implement 
TFlat. It would need to know the field location (somehow indicate where the 
field will go after deserialization), though, which is, to my knowledge, is not 
something GSon supports either. But I'm still on 1.7, haven't checked out all 
the 2.x goodies.


Original comment by pawel.ve...@gmail.com on 13 Jan 2012 at 5:02

@GoogleCodeExporter
Copy link
Author

[deleted comment]

@GoogleCodeExporter
Copy link
Author

Interestingly enough, you can create instances of anonymous objects.
However, such instances will not be "attached" to the outer class, yet they are 
legal. Attempting to reference parent class will simply return null. Obvious 
problem is, of course, that there is no way to declare a field of anonymous 
class.

Here is the Groovy fragment I ran to test this:


interface T {
}
class P {
  int out = 13;
  T z = new T() {
    int k;
    {
        System.out.println("Anonymous <init>...");
        P parent = P.this;
        if (parent == null) { System.out.println("No Parent!"); }
        else { System.out.println(parent.out) }; 
    }
  };
}
P p = new P();
Class<T> cc = p.z.getClass();
System.out.println(cc.getName());
T another = cc.newInstance();
---
output:
Anonymous <init>...
13
P$1
Anonymous <init>...
No Parent!
Result: P$1@1567ee3

Original comment by pawel.ve...@gmail.com on 13 Jan 2012 at 5:10

@GoogleCodeExporter
Copy link
Author

Original comment by limpbizkit on 11 Apr 2012 at 8:50

  • Added labels: Type-Enhancement
  • Removed labels: Type-Defect

@GoogleCodeExporter
Copy link
Author

We still use gson-1.3 due to this issue...

Today I found http://code.google.com/p/google-gson/issues/detail?id=96 in our 
logs.
The bug fixed in 1.4++, but we can't move to fresh version of gson since we 
have a lot of inner/local classes to serialize.



Original comment by stanisla...@gmail.com on 22 Jan 2013 at 12:02

@GoogleCodeExporter
Copy link
Author

Same here. Even though I love GSON simplicity and extensibility, but inability 
to serialize anonymous classes simply kills the practical usability of this 
great library!

The use case I'm talking about is very simple and widely used. Image you have 
class Car:
public class Car {
   String name;
   String color;
}

Let's create 2 instances using different code-style:

   Car car1 = new Car();
   car1.name = "BMW";
   car1.color = "Red";

   Car car2 = new Car() {{
      name = "Nissan";
      color = "Gold";
   }}

car2 object has the same number of fields and from logical perspective it is of 
the same type than car1. The anonymous Car subclass created for the car2 
instance can be safely ignored in this case as it doesn't add anything to the 
car2 that car1 wouldn't have. So why would Gson refuse processing car2?

Original comment by alexande...@gmail.com on 6 Feb 2013 at 5:24

@GoogleCodeExporter
Copy link
Author

Don't use double brace initialization. It prevents serialization and Gson is 
designed for symmetric serialization and serialization.

Original comment by limpbizkit on 7 Feb 2013 at 1:02

  • Changed state: WontFix

@GoogleCodeExporter
Copy link
Author

jackson can do this:
        ObjectMapper mapper = new ObjectMapper();
        mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
        String result=mapper.writeValueAsString(x);
why gson not?

Original comment by che...@gmail.com on 21 Nov 2013 at 2:55

@codeblooded
Copy link

I see this closed, but I don't see a reason. Can we reopen or provide clarification? It sounds like this thread seemed in overwhelming support for anonymous class serialization.

@mintern
Copy link

mintern commented Aug 8, 2018

This is especially problematic with Java 8. I've tried to create a TypeAdapterFactory for serializing Streams, but my create method never even gets called because ReferencePipeline$2 is anonymous, so the Excluder just returns null.

@lyubomyr-shaydariv
Copy link
Contributor

@mintern

This is especially problematic with Java 8. I've tried to create a TypeAdapterFactory for serializing Streams, but my create method never even gets called because ReferencePipeline$2 is anonymous, so the Excluder just returns null.

It should work if you provide a type to the toJson() method:

... = gson.toJson(stringStream, new TypeToken<Stream<String>>() {}.getType());

I think that this issue should be reopened, because it's possible to serialize and deserialize an anonymous/local class object, if the class does not have its outer class reference this$0, for example, if declared in a static method (don't think it has much practical use, though).

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

No branches or pull requests

4 participants