discomarathon / google-gson

Automatically exported from code.google.com/p/google-gson
0 stars 0 forks source link

ClassCastException in TypeInfoFactory #102

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Getting exception when trying to jsonify a internally created object. Stack
trace is 

java.lang.ClassCastException: java.lang.Class cannot be cast to
java.lang.reflect.ParameterizedType
    at com.google.gson.TypeInfoFactory.getActualType(TypeInfoFactory.java:91)
    at com.google.gson.TypeInfoFactory.extractRealTypes(TypeInfoFactory.java:110)
    at com.google.gson.TypeInfoFactory.getActualType(TypeInfoFactory.java:65)
    at
com.google.gson.TypeInfoFactory.getTypeInfoForField(TypeInfoFactory.java:54)
    at
com.google.gson.ObjectNavigator.navigateClassFields(ObjectNavigator.java:166)
    at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:151)
    at
com.google.gson.JsonSerializationVisitor.getJsonElementForChild(JsonSerializatio
nVisitor.java:163)
    at
com.google.gson.JsonSerializationVisitor.addAsChildOfObject(JsonSerializationVis
itor.java:137)
    at
com.google.gson.JsonSerializationVisitor.visitObjectField(JsonSerializationVisit
or.java:132)
    at
com.google.gson.ObjectNavigator.navigateClassFields(ObjectNavigator.java:179)
    at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:151)
    at
com.google.gson.JsonSerializationVisitor.getJsonElementForChild(JsonSerializatio
nVisitor.java:163)
    at
com.google.gson.JsonSerializationVisitor.addAsChildOfObject(JsonSerializationVis
itor.java:137)
    at
com.google.gson.JsonSerializationVisitor.visitObjectField(JsonSerializationVisit
or.java:132)
    at
com.google.gson.ObjectNavigator.navigateClassFields(ObjectNavigator.java:179)
    at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:151)
    at
com.google.gson.JsonSerializationVisitor.getJsonElementForChild(JsonSerializatio
nVisitor.java:163)
    at
com.google.gson.JsonSerializationVisitor.addAsArrayElement(JsonSerializationVisi
tor.java:150)
    at
com.google.gson.JsonSerializationVisitor.visitCollection(JsonSerializationVisito
r.java:78)
    at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:137)
    at
com.google.gson.JsonSerializationVisitor.getJsonElementForChild(JsonSerializatio
nVisitor.java:163)
    at
com.google.gson.JsonSerializationVisitor.addAsChildOfObject(JsonSerializationVis
itor.java:137)
    at
com.google.gson.JsonSerializationVisitor.visitCollectionField(JsonSerializationV
isitor.java:103)
    at
com.google.gson.ObjectNavigator.navigateClassFields(ObjectNavigator.java:174)
    at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:151)
    at
com.google.gson.JsonSerializationVisitor.getJsonElementForChild(JsonSerializatio
nVisitor.java:163)
    at
com.google.gson.JsonSerializationVisitor.addAsChildOfObject(JsonSerializationVis
itor.java:137)
    at
com.google.gson.JsonSerializationVisitor.visitObjectField(JsonSerializationVisit
or.java:132)
    at
com.google.gson.ObjectNavigator.navigateClassFields(ObjectNavigator.java:179)
    at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:151)
    at
com.google.gson.JsonSerializationContextDefault.serialize(JsonSerializationConte
xtDefault.java:47)
    at com.google.gson.Gson.toJson(Gson.java:273)
    at com.google.gson.Gson.toJson(Gson.java:229)
    at com.google.gson.Gson.toJson(Gson.java:209)
    at com.company.it.widgetserver.AjaxServlet.doGet(AjaxServlet.java:138)

What steps will reproduce the problem?
Create classes with generics and try to convert to json

What version of the product are you using? On what operating system?
Tried with 1.3, 1.2.3, 1.2.2 and still getting same error.  It is on Windows.

Original issue reported on code.google.com by brsan...@gmail.com on 19 Feb 2009 at 8:07

GoogleCodeExporter commented 9 years ago
Please post a code sample that we can use to reproduce this problem.

Original comment by inder123 on 11 Mar 2009 at 9:56

GoogleCodeExporter commented 9 years ago
Is this related to Issue #40?

Original comment by joel.leitch@gmail.com on 12 Mar 2009 at 5:35

