JavaBeanConverter naming requirements

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

JavaBeanConverter naming requirements

Peter A
Once nuisance of working with the JavaBeanConverter is that it appears to have different naming requirements than the default converter.

For example, I have a class which is defined like:
-------------------------- BEGIN ---------------------------------
public class Se3_F64 {
   public DenseMatrix64F R;
   public Vector3D_F64 T;
   public void setR(DenseMatrix64F R){...}
   public void setT(Vector3D_F64 T){...}
   public DenseMatrix64F getR(){...}
   public Vector3D_F64 getT(){...}
}
---------------------------- END ----------------------------------

and in the past was serialized (insider another object) as follows:

-------------------------- BEGIN ---------------------------------
  <rightToLeft>
    <R>
      <numRows>3</numRows>
      <numCols>3</numCols>
      <data>
        <double>1.0</double>
        <double>0.0</double>
        <double>0.0</double>
        <double>0.0</double>
        <double>1.0</double>
        <double>0.0</double>
        <double>0.0</double>
        <double>0.0</double>
        <double>1.0</double>
      </data>
    </R>
    <T>
      <x>0.07</x>
      <y>0.0</y>
      <z>0.0</z>
    </T>
  </rightToLeft>
---------------------------- END ----------------------------------
where rightToLeft is an object of type Se3_F64. 

If I try to deserialize the object with the following
-------------------------- BEGIN ---------------------------------
        XStream xstream = new XStream(new PureJavaReflectionProvider(),new XppDriver(),
                new ClassLoaderReference(UtilIO.class.getClassLoader()));
        xstream.registerConverter(new JavaBeanConverter(xstream.getMapper()));
---------------------------- END ----------------------------------
it will fail with the error message shown below.  However, if I comment out the new JavaBeanConverter() line it will parse it just fine.  A fix to get around this issue is to modify the XML so that <R></R> becomes <r></r> and similar for <T>.  This can be a bit annoying, but it becomes very annoying if other people try to parse my serialized objects in their code and don't realize that you need to use the JavaBeanConverter.

-------------------------- BEGIN ---------------------------------
Exception in thread "Thread-1" com.thoughtworks.xstream.converters.ConversionException: No field 'R' found in class 'georegression.struct.se.Se3_F64' : No field 'R' found in class 'georegression.struct.se.Se3_F64'
---- Debugging information ----
message             : No field 'R' found in class 'georegression.struct.se.Se3_F64'
cause-exception     : com.thoughtworks.xstream.converters.reflection.MissingFieldException
cause-message       : No field 'R' found in class 'georegression.struct.se.Se3_F64'
class               : georegression.struct.se.Se3_F64
required-type       : georegression.struct.se.Se3_F64
converter-type      : com.thoughtworks.xstream.converters.javabean.JavaBeanConverter
path                : /boofcv.struct.calib.StereoParameters/rightToLeft/R
line number         : 31
class[1]            : boofcv.struct.calib.StereoParameters
version             : 1.4.7
-------------------------------
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:79)
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
    at com.thoughtworks.xstream.converters.javabean.JavaBeanConverter.unmarshal(JavaBeanConverter.java:134)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134)
    at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)
    at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1185)
    at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1169)
    at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1040)
    at boofcv.io.UtilIO.loadXML(UtilIO.java:157)
    at boofcv.alg.geo.rectify.ShowRectifyCalibratedApp.changeInput(ShowRectifyCalibratedApp.java:154)
    at boofcv.gui.SelectAlgorithmAndInputPanel.performChangeInput(SelectAlgorithmAndInputPanel.java:326)
    at boofcv.gui.SelectAlgorithmAndInputPanel.access$200(SelectAlgorithmAndInputPanel.java:44)
    at boofcv.gui.SelectAlgorithmAndInputPanel$8.run(SelectAlgorithmAndInputPanel.java:300)
Caused by: com.thoughtworks.xstream.converters.reflection.MissingFieldException: No field 'R' found in class 'georegression.struct.se.Se3_F64'
    at com.thoughtworks.xstream.converters.javabean.PropertyDictionary.propertyDescriptor(PropertyDictionary.java:98)
    at com.thoughtworks.xstream.converters.javabean.BeanProvider.getProperty(BeanProvider.java:186)
    at com.thoughtworks.xstream.converters.javabean.BeanProvider.propertyDefinedInClass(BeanProvider.java:134)
    at com.thoughtworks.xstream.converters.javabean.JavaBeanConverter.unmarshal(JavaBeanConverter.java:130)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
    ... 18 more


