<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>random  programmable thought bubbles on java javascript occasional css even php &#187; CGLIB</title>
	<atom:link href="http://www.anzaan.com/tag/cglib/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.anzaan.com</link>
	<description></description>
	<lastBuildDate>Wed, 18 Jan 2012 02:51:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Serializing CGLIB enhanced proxy into JSON using XStream</title>
		<link>http://www.anzaan.com/2010/06/serializing-cglib-enhanced-proxy-into-json-using-xstream/</link>
		<comments>http://www.anzaan.com/2010/06/serializing-cglib-enhanced-proxy-into-json-using-xstream/#comments</comments>
		<pubDate>Sat, 26 Jun 2010 01:34:36 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[CGLIB]]></category>
		<category><![CDATA[enhanced proxy]]></category>
		<category><![CDATA[lazy loading]]></category>
		<category><![CDATA[serialization]]></category>
		<category><![CDATA[xstream]]></category>

		<guid isPermaLink="false">http://www.anzaan.com/?p=133</guid>
		<description><![CDATA[I use a custom very lightweight persistence library that does lazy loading using CGLIB Enhanced proxy.
THe generated proxy for domain objects use  Key/value Map data fed to it via a static factory method.
When a get or set method is called for the wrapped domain, the proxy check the value for the field in the Map,
if it finds an entry for the field, which means the field hasn't been initialised, it sets the field value from Map and removes <a href="http://www.anzaan.com/2010/06/serializing-cglib-enhanced-proxy-into-json-using-xstream/">Read more <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I use a custom very lightweight persistence library that does lazy loading using CGLIB Enhanced proxy.<br />
THe generated proxy for domain objects use  Key/value Map data fed to it via a static factory method.<br />
When a get or set method is called for the wrapped domain, the proxy check the value for the field in the Map,<br />
if it finds an entry for the field, which means the field hasn&#8217;t been initialised, it sets the field value from Map and removes<br />
the entry from the Map.<br />
If no entry is found in the Map, the method returns value of the field of the domain object encapsulated by the getter method<br />
rather than getting it from the Map.</p>
<p>Of course if the field is a domain object, then the object is fetched using the PK value in the Map.<br />
That gives me the same  lazy loading voodoo magic like Hibernate- the 10 pound gorrila.<br />
The persistence is backed by a cache which looks at a domain&#8217;s metadata  and<br />
only caches those that are specified as cacheable.</p>
<p>Everything works like a charm except that the CGLIB enhanced  objects  don&#8217;t play nice with XStream at all.<br />
When serializing enhanced objects XStream spits out gory details of classe/superclasses/interfaces and full dissection of a Map that is fed to a static method when creating the proxy object, when all i want is the pojo object wrapped by the proxy.</p>
<p>I believe the XStream library simply gets the value of the field rather than calling the getter method  using reflection when serializing.<br />
That must be the reason that in my case all serialised objects have empty values for fields because the fields don&#8217;t get set  when the proxy is<br />
 created, they get set only setter method is called on it or getter method is called for the first time .<br />
I think that&#8217;s the same problem with Hibernate and I guess that&#8217;s the reason it throws Lazy Initilization Exception.</p>
<p>I tried the CGLIBEnhancedConverter that comes with the library but it didn&#8217;t work for me.<br />
I couldn&#8217;t find a simple enough solution in the internet and the ones I found were all Hibernate specific.<br />
Since this is the second time I had been trying to solve the issue, I decided to push forward and find a work around myself.</p>
<p>After trying out a few different solutions I finally came up with a dead simple solution.<br />
IT involves a static method to deproxy the enhanced domain objects and a XStream custom converter class.<br />
There may be performance cost  as it uses reflection eventhough getter setter methods for domain classes are cached for reuse.</p>
<p>Here&#8217;s the simplified method.</p>
<pre class="brush: java; title: ; notranslate">

  /**
     * Deproxies a CGLIB enhanced proxy object
     * @param &lt;T&gt;
     * @param proxy
     * @return deproxied domain object
     */
    public static &lt;T &gt; T deproxyReflection(final T proxy) {

      Class entityClass = proxy.getClass().getSuperclass();

        T entity = (T) ClassUtil.getInstance(entityClass);

        Field[] fields =  entityClass.getDeclaredFields();

        for (Field f : fields) {
            try {

	 // no need to set the values of collections as they won;t be serialized.
                //we just need the actaul properties taht amp to table columns
                if(List.class.isAssignableFrom(f.getType()))
                    continue;

                //I use a utility method to fetch getter/setter methods.
                //it simply loops through the object and super class to find the methods.
//so instead of screwing arund with the field's security settings we'll use getters/setters to ensure its unintrusive
                Method getter = ClassUtil.getPojoMethod(entityClass, f.getName(), ClassUtil.MethodType.GETTER);
                Method setter = ClassUtil.getPojoMethod(entityClass, f.getName(), new Class[]{f.getType()}, ClassUtil.MethodType.SETTER);

                Object val = getter.invoke(proxy, null);
                setter.invoke(entity, new Object[]{val});

            } catch (Exception ex) {
                Logger.getLogger(EntityProxyFactory.class.getName()).log(Level.SEVERE, null, ex);
            }
            try {
                f.set(entity, f.get(proxy));
            } catch (Exception ex) {
                Logger.getLogger(EntityProxyFactory.class.getName()).log(Level.SEVERE, null, ex);
            } 

        }

        return entity;
    }
</pre>
<p>We need to register a converter with XStream  that used the above method to sanitize the domain objects before serializing.</p>
<pre class="brush: java; title: ; notranslate">

/**
 * XStream converter to convert a CGLIB enhanced proxy  to the wrapped pojo object.
 *
 */
public class CGLIBEnhancedEntityConverter implements Converter {

    public boolean canConvert(Class clazz) {
        return (Enhancer.isEnhanced(clazz)  || clazz == CGLIBMapper.Marker.class) ;
    }

    public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {

            // deproxy before sending it off the chain for serialization. ANd that's it.
           // XStream will get a simple pojo object and it will serialize it like any other pojo object.
         context.convertAnother(EntityProxyFactory.deproxyReflection(source));

    }

    public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {

    throw new Error(&quot;not supported&quot;);
    }

}
</pre>
<p>And that&#8217;s it. That&#8217;s all it takes.<br />
If a domain object has other domain objects as fields, those fields will not be handled by the above method.<br />
For that there are two choices. Firstly you can look at the field&#8217;s class type and say if t implements or extends your base Domain class/interface, you can deproxy them recursively.<br />
In my case all domain objects implement a bare minimum interface called IEntity with only one getId() method.</p>
<p> the above method can be modified to recursively deproxy/sanitize a domain&#8217;s fields if they are proxied objects.</p>
<pre class="brush: java; title: ; notranslate">

//.............
            Object val = getter.invoke(proxy, null);

                if (IEntity.class.isAssignableFrom(f.getType()) {
                    val=deproxy(val);//recursively deproxy the fields if they are enhanced objects
                }
                setter.invoke(entity, new Object[]{val});
</pre>
<p>If you only have to serialize a handful of domain objects, it might be better to register converters<br />
 for those fields at startup instead of using the above method.</p>
<p>Say, we have a domain class State with Country as one of its field, we can register the above converter to convert the country object as below.</p>
<pre class="brush: java; title: ; notranslate">

//.............
//entity manager that handles all persistence needs
IEntityManager em= (IEntityManager) BeanFactory.getBean(&quot;entityManager&quot;);

//fetch a list of State objects with id smaller than3
       List&lt;State&gt; list= em.fetch(State.class, &quot;id&lt;3&quot;);

//uses factory method to instantiate Xstream
xstream xstream= XStreamFactory.getXstream(Format.JSON);

CGLIBEnhancedEntityConverter cglibConverter= new CGLIBEnhancedEntityConverter();

//register default converter
xstream.registerConverter(cglibConverter);

//register field converter. country field for State objects
xstream.registerLocalConverter(State.class, &quot;country&quot;, cglibConverter);

//spit out the serialized json objects
 System.out.println(xs.toXML(list));
</pre>
<p>here&#8217;s the result  without deproxying the domain object:<br />
The before version <img src='http://www.anzaan.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<pre class="brush: java; title: ; notranslate">

{&quot;list&quot;: [
  {
    &quot;code&quot;: &quot;&quot;,
    &quot;name&quot;: &quot;&quot;,
    &quot;daylightSavingStart&quot;: &quot;&quot;,
    &quot;daylightSavingEnd&quot;: &quot;&quot;,
    &quot;CGLIB$BOUND&quot;: true,
    &quot;CGLIB$CALLBACK_0&quot;: {
      &quot;@class&quot;: &quot;com.barahisolutions.proxy.EntityProxyFactory$EntityMethodInterceptor&quot;,
      &quot;data&quot;: [
        {},
        {
          &quot;default&quot;: {
            &quot;loadFactor&quot;: 0.75,
            &quot;threshold&quot;: 12
          },
          &quot;int&quot;: 16,
          &quot;int&quot;: 8,
          &quot;string&quot;: &quot;id&quot;,
//..................................................
//there's 10 times more of this garbage which i didn;t bother to print out.
</pre>
<p>And here's the nice and clean pojo version of the deproxied proxy objects.<br />
I used the recursive option to inspect properties if objects and deproxy them if they are proxied domain<br />
objects.<br />
The after version <img src='http://www.anzaan.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<pre class="brush: java; title: ; notranslate">

{&quot;list&quot;: [
  {
    &quot;id&quot;: 1,
    &quot;code&quot;: &quot;NSW&quot;,
    &quot;name&quot;: &quot;New South Wales&quot;,
    &quot;utcOffset&quot;: 10.0,
    &quot;daylightSavingOn&quot;: false,
    &quot;daylightSavingStart&quot;: &quot;&quot;,
    &quot;daylightSavingEnd&quot;: &quot;&quot;,
    &quot;country&quot;: {
      &quot;id&quot;: 18,
      &quot;code&quot;: &quot;&quot;,
      &quot;name&quot;: &quot;Barbados&quot;
    }
  },
  {
    &quot;id&quot;: 2,
    &quot;code&quot;: &quot;VIC&quot;,
    &quot;name&quot;: &quot;Victoria&quot;,
    &quot;daylightSavingOn&quot;: false,
    &quot;daylightSavingStart&quot;: &quot;&quot;,
    &quot;daylightSavingEnd&quot;: &quot;&quot;,
    &quot;country&quot;: {
      &quot;id&quot;: 12,
      &quot;code&quot;: &quot;AUS&quot;,
      &quot;name&quot;: &quot;Australia&quot;
    }
  }
]}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.anzaan.com/2010/06/serializing-cglib-enhanced-proxy-into-json-using-xstream/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