GoogleCodeExporter commented 9 years ago
I've got the same error with class: 

public class BaseEvent<C extends IContent> implements IEvent<C> {
    //private static final Log log = LogFactory.getLog( BaseEvent.class );

    private final long timestamp;
    private Severity severity;
    private final C content;
    private transient final Object source;
    private final Tag tag;

    public BaseEvent( final Tag tag,
                      final Severity severity,
                      final C content,
                      final Object source,
                      final long timestamp ) {
        if ( tag == null ) {
            throw new IllegalArgumentException( "Type can't be null" );
        }
        if ( severity == null ) {
            throw new IllegalArgumentException( "Severity can't be null" );
        }
        if ( source == null ) {
            throw new IllegalArgumentException( "Source can't be null" );
        }

        this.tag = tag;
        this.severity = severity;
        this.content = content;
        this.source = source;
        this.timestamp = timestamp;
    }

    public BaseEvent( final Tag tag,
                      final Severity severity,
                      final C content,
                      final Object source ) {
        this( tag, severity, content, source, System.currentTimeMillis() );
    }

    public Tag getTag() {
        return tag;
    }

    public long getTimestamp() {
        return timestamp;
    }

    public Severity getSeverity() {
        return severity;
    }

    public synchronized void promote( final Severity s ) {
        if ( s.more( severity ) ) {
            severity = s;
        }
    }

    public C getContent() {
        return content;
    }

    public Object getSource() {
        return source;
    }

    public String toString() {
        final StringBuilder sb = new StringBuilder();
        sb.append( "Event[" );
        sb.append( tag ).append( "; " );
        sb.append( severity ).append( "; " );
        sb.append( new Date( timestamp ) );
        sb.append( "]\n" );
        sb.append( content );
        return sb.toString();
    }
}

Original comment by chere...@gmail.com on 1 Apr 2009 at 7:25

GoogleCodeExporter commented 9 years ago
We have enough tests that use similar kind of types in Gson. See
http://code.google.com/p/google-gson/source/browse/trunk/gson/src/test/java/com/
google/gson/functional/ParameterizedTypesTest.java
for examples. 

I also took the specified test and ran it without any problems. One thing to 
note is
that if you are directly serializing/deserializing an instance of BaseEvent 
then you
need to pass the correct parameterized type using the TypeToken idiom. See
http://sites.google.com/site/gson/gson-user-guide#TOC-Serializing-and-Deserializ
ing-Gener
for examples.

Original comment by inder123 on 1 Apr 2009 at 10:17

GoogleCodeExporter commented 9 years ago
r415 includes a fix to show a more helpful message when this situation occurs.

Original comment by inder123 on 1 Apr 2009 at 10:27

GoogleCodeExporter commented 9 years ago
Well, may be it is not right place to ask, but I do not really understand why I 
require to specify additional params just to serialize generalized type. JS is 
easy 
typed, why you need so much type info to serialize to it? Is it any option to 
serialize "by real type", as if all generics are converted to their <?> version?

Original comment by chere...@gmail.com on 8 Apr 2009 at 9:14

GoogleCodeExporter commented 9 years ago
Unfortunately, this is a Java issue. The way Java Generics were designed, an 
pbject
loses all the Generics information (because of type-erasure).  This is 
generally not
a problem during serialization except in the cases like above. In your example,
BaseEvent class defines its content field as type C (which is called a 
TypeVariable).
After type-erasure, the object's field has no information as to what C actually 
maps
to. Gson uses some tricks to figure that out, but for that it needs the generic 
type
information as specified. 

Original comment by inder123 on 8 Apr 2009 at 6:44

GoogleCodeExporter commented 9 years ago
Yes, I understand about type-erasure. I do understand about how it complicate 
deserializing json -> java too. But I do not 
understand what prevent Gson from serializing, say,  class Struct<C>{ private C 
content; } as if it was class Struct{ private 
Object content;} ? As far, as I know, second is exactly what we'll have in 
bytecode after type-erasure, and exactly what 
we'll see throught Reflection API. In any case, object, reffered by field 
"content" will be serialized using it actual type, 
not declared one -- why we ever need field declared type? May be I miss 
something?

Original comment by chere...@gmail.com on 9 Apr 2009 at 11:59