--
"Now, now my good man, this is no time for making enemies."    — Voltaire (1694-1778), on his deathbed in response to a priest asking that he renounce Satan.
Reply | Threaded
Open this post in threaded view
|

Re: JavaBeanConverter naming requirements

Jörg Schaible-4
Hi Peter,

Peter A wrote:

> Once nuisance of working with the JavaBeanConverter is that it appears to
> have different naming requirements than the default converter.
>
> For example, I have a class which is defined like:
> -------------------------- BEGIN ---------------------------------
> public class Se3_F64 {
>    public DenseMatrix64F R;
>    public Vector3D_F64 T;
>    public void setR(DenseMatrix64F R){...}
>    public void setT(Vector3D_F64 T){...}
>    public DenseMatrix64F getR(){...}
>    public Vector3D_F64 getT(){...}
> }
> ---------------------------- END ----------------------------------
>
> and in the past was serialized (insider another object) as follows:
>
> -------------------------- BEGIN ---------------------------------
>   <rightToLeft>
>     <R>
>       <numRows>3</numRows>
>       <numCols>3</numCols>
>       <data>
>         <double>1.0</double>
>         <double>0.0</double>
>         <double>0.0</double>
>         <double>0.0</double>
>         <double>1.0</double>
>         <double>0.0</double>
>         <double>0.0</double>
>         <double>0.0</double>
>         <double>1.0</double>
>       </data>
>     </R>
>     <T>
>       <x>0.07</x>
>       <y>0.0</y>
>       <z>0.0</z>
>     </T>
>   </rightToLeft>
> ---------------------------- END ----------------------------------
> where rightToLeft is an object of type Se3_F64.
>
> If I try to deserialize the object with the following
> -------------------------- BEGIN ---------------------------------
>         XStream xstream = new XStream(new PureJavaReflectionProvider(),new
> XppDriver(),
>                 new ClassLoaderReference(UtilIO.class.getClassLoader()));
>         xstream.registerConverter(new
> JavaBeanConverter(xstream.getMapper()));
> ---------------------------- END ----------------------------------
> it will fail with the error message shown below.  However, if I comment
> out
> the new JavaBeanConverter() line it will parse it just fine.  A fix to get
> around this issue is to modify the XML so that <R></R> becomes <r></r> and
> similar for <T>.  This can be a bit annoying, but it becomes very annoying
> if other people try to parse my serialized objects in their code and don't
> realize that you need to use the JavaBeanConverter.


It's in the responsibility of *each* converter to map possible elements to
members/fields of a Java object. A reflection based converter will use the
real field name, a converter based on the JavaBean naming conventions will
use those. You can *never* expect that you can read XML with an XStream
instance that has been setup differently compared to the one you have used
to write.


> -------------------------- BEGIN ---------------------------------
> Exception in thread "Thread-1"
> com.thoughtworks.xstream.converters.ConversionException: No field 'R'
> found in class 'georegression.struct.se.Se3_F64' : No field 'R' found in
> class 'georegression.struct.se.Se3_F64'
> ---- Debugging information ----
> message             : No field 'R' found in class
> 'georegression.struct.se.Se3_F64'
> cause-exception     :
> com.thoughtworks.xstream.converters.reflection.MissingFieldException
> cause-message       : No field 'R' found in class
> 'georegression.struct.se.Se3_F64'
> class               : georegression.struct.se.Se3_F64
> required-type       : georegression.struct.se.Se3_F64
> converter-type      :
> com.thoughtworks.xstream.converters.javabean.JavaBeanConverter
> path                : /boofcv.struct.calib.StereoParameters/rightToLeft/R
> line number         : 31
> class[1]            : boofcv.struct.calib.StereoParameters
> version             : 1.4.7
> -------------------------------


This is definitely the correct reaction. According to JavaBean convention
the property is "r" and not "R".

If the XML format is given, you may use in the applet an additional custom
Mapper and overload the serializedMember and realMember methods to adjust
the orthography of members with one character only.

However, be aware that the JavaBeanConverter will not support fields without
getter/setter nor does it support attributes or field aliases. To be on the
safe side you should use the same XStream setup everywhere you read/write
the XML.

Cheers,
Jörg


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email