<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Caleb Powell&#039;s Blog</title>
	<atom:link href="http://arity.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://arity.wordpress.com</link>
	<description></description>
	<lastBuildDate>Sat, 27 Jun 2009 04:16:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='arity.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Caleb Powell&#039;s Blog</title>
		<link>http://arity.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://arity.wordpress.com/osd.xml" title="Caleb Powell&#039;s Blog" />
	<atom:link rel='hub' href='http://arity.wordpress.com/?pushpress=hub'/>
		<item>
		<title>JBPM Migrator</title>
		<link>http://arity.wordpress.com/2009/06/21/jbpm-migrator/</link>
		<comments>http://arity.wordpress.com/2009/06/21/jbpm-migrator/#comments</comments>
		<pubDate>Sun, 21 Jun 2009 12:01:00 +0000</pubDate>
		<dc:creator>Caleb Powell</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[jbpm]]></category>

		<guid isPermaLink="false">http://arity.wordpress.com/2009/06/21/jbpm-migrator/</guid>
		<description><![CDATA[JBPM Migrator Overview We are using the JBPM workflow library (version 3.2.2) on a project here at Intelliware. After some analysis, we chose JBPM as our process modelling tool because it was open source and it was easy to integrate into our technology stack (Java 4, Hibernate for persistence). Over time, a process definition needs [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=arity.wordpress.com&amp;blog=8343867&amp;post=10&amp;subd=arity&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div>
<h1>JBPM Migrator</h1>
<h3>Overview<br /></h3>
<p>We are using the <a href="http://www.jboss.org/jbossjbpm/" id="d7lw" title="jBPM">JBPM</a> workflow library (version 3.2.2) on a project here at <a href="http://www.i-proving.ca/">Intelliware</a>. After some analysis, we chose JBPM as our process modelling tool because it was open source and it was easy to integrate into our technology stack (Java 4, Hibernate for persistence).</p>
<p>Over time, a process definition needs to change. Usually these changes reflect new business requirements, but they can also be related to a bug fix or an improvement in the existing process. So when we release a new version of a software product, we may need to update the older process instances in the database. Rather than provide a mechanism to migrate process instances, the JBPM library supports multiple versions of a process definition simultaneously:<br />
<blockquote><i>Process instances always execute to the process definition that they are started in. But JBPM allows for multiple process definitions of the same name to coexist in the database. So typically, a process instance is started in the latest version available at that time and it will keep on executing in that same process definition for its complete lifetime. When a newer version is deployed, newly created instances will be started in the newest version, while older process instances keep on executing in the older process definitions.</i><sup><a href="http://www.blogger.com/post-edit.g?blogID=5861474929477155039&amp;postID=4977779109642483320#FOOTNOTE-1">1</a></sup>        </p></blockquote>
<p>This wasn&#8217;t very appealing to us. Our application has processes that can be resumed at <i>any</i> point in the future (potentially years later) so by following the JBPM prescribed approach our developers would have to support &#8211; and the QA folks would have to test &#8211; outdated process instances for years to come.
<div>What we <i>wanted</i> was the ability to migrate outdated process instances to the current process definition. Indeed, the JBPM documentation addresses this approach:</div>
<p>
<div>
<blockquote> <i>An alternative approach to changing process definitions might be to convert the executions to a new process definition. Please take into account that this is not trivial due to the long-lived nature of business processes. Currently, this is an experimental area so for which there are not yet much out-of-the-box support.</p>
<p>As you know there is a clear distinction between process definition data, process instance data (the runtime data) and the logging data. With this approach, you create a separate new process definition in the JBPM database (by e.g. deploying a new version of the same process). Then the runtime information is converted to the new process definition. This might involve a translation cause tokens in the old process might be pointing to nodes that have been removed in the new version. So only new data is created in the database. But one execution of a process is spread over two process instance objects&#8230;</p>
<p></i></p></blockquote>
<p>JBPM doesn&#8217;t provide a tool to do this, but the code is open source and well documented, so we build a jbpm-migrator ourselves.</div>
<p></div>
<p><b>The Migrator</b></p>
<p>Given an old process instance, the migrator is responsible for transferring data to the latest process instance. The migrator transfers:
<ol type="1">
<li>All of the tokens. This is facilitated through the use of <a href="http://www.blogger.com/post-edit.g?blogID=5861474929477155039&amp;postID=4977779109642483320#Mapping_Token_Nodes" id="m2k1" title="mappings">mappings</a> .</p>
</li>
<p>
<li>All persistent and transient variables.</li>
<p>
<li>It adds a migration memo (a String in the persistent variables map) to the new process instance which records info about the migration (the current date, the old process definition version#, the old process instance id , etc).</li>
<p></ol>
<p>The migration is performed recursively, so each sub-process is migrated according to the above steps.</p>
<p><b><a id="q0qz" name="Mapping_Token_Nodes"></a>Mapping Token Nodes</b></p>
<p>One of the key challenges when migrating a process instance is the renaming or removal of <i>wait state</i> nodes. Wait state nodes (the green boxes in the diagram below) are where tokens reside when a process instance is persisted. Determining where a token should be placed is facilitated through a<i> migration</i>. A Migration contains a map that tells the Migrator where to put a token from a <i>deprecated</i> wait state node in the current process. Consider the following three versions of a Process called &#8216;Application&#8217;:</p>
<div id="a.dk" style="text-align:left;">
<div id="t:g-" style="text-align:center;"><img src="http://docs.google.com/File?id=dfd4dds3_313295b8dq_b" style="width:100%;" /></p>
<div style="text-align:left;">
<p></div>
<p></div>
<p>
<div id="itr_" style="text-align:center;"><img style="width:100%;" src="http://docs.google.com/File?id=dfd4dds3_32f8zg9tdb_b" /></p>
</div>
<p>
<div id="od7b" style="text-align:center;">
<div id="fbza" style="text-align:center;"><img src="http://docs.google.com/File?id=dfd4dds3_34dkb3wxf9_b" style="width:100%;" /></p>
<div style="text-align:left;">For the Application Process, two migrations would be written<sup><a href="http://www.blogger.com/post-edit.g?blogID=5861474929477155039&amp;postID=4977779109642483320#FOOTNOTE-2">2</a></sup>:</p>
<ol>
<li>Migration #1 (maps tokens from version #1 to version #2):<br />
<blockquote> {&#8216;init&#8217; =&gt; &#8216;start&#8217;, &#8216;invalid&#8217; =&gt; &#8216;Requires Review&#8217;, &#8216;end&#8217; =&gt; &#8216;application completed&#8217;}</p></blockquote>
<p></li>
<p>
<li>Migration #2 (maps tokens from version #2 to version #3):<br />
<blockquote> {&#8216;start&#8217; =&gt; &#8216;application received&#8217;}</p></blockquote>
</li>
</ol>
<p>Our migrator takes these individual migration maps and creates a composite map. With the composite map, the migrator can map a token from <i>any</i> outdated wait-state node <i>directly </i>to the appropriate node in the current process. The composite map of these two migrations would be written as:<br />
<blockquote>{&#8216;init&#8217; =&gt; &#8216;application received&#8217;, &#8216;start&#8217; =&gt; &#8216;application received&#8217;, &#8216;invalid&#8217; =&gt; &#8216;Requires Review&#8217;, &#8216;end&#8217; =&gt; &#8216;application completed&#8217;}</p></blockquote>
<p>Note that the map only needs to explain what to do with tokens on <i>deprecated</i> nodes (e.g. <i>init, start, invalid,  </i>and <i>end)</i>. No mapping is required for non-deprecated nodes (e.g. <i>managerial audit, application completed</i>, and <i>Requires review)</i>. By default, if no mapping exists for a wait state node (i.e. it is not deprecated) the migrator will attempt to move the token to a node with the same name in the new version.</p>
<p>The example I am using includes a discrete migration for each version of the process but this is not always required. Depending on the changes being made to the Process Definition, it is possible that the developer will not be required to include a migration at all. This is a good thing. It means that we don&#8217;t have to write a migration for every single process definition change and there is almost no configuration required on behalf of the developer.</p>
<p>But there is a cost. Deprecated nodes can never be used in future definitions of your process. So with our &#8216;Application<i>&#8216; </i>Process, the <i>init</i>, <i>start</i>, <i>invalid</i>, and <i>end</i> nodes can never be used again in the process definition (as wait states). Doing so would break the migrator.<br />
<h3><b>Defining a Migration</b><br /></h3>
<p>Migrations are written as Java classes. The class must implement the Migration interface, it must not be abstract, and it must contain a default constructor. The Migration interface declares one method that must be implemented:
<div class="source">
<pre>
<blockquote>public StateNodeMap createNodeMap();</blockquote>

</pre>
<p>Here is how you would express the first migration for &#8216;Application&#8217; Process Definition example:<span style="font-family:monospace;"></p>
<p></span></div>
<div class="source">
<pre>
<blockquote>public class ApplicationProcessMigration001 implements Migration{   public StateNodeMap createNodeMap() {       return new StateNodeMap(new String[][]{               {"init", "start"}, {"invalid", "Requires Review"}, {"end", "application completed"}       });   }}</blockquote>
</pre>
<p>Defining a Migrator</div>
<p>How do we create the migrator and use it to perform a migration? Like this:<br />
<blockquote>
<pre>
<blockquote>Migrator migrator = new Migrator(“ApplicationProcess”, jbpmContext, “com.foobar.ApplicationProcessMigration”);ProcessInstance newProcess = migrator.migrate(oldProcess);</blockquote>
<blockquote></blockquote>
</pre>
</blockquote>
<p>The parameters used to create the Migrator instance are:
<ol type="1">
<li>The name of the Process Definition that it will be migrating.</p>
</li>
<p>
<li>A JbpmContext instance. The migrator requires this to look up the latest Process Definition.</p>
</li>
<p>
<li>The Migration base class name. The migrator assumes that your migrations use the pattern <i>package.ClassName{</i><i>migration#}<a name="a3"></a></i>. For the base Class name “com.foobar.ApplicationProcessMigration”, the migrator will attempt to load and instantiate classes named “com.foobar.ApplicationProcessMigration001”, “com.foobar.ApplicationProcessMigration002”, etc, until it can’t find any valid classes.</li>
<p></ol>
<p>The third point is another example of convention over configuration, resulting in less maintenance and tedium on behalf of the developer.</p>
<h3>Unit and Integration Testing<br /></h3>
<p>I&#8217;m putting this section last, but it was one of our top concerns when considering an approach to migrations. We debated a number of approaches to testing and most of them were deemed to be too complex and error prone.</p>
<p>We already unit tested our JBPM process definitions to make sure that transitions point to valid nodes and that all actions declared in the process were available on the Classpath. With regards to the migrations, we have a base test that asserts that:
<ol>
<li>A developer has not introduced a deprecated node into the current process definition.</li>
<p>
<li>All current nodes in the composite map exist in the process definition.</li>
<p>
<li>All current nodes in the composite map are valid wait state nodes.</li>
<p></ol>
<p>Our application is deployed several times a week to a test environment where QA folks test functionality and validate stories. This provides a great opportunity to discover problems with our application early, and the migration code is no exception. We write migrations throughout the entire development cycle (not just when we release) to make sure, so if a QA person loads up an outdated process from from last week, the migrator will be run. This gives us a chance to find runtime bugs that the unit tests can&#8217;t locate.</p>
</div></div>
</p></div>
</div>
<hr />
<ol>
<li><a name="FOOTNOTE-1"></a><span style="font-family:'Lucida Grande';"><i><span style="font-size:85%;">http://docs.jboss.com/jbpm/v3.2/userguide/html/jpdl.html#processversioning</span></i></span></li>
<li><a name="FOOTNOTE-2"></a>I&#8217;m using the Ruby literal syntax for a Hash because there isn&#8217;t one in Java.</li>
</ol>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/arity.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/arity.wordpress.com/10/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/arity.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/arity.wordpress.com/10/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/arity.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/arity.wordpress.com/10/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/arity.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/arity.wordpress.com/10/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/arity.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/arity.wordpress.com/10/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/arity.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/arity.wordpress.com/10/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/arity.wordpress.com/10/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/arity.wordpress.com/10/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=arity.wordpress.com&amp;blog=8343867&amp;post=10&amp;subd=arity&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://arity.wordpress.com/2009/06/21/jbpm-migrator/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7b93ab5b8c5f5900ae30991c44201416?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">caleb_powell</media:title>
		</media:content>

		<media:content url="http://docs.google.com/File?id=dfd4dds3_313295b8dq_b" medium="image" />

		<media:content url="http://docs.google.com/File?id=dfd4dds3_32f8zg9tdb_b" medium="image" />

		<media:content url="http://docs.google.com/File?id=dfd4dds3_34dkb3wxf9_b" medium="image" />
	</item>
		<item>
		<title>The Pitfalls of Dynamic Proxy Serialization</title>
		<link>http://arity.wordpress.com/2008/02/12/the-pitfalls-of-dynamic-proxy-serialization/</link>
		<comments>http://arity.wordpress.com/2008/02/12/the-pitfalls-of-dynamic-proxy-serialization/#comments</comments>
		<pubDate>Tue, 12 Feb 2008 04:47:00 +0000</pubDate>
		<dc:creator>Caleb Powell</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[proxy]]></category>
		<category><![CDATA[serialization]]></category>

		<guid isPermaLink="false">http://arity.wordpress.com/2008/02/12/the-pitfalls-of-dynamic-proxy-serialization/</guid>
		<description><![CDATA[Recently, we ran into problems de-serializing proxy objects. The first pitfall involved a bug in Weblogic that prevented us from de-serializing a java.lang.reflect.Proxy instance. The second pitfall occurred as a result of using a Cglib proxy. In our efforts to deal with these pitfalls we managed to deepen our understanding of how these libraries create [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=arity.wordpress.com&amp;blog=8343867&amp;post=9&amp;subd=arity&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Recently, we ran into problems de-serializing proxy objects. The first pitfall involved a bug in Weblogic that prevented us from de-serializing a <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/reflect/Proxy.html">java.lang.reflect.Proxy</a> instance. The second pitfall occurred as a result of using a <a href="http://cglib.sourceforge.net/">Cglib</a> proxy. In our efforts to deal with these pitfalls we managed to deepen our understanding of how these libraries create dynamic proxies.</p>
<div style="text-align:center;"><span style="font-size:130%;">Pitfall #1</span></div>
<p>We wanted to use the java.lang.reflect.Proxy class to make instances of one (very simple) class assignable to different types of  interfaces. Everything was going just swimingly and we were close to checking in our code. When it came time to run our integration tests, Weblogic began throwing a  ClassNotFoundException whenever it attempted to de-serialize a proxy instance in a MessageDrivenBean. Once we confirmed that the interfaces were indeed on the Classpath, we fired up the debugger and dug a little deeper (but not until we consumed a a copious amount of Coca-Cola and Marlboros&#8230; thanks for the tip <a href="http://www.i-proving.ca/space/Michael+Melvin">Mike</a>). We discovered that &#8211; in the process of de-serializing our proxy object &#8211; the java.io.ObjectInputStream was trying to load our interfaces with the wrong classloader. It was using the parent of the Weblogic application classloader which had no knowledge of the classpath in our EAR file. We were were pretty certain that the reason was due to a bug in the way Weblogic was managing classloaders in it&#8217;s JMS implementation (of course, Weblogic is not open source so we can&#8217;t be 100% certain of this).</p>
<p>We couldn&#8217;t de-serialize the object ourselves inside the message bean and we couldn&#8217;t modify the way Weblogic managed classloaders, so we tried using the Cglib library instead. The Cglib proxy worked? The reason is because the ObjectInputStream de-serializes Cglib instances differently than it does a java.lang.reflect.Proxy instance. Why? Because of a key difference between the two types of proxy objects;</p>
<ul>
<li>When you create an instance using the JDK Proxy, it generates a subclass of the java.lang.reflect.Proxy class for you (the subclass is assignable to any interfaces you provide). Furthermore, the class generated by the java.lang.reflect.Proxy will have a different class descriptor (in fact, a Proxy class descriptor).</li>
</ul>
<p>
<ul>
<li>On the other hand, the Cglib library generates a subclass of an arbitrary class that you provide (as with the JDK proxy, the Cglib  generated subclass will also be assignable to any interfaces you choose to provide). The class generated by the Cglib library will have a regular class descriptor.</li>
</ul>
<p>Whenever the ObjectInputStream de-serializes an object, it peeks at the Class descriptor. If it has a Proxy class descriptor, it invokes the ObjectInputStream.resolveProxyClass() method which creates a new version of the proxy subclass in the JVM (if it didn&#8217;t already exist) based on the declared interfaces. Because the Cglib class  has a normal class descriptor, the ObjectInputStream.resolveClass() method is invoked instead. For reasons we&#8217;re not sure of, the classloader that is retrieved in the   ObjectInputStream.resolveClass() method is the correct one and can resolve our interfaces/classes.</p>
<div style="text-align:center;"><span style="font-size:180%;"><span style="font-size:130%;">Pitfall #2</span><br /></span></div>
<p>Now our Cglib proxy was being de-serialized correctly when sent to a JMS MessageDrivenBean. But we we were also sending these proxies to a rich client, and the Cglib proxies were not being de-serialized there. We were stunned, but only temporarily. This result was to be expected. The Cglib generated objects were instances of a subclass generated dynamically on a different JVM. Our rich client JVM didn&#8217;t recognize the class and was quite justified in throwing a ClassNotFoundException.</p>
<p>It turns out there is a pretty simple solution to this problem. Basically, you need to implement the  writeReplace() and readResolve()  methods on the object that your proxy delegates methods to. The delegate uses these methods to de-proxy and re-proxy itself depending on whether it is being serialized or de-serialized. In our case, our delegate object is the super-class of our Proxy instance, so we implemented the writeReplace() and readResolve() methods on it. Here is an example using a class called DataHandler;</p>
<blockquote><pre><span style="color:rgb(204,51,204);">public static class</span> DataHandler <span style="color:rgb(204,51,204);">implements</span> Serializable {<span style="color:rgb(204,51,204);">private static final long</span> <span style="color:rgb(51,51,255);">serialVersionUID</span> = 1L;<span style="color:rgb(204,51,204);">private final String</span> <span style="color:rgb(51,102,255);">someData</span>;

<span style="color:rgb(204,51,204);">public</span> DataHandler(String someData){<span style="color:rgb(204,51,204);">this</span>.<span style="color:rgb(51,102,255);">someData</span> = someData;}<span style="color:rgb(204,51,204);">public</span> String getSomeData() {<span style="color:rgb(204,51,204);">return</span> <span style="color:rgb(51,102,255);">someData</span>;}

<span style="color:rgb(204,51,204);">public boolean</span> equals(Object obj) {<span style="color:rgb(204,51,204);">return</span> obj <span style="color:rgb(204,51,204);">instanceof</span> DataHandler ?      ((DataHandler)obj).getSomeData().equals(<span style="color:rgb(204,51,204);">this</span>.<span style="color:rgb(51,102,255);">someData</span>): <span style="color:rgb(204,51,204);">false</span>;}

<span style="color:rgb(204,51,204);">public</span> Object writeReplace() <span style="color:rgb(204,51,204);">throws</span> ObjectStreamException{<span style="color:rgb(204,51,204);">return</span> <span style="color:rgb(204,51,204);">new</span> DataHandler(<span style="color:rgb(204,51,204);">this</span>.<span style="color:rgb(51,102,255);">someData</span>);}<span style="color:rgb(204,51,204);">public</span> Object readResolve() <span style="color:rgb(204,51,204);">throws</span> ObjectStreamException{<span style="color:rgb(204,51,204);">return</span> ProxyFactory.createCglibProxy(DataHandler.<span style="color:rgb(204,51,204);">class</span>,                   <span style="color:rgb(204,51,204);">new</span> Class[]{IFoo.<span style="color:rgb(204,51,204);">class</span>},                   <span style="color:rgb(204,51,204);">new</span> Object[] {<span style="color:rgb(204,51,204);">this</span>.<span style="color:rgb(51,102,255);">someData</span>});}}

<span style="color:rgb(204,51,204);">public interface</span> IFoo <span style="color:rgb(204,51,204);">extends</span> java.io.Serializable{}
</pre>
<p></p></blockquote>
<p>We create a proxy with the Cglib library like so;</p>
<blockquote><p>Enhancer enhancer = new Enhancer();<br />enhancer.setSuperclass(DataHandler.<span style="color:rgb(204,51,204);">class</span>);<br />enhancer.setInterfaces(<span style="color:rgb(204,51,204);">new</span> Class[]{IFoo.<span style="color:rgb(204,51,204);">class</span>});<br />enhancer.setCallback(<span style="color:rgb(204,51,204);">new</span> NoOpCallback());<span style="color:rgb(51,204,0);">//a NoOp callback. All methods will be invoked on the superclass</span><br />IFoo foo = (IFoo) enhancer.create(<br /><span style="color:rgb(204,51,204);">                        new</span> Class[]{String.<span style="color:rgb(204,51,204);">class</span>},<br /><span style="color:rgb(204,51,204);">                            new</span> Object[] {<span style="color:rgb(51,102,255);">&#8220;someData&#8221;</span>});<span style="color:rgb(51,204,0);">//generates a subclass of DataHandler that assignable to the IFoo interface.</span></p></blockquote>
<p>When the foo instance is serialized, the super-class (DataHandler) method writeReplace() is invoked. The writeReplace method returns a new instance of the DataHandler class, thereby discarding the Proxy wrapper subclass. It&#8217;s this new instance of DataHandler that gets serialized, not the original subclass. When the DataHandler instance is eventually de-serialized, the readResolve() method is invoked on it. The readResolve() will generate and return a new proxy subclass equivalent to the original . We learned this little trick by studying the code in the Hibernate project which uses Cglib for proxies and is open-source.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/arity.wordpress.com/9/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/arity.wordpress.com/9/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/arity.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/arity.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/arity.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/arity.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/arity.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/arity.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/arity.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/arity.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/arity.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/arity.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/arity.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/arity.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/arity.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/arity.wordpress.com/9/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=arity.wordpress.com&amp;blog=8343867&amp;post=9&amp;subd=arity&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://arity.wordpress.com/2008/02/12/the-pitfalls-of-dynamic-proxy-serialization/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7b93ab5b8c5f5900ae30991c44201416?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">caleb_powell</media:title>
		</media:content>
	</item>
		<item>
		<title>Antwrap</title>
		<link>http://arity.wordpress.com/2007/04/20/antwrap/</link>
		<comments>http://arity.wordpress.com/2007/04/20/antwrap/#comments</comments>
		<pubDate>Fri, 20 Apr 2007 00:27:00 +0000</pubDate>
		<dc:creator>Caleb Powell</dc:creator>
				<category><![CDATA[Ant]]></category>
		<category><![CDATA[JRuby]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://arity.wordpress.com/2007/04/20/antwrap/</guid>
		<description><![CDATA[Recently, I wrote a library called Antwrap that can be used to invoke Ant tasks from a Ruby script. My original motivation for writing it was to use Rake as a build tool on a Java project. While Ant provides an abundance of useful tasks, I&#8217;ve always found its XML syntax makes it hard to [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=arity.wordpress.com&amp;blog=8343867&amp;post=8&amp;subd=arity&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Recently, I wrote a library called <a target="_blank" href="http://rubyforge.org/projects/antwrap/">Antwrap</a> that can be used to invoke <a target="_blank" href="http://ant.apache.org/">Ant</a> tasks from a Ruby script. My original motivation for writing it was to use <a target="_blank" href="http://martinfowler.com/articles/rake.html">Rake</a> as a build tool on a Java project. While Ant provides an abundance of useful tasks, I&#8217;ve always found its XML syntax makes it hard to write concise, fine-grained tasks (the original author of Ant <a target="_blank" href="http://www.theserverside.com/news/thread.tss?thread_id=24864">states as much</a>). Rake is an internal DSL written in Ruby(which <i>is</i> concise), so you can define your own abstractions in the build script and you have a huge selection of libraries at your disposal.</p>
<p>I wanted to use Rake as a build tool but there was an obvious hurdle to clear; all those Java specific tasks that we take for granted in Ant aren&#8217;t available in the Ruby libraries. For example, let&#8217;s say a Rake script needs to kick off a Java process. The core Ruby libraries make this possible:</p>
<div>
<pre>system(<span>"java"</span>, <span>"-client -jar lib/foobar.jar"</span>)</pre>
</div>
<p>But the system call is not specific to the Java executable so passing in JVM and Program options can be awkward. In Ant, we would use the <i>java</i> task:
<div>
<pre>&lt;java classpath=<span>"lib/foobar.jar"</span> classname=<span>"foo.bar.FooBar"</span> fork=<span>"<span>true</span>"</span>&gt;

    &lt;jvmarg value=<span>"client"</span>/&gt;    &lt;arg value=<span>"argOne"</span>/&gt;    &lt;arg value=<span>"argTwo"</span>/&gt;&lt;/java&gt;</pre>
</div>
<p>This is the equivalent using Antwrap:
<div>
<pre>@ant = AntProject.<span>new</span>(:ant_home =&gt; <span>"/Users/caleb/tools/apache-ant-1.7.0"</span>)

@ant.java(:classpath =&gt; 'lib/foobar.jar', :classname =&gt; 'foo.bar.FooBar',           :fork =&gt; '<span>true</span>'){    jvmarg(:value =&gt; 'client')    arg(:value =&gt; 'argOne')    arg(:value =&gt; 'argTwo')}</pre>
</div>
<p>The Task attributes are passed to the method as a hash. What would normally be child elements in XML are passed to the method via a <a target="_blank" href="http://eli.thegreenplace.net/2006/04/18/understanding-ruby-blocks-procs-and-methods/">block</a>. The AntProject instance doesn&#8217;t actually have a <i>java</i> method defined. Rather, its <i>method_missing</i> method is invoked and ends up instantiating the appropriate Ant task for you. This is one example of Ruby&#8217;s powerful meta-programming features; they make it easy to provide rich semantics (as opposed to invoking @ant.executeTask(&#8216;java&#8217;)).
<p>Here is a more complicated example using the <i>javac</i> task. This simply illustrates that all of the normal Ant tasks are at your disposal, including Ant Properties and Refs:</p>
<div>
<pre>@ant = AntProject.<span>new</span>(:ant_home =&gt; <span>"/Users/caleb/tools/apache-ant-1.7.0"</span>)@ant.property(:name =&gt; 'common.dir', :value =&gt; @current_dir)

@ant.path(:id =&gt; <span>"other.class.path"</span>){    pathelement(:location =&gt; <span>"classes"</span>)    pathelement(:location =&gt; <span>"config"</span>)}

@ant.path(:id =&gt; <span>"common.class.path"</span>){    fileset(:dir =&gt; <span>"${common.dir}/lib"</span>){        include(:name =&gt; <span>"**/*.jar"</span>)    }    pathelement(:location =&gt; <span>"${common.classes}"</span>)}

@ant.javac(:srcdir =&gt; <span>"test"</span>, :destdir =&gt; <span>"classes"</span>){    classpath(:refid =&gt; <span>"common.class.path"</span>)    classpath(:refid =&gt; <span>"other.class.path"</span>)}</pre>
</div>
<p>The transition from an existing Ant build file to a Rake file is relatively easy. There is a handy <a target="_blank" href="http://rubyforge.org/frs/download.php/16970/convert.rb">conversion script</a> available. So this:
<div>
<pre>&lt;target name=<span>"clean"</span> depends=<span>"init"</span>&gt;

    &lt;delete dir=<span>"classes"</span> failonerror=<span>"false"</span>/&gt;    &lt;delete dir=<span>"${distro.dir}"</span>/&gt;    &lt;delete file=<span>"${outputjar}"</span>/&gt;

    &lt;delete file=<span>"${output.dir}"</span>/&gt;&lt;/target&gt;</pre>
</div>
<p>Becomes the Rake equivalent:
<div>
<pre>task :clean =&gt; [:init] <span>do</span>    @ant.delete(:dir =&gt; <span>"classes"</span>, :failonerror =&gt; <span>"<span>false</span>"</span>)    @ant.delete(:dir =&gt; <span>"${distro.dir}"</span>)    @ant.delete(:file =&gt; <span>"${outputjar}"</span>)    @ant.delete(:file =&gt; <span>"${output.dir}"</span>)end</pre>
</div>
<p>Antwrap runs on the native Ruby and the <a target="_blank" href="http://jruby.codehaus.org/">JRuby</a> interpreter. If running on the native Ruby interpreter, Antwrap depends on the <a target="_blank" href="http://rjb.rubyforge.org/">Ruby Java Bridge</a> (RJB) Gem which invokes Java classes via the Java Native Interface (JNI). Antwrap is currently being used for Ant tasks in the <a target="_blank" href="http://raven.rubyforge.org/index.html">Raven</a> (a.k.a. don&#8217;t call me Maven) project. Raven is a JRuby implementation of the Rake tool that provides all kinds of utilities for a Java project.
<p>In the long-term, I see Ruby/Rake scripts complementing a tool like Maven on Java projects. Ruby for fine-grained, project specific tasks and Maven for coarse-grained, boiler-plate tasks (compilation, unit-tests, packaging, documentation) that you need on most Java projects.</p>
<p><i>Other resources:</i><br /><i><a target="_blank" href="http://www.martinfowler.com/bliki/JRake.html">Martin Fowler on JRake</a></i><br /><i><a target="_blank" href="http://groovy.codehaus.org/Ant+Scripting">Groovy Antbuilder</a></i></p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/arity.wordpress.com/8/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/arity.wordpress.com/8/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/arity.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/arity.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/arity.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/arity.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/arity.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/arity.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/arity.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/arity.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/arity.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/arity.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/arity.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/arity.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/arity.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/arity.wordpress.com/8/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=arity.wordpress.com&amp;blog=8343867&amp;post=8&amp;subd=arity&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://arity.wordpress.com/2007/04/20/antwrap/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7b93ab5b8c5f5900ae30991c44201416?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">caleb_powell</media:title>
		</media:content>
	</item>
		<item>
		<title>Macrodef</title>
		<link>http://arity.wordpress.com/2006/11/07/macrodef/</link>
		<comments>http://arity.wordpress.com/2006/11/07/macrodef/#comments</comments>
		<pubDate>Tue, 07 Nov 2006 01:28:00 +0000</pubDate>
		<dc:creator>Caleb Powell</dc:creator>
				<category><![CDATA[Ant]]></category>

		<guid isPermaLink="false">http://arity.wordpress.com/2006/11/07/macrodef/</guid>
		<description><![CDATA[The &#60;macrodef/&#62; task (new in Ant 1.6.5) can be used to define your own custom tasks from within an existing build file. In some cases it can eliminate the need to define your own custom tasks in the traditional fashion. When possible, you should try to use &#60;macrodef/&#62; instead of the &#60;antcall/&#62; task. By using [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=arity.wordpress.com&amp;blog=8343867&amp;post=7&amp;subd=arity&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The <a target="_blank" href="http://ant.apache.org/manual/CoreTasks/macrodef.html">&lt;macrodef/&gt;</a> task (new in Ant 1.6.5) can be used to define your own custom tasks from within an existing build file. In some cases it can eliminate the need to define your own custom tasks in the <a target="_blank" href="http://ant.apache.org/manual/develop.html#writingowntask/">traditional fashion</a>.
<p style="text-align:left;"></p>
<p style="text-align:left;">When possible, you should try to use &lt;macrodef/&gt; instead of the &lt;antcall/&gt; task. By using &lt;antcall/&gt;, you&#8217;re invoking your target as if it were a task. This practice can become harder to maintain and result in performance problems in larger build files.</p>
<p style="text-align:left;">For example, here is a simple project file using the &lt;antcall/&gt; task to invoke the &#8216;foo&#8217; target :</p>
<div>
<pre>&lt;project name=<span>"antcall"</span>&gt;

&lt;property name=<span>"A"</span> value=<span>"A"</span>/&gt;&lt;property name=<span>"B"</span> value=<span>"B"</span>/&gt;

&lt;property name=<span>"C"</span> value=<span>"C"</span>/&gt;

&lt;target name=<span>"foo"</span>&gt;&lt;echo&gt;A: ${A}&lt;/echo&gt;

&lt;echo&gt;B: ${B}&lt;/echo&gt;&lt;echo&gt;C: ${C}&lt;/echo&gt;&lt;/target&gt;

&lt;target name=<span>"foo.call.1"</span>&gt;

&lt;antcall target=<span>"foo"</span>&gt;&lt;/antcall&gt;&lt;/target&gt;

&lt;target name=<span>"foo.call.2"</span>&gt;&lt;antcall target=<span>"foo"</span>&gt;

 &lt;param name=<span>"A"</span> value=<span>"eh?"</span> /&gt; &lt;param name=<span>"B"</span> value=<span>"bee"</span> /&gt;

 &lt;param name=<span>"C"</span> value=<span>"sea"</span> /&gt;&lt;/antcall&gt;&lt;/target&gt;

&lt;/project&gt;</pre>
</div>
<p>And here is the same project file rewritten so that &#8216;foo&#8217; is a task:
<div>
<pre>&lt;project name=<span>"macrodef"</span>&gt;

&lt;macrodef name=<span>"foo"</span>&gt;&lt;attribute name=<span>"A"</span> <span>default</span>=<span>"A"</span> /&gt;&lt;attribute name=<span>"B"</span> <span>default</span>=<span>"B"</span> /&gt;

&lt;attribute name=<span>"C"</span> <span>default</span>=<span>"C"</span> /&gt;&lt;sequential&gt; &lt;echo&gt;A: @{A}&lt;/echo&gt;

 &lt;echo&gt;B: @{B}&lt;/echo&gt; &lt;echo&gt;C: @{C}&lt;/echo&gt;&lt;/sequential&gt;&lt;/macrodef&gt;

&lt;target name=<span>"foo.call.1"</span>&gt;&lt;foo/&gt;&lt;/target&gt;

&lt;target name=<span>"foo.call.2"</span>&gt;&lt;foo a=<span>"EH?"</span> b=<span>"BEE"</span> c=<span>"SEA"</span>/&gt;

&lt;/target&gt;

&lt;/project&gt;</pre>
</div>
<p>The difference between the approaches is subtle but important;
<ul>
<li>The &#8216;macrodef&#8217; project is going to be more maintainable because the &#8216;foo&#8217; task attributes are encapsulated (rather than using &lt;property/&gt; elements). </li>
<li>Eclipse automatically detects the new task and provides the attributes via auto-completion. This saves a person having to scroll down to the target definition to determine what parameters for an &lt;antcall&gt; are required. </li>
<li>The performance of the &#8216;macrodef&#8217; project will be better than the &#8216;antcall&#8217; project because the &lt;antcall/&gt; will actually create an entirely new project instance in memory. This is mentioned on the  <a target="_blank" href="http://wiki.apache.org/ant/NewAntFeaturesInDetail/MacroDef/"> ant wiki</a></li>
</ul>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/arity.wordpress.com/7/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/arity.wordpress.com/7/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/arity.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/arity.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/arity.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/arity.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/arity.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/arity.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/arity.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/arity.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/arity.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/arity.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/arity.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/arity.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/arity.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/arity.wordpress.com/7/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=arity.wordpress.com&amp;blog=8343867&amp;post=7&amp;subd=arity&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://arity.wordpress.com/2006/11/07/macrodef/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7b93ab5b8c5f5900ae30991c44201416?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">caleb_powell</media:title>
		</media:content>
	</item>
	</channel>
</rss>
