I have a JSON string like this:
{"sectionIdStats":"","cdArtist":"xyz","length":220,"sectionId":11,"cdTitle":"track #12","comment":"","clipBase":"/3/2/2/1/075596061223-1-5","dates":"","id":{"value":33012},"discNumber":1,"pickflag":"","trackNumber":12,"idValue":33012}
The object I am deserializng this into has the following setters:
public void setSectionId(int id)
{
//...
}
public void setSectionId(String id)
{
//...
}
(from past experience it seems that I need both -- not sure why but that's another issue it seems).
When I call JSONObject.fromString()
I get:
com.[snipsnip].musicops.json.JsonUtil$JsonSerializationException: Error in Deserialization of class com.[snipsnip].mgpi2.model.classical.ClassicalTrack for JSONObject: {"sectionIdStats":"","cdArtist":"XYZ","length":220,"sectionId":11,"cdTitle":"track #12","comment":"","clipBase":"/3/2/2/1/075596061223-1-5","dates":"","id":{"value":33012},"discNumber":1,"pickflag":"","trackNumber":12,"idValue":33012} -- java.lang.IllegalArgumentException: Cannot invoke com.[snipsnip].mgpi2.model.classical.ClassicalTrack.setSectionId - java.lang.ClassCastException@bb12
at com.[snipsnip].musicops.json.JsonUtil.deserialize(JsonUtil.java:299)
at com.[snipsnip].musicops.json.JsonUtil.deserialize(JsonUtil.java:323)
at com.[snipsnip].mgpi2.model.classical.ClassicalModelTest.testAssignTrackSection(ClassicalModelTest.java:554)
Caused by: net.sf.json.JSONException: java.lang.IllegalArgumentException: Cannot invoke com.[snipsnip].mgpi2.model.classical.ClassicalTrack.setSectionId - java.lang.ClassCastException@bb12
at net.sf.json.JSONObject.toBean(JSONObject.java:682)
at net.sf.json.JSONObject.toBean(JSONObject.java:554)
at com.[snipsnip].musicops.json.JsonUtil.deserialize(JsonUtil.java:295)
... 67 more
Caused by: java.lang.IllegalArgumentException: Cannot invoke com.[snipsnip].mgpi2.model.classical.ClassicalTrack.setSectionId - java.lang.ClassCastException@bb12
at org.apache.commons.beanutils.PropertyUtilsBean.invokeMethod(PropertyUtilsBean.java:1778)
at org.apache.commons.beanutils.PropertyUtilsBean.setSimpleProperty(PropertyUtilsBean.java:1759)
at org.apache.commons.beanutils.PropertyUtilsBean.setNestedProperty(PropertyUtilsBean.java:1648)
at org.apache.commons.beanutils.PropertyUtilsBean.setProperty(PropertyUtilsBean.java:1677)
at org.apache.commons.beanutils.PropertyUtils.setProperty(PropertyUtils.java:559)
at net.sf.json.JSONObject.setProperty(JSONObject.java:781)
at net.sf.json.JSONObject.setProperty(JSONObject.java:761)
at net.sf.json.JSONObject.toBean(JSONObject.java:638)
... 69 more
Besides the "why is this happening", is there a way to gather more information on which Class it was trying to cast into what?
Thanks.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It looks like you have a property with two setters, the PropertyDescriptor will try its best to determine which is the correct pair of methods for read/write, which I think will be the ones that match the return type with the set type (I'm assuming the return type of sectionId is int). Following that train of thought I created a bean with two properties (int,String) which will have their appropriate setter/getter and an extra setter with another type, so far the tests are green with the latest version from cvs. So either there was a bug that has been corrected or I misunderstood your problem. I'm attaching the code for your perusal.
public class Bean {
private int integer;
private String string;
public int getInteger() {return integer;}
public String getString() {return string;}
public void setInteger( int integer ) {this.integer = integer;}
public void setInteger( String integer )
{this.integer = new Integer( integer ).intValue();}
public void setString( int string )
{this.string = String.valueOf( string );}
public void setString( String string )
{this.string = string;}
}
thanks for the reply. Your test case matches my situation except for the fact that the sectionId which figures as an int in the Json string is actually a class itself with setters. So maybe the introspection doesn't go 'deep enough' or as you said there was a bug that has been fixed. I tried the 2.02a but found some backward compatibility problems so I didn't pursue it.
However, the best thing would be for the ClassCastException message to be more explicit so I can determine what type it is trying (I assume it is 'int' but I cannot be sure) and which method(s) it is trying. Is it possible to turn o some verbose mode that would indicate all this?
Thanks.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hmmm can you send a sample of your code to get more insight? it seems like PropetyUtils catches an IllegalArgumentException and throws a ClassCastException, which is later wrapped in a JSONException, meaning that perhaps there may be an opportunity to know more about the error.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
can I reach you by email? That'll be easier if we start exchanging code. I sent you an email through your sourceforge account, or you can do the same through my sourceforge account.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have a JSON string like this:
{"sectionIdStats":"","cdArtist":"xyz","length":220,"sectionId":11,"cdTitle":"track #12","comment":"","clipBase":"/3/2/2/1/075596061223-1-5","dates":"","id":{"value":33012},"discNumber":1,"pickflag":"","trackNumber":12,"idValue":33012}
The object I am deserializng this into has the following setters:
public void setSectionId(int id)
{
//...
}
public void setSectionId(String id)
{
//...
}
(from past experience it seems that I need both -- not sure why but that's another issue it seems).
When I call JSONObject.fromString()
I get:
com.[snipsnip].musicops.json.JsonUtil$JsonSerializationException: Error in Deserialization of class com.[snipsnip].mgpi2.model.classical.ClassicalTrack for JSONObject: {"sectionIdStats":"","cdArtist":"XYZ","length":220,"sectionId":11,"cdTitle":"track #12","comment":"","clipBase":"/3/2/2/1/075596061223-1-5","dates":"","id":{"value":33012},"discNumber":1,"pickflag":"","trackNumber":12,"idValue":33012} -- java.lang.IllegalArgumentException: Cannot invoke com.[snipsnip].mgpi2.model.classical.ClassicalTrack.setSectionId - java.lang.ClassCastException@bb12
at com.[snipsnip].musicops.json.JsonUtil.deserialize(JsonUtil.java:299)
at com.[snipsnip].musicops.json.JsonUtil.deserialize(JsonUtil.java:323)
at com.[snipsnip].mgpi2.model.classical.ClassicalModelTest.testAssignTrackSection(ClassicalModelTest.java:554)
Caused by: net.sf.json.JSONException: java.lang.IllegalArgumentException: Cannot invoke com.[snipsnip].mgpi2.model.classical.ClassicalTrack.setSectionId - java.lang.ClassCastException@bb12
at net.sf.json.JSONObject.toBean(JSONObject.java:682)
at net.sf.json.JSONObject.toBean(JSONObject.java:554)
at com.[snipsnip].musicops.json.JsonUtil.deserialize(JsonUtil.java:295)
... 67 more
Caused by: java.lang.IllegalArgumentException: Cannot invoke com.[snipsnip].mgpi2.model.classical.ClassicalTrack.setSectionId - java.lang.ClassCastException@bb12
at org.apache.commons.beanutils.PropertyUtilsBean.invokeMethod(PropertyUtilsBean.java:1778)
at org.apache.commons.beanutils.PropertyUtilsBean.setSimpleProperty(PropertyUtilsBean.java:1759)
at org.apache.commons.beanutils.PropertyUtilsBean.setNestedProperty(PropertyUtilsBean.java:1648)
at org.apache.commons.beanutils.PropertyUtilsBean.setProperty(PropertyUtilsBean.java:1677)
at org.apache.commons.beanutils.PropertyUtils.setProperty(PropertyUtils.java:559)
at net.sf.json.JSONObject.setProperty(JSONObject.java:781)
at net.sf.json.JSONObject.setProperty(JSONObject.java:761)
at net.sf.json.JSONObject.toBean(JSONObject.java:638)
... 69 more
Besides the "why is this happening", is there a way to gather more information on which Class it was trying to cast into what?
Thanks.
It looks like you have a property with two setters, the PropertyDescriptor will try its best to determine which is the correct pair of methods for read/write, which I think will be the ones that match the return type with the set type (I'm assuming the return type of sectionId is int). Following that train of thought I created a bean with two properties (int,String) which will have their appropriate setter/getter and an extra setter with another type, so far the tests are green with the latest version from cvs. So either there was a bug that has been corrected or I misunderstood your problem. I'm attaching the code for your perusal.
public class Bean {
private int integer;
private String string;
public int getInteger() {return integer;}
public String getString() {return string;}
public void setInteger( int integer ) {this.integer = integer;}
public void setInteger( String integer )
{this.integer = new Integer( integer ).intValue();}
public void setString( int string )
{this.string = String.valueOf( string );}
public void setString( String string )
{this.string = string;}
}
import junit.framework.TestCase;
import net.sf.json.JSONObject;
public class TestBean extends TestCase {
public void testBean_from_json1() {
JSONObject json = JSONObject.fromObject( "{'integer':11,'string':12}" );
Bean b = (Bean) JSONObject.toBean( json, Bean.class );
assertBean( b );
}
public void testBean_from_json2() {
JSONObject json = JSONObject.fromObject( "{'integer':'11','string':'12'}" );
Bean b = (Bean) JSONObject.toBean( json, Bean.class );
assertBean( b );
}
public void testBean_with_integers() {
Bean bean = new Bean();
bean.setInteger( 11 );
bean.setString( 12 );
JSONObject json = JSONObject.fromObject( bean );
Bean b = (Bean) JSONObject.toBean( json, Bean.class );
assertBean( b );
}
public void testBean_with_strings() {
Bean bean = new Bean();
bean.setInteger( "11" );
bean.setString( "12" );
JSONObject json = JSONObject.fromObject( bean );
Bean b = (Bean) JSONObject.toBean( json, Bean.class );
assertBean( b );
}
private void assertBean( Bean b ) {
assertEquals( 11, b.getInteger() );
assertEquals( "12", b.getString() );
}
}
thanks for the reply. Your test case matches my situation except for the fact that the sectionId which figures as an int in the Json string is actually a class itself with setters. So maybe the introspection doesn't go 'deep enough' or as you said there was a bug that has been fixed. I tried the 2.02a but found some backward compatibility problems so I didn't pursue it.
However, the best thing would be for the ClassCastException message to be more explicit so I can determine what type it is trying (I assume it is 'int' but I cannot be sure) and which method(s) it is trying. Is it possible to turn o some verbose mode that would indicate all this?
Thanks.
Hmmm can you send a sample of your code to get more insight? it seems like PropetyUtils catches an IllegalArgumentException and throws a ClassCastException, which is later wrapped in a JSONException, meaning that perhaps there may be an opportunity to know more about the error.
can I reach you by email? That'll be easier if we start exchanging code. I sent you an email through your sourceforge account, or you can do the same through my sourceforge account.