<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1613193234145521679</id><updated>2025-01-03T15:12:34.353-08:00</updated><category term="java"/><category term="java collections"/><category term="cache"/><category term="code"/><category term="duck typing"/><category term="dynamic proxies"/><category term="gwt"/><category term="i18n"/><title type='text'>Thinking in Code</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://thinking-in-code.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1613193234145521679/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://thinking-in-code.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Dean Povey</name><uri>http://www.blogger.com/profile/09086367210893430445</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCEQXgY3WXgevxZXsbbV8IUum-LjN8mEG_KVzOwwoormgzqucAkoLyxsv8dO36BqJgadae2uob6oqM_E0i6jVAkZP0l2MElDXVGEhxfOGFeB98sIbYvVGjPskiZpFhVw/s220/profile.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>10</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1613193234145521679.post-7289745005476818641</id><published>2011-07-01T20:27:00.000-07:00</published><updated>2011-07-01T20:29:48.801-07:00</updated><title type='text'>Google+ - First Impressions</title><content type='html'>I got an invite for &lt;a href=&quot;http://plus.google.com/&quot;&gt;Google+&lt;/a&gt; recently, before they shut down invites due to apparently &lt;a href=&quot;http://www.computerworld.com/s/article/9218068/Google_invites_shut_down_after_insane_demand_&quot;&gt;insane demand&lt;/a&gt;. I have to say I&#39;m impressed. While I have seen stories claiming that its many features are too complex to navigate, I didn&#39;t find that to be any particular problem. The menus/buttons are for the most part logically laid out, and everything seems close at hand when you need it.&lt;br /&gt;
&lt;br /&gt;
Circles are awesome. For the longest time I wanted on Facebook the ability to update status just for close friends or family, or to share some geek related post - in fact I used Buzz exclusively for this, since the only people I knew that were on it were geeks.  Circles makes that really easy.  You can drag and drop your friends into different circles (they can also be in more than one circle, although sadly you cannot drag one circle into another).  When you &quot;share&quot; stuff you can select if you want the post to be public or to involve one or more of your circles.  It works very nicely.&lt;br /&gt;
&lt;br /&gt;
I also had a quick play with the &quot;hangout&quot; feature.  This allows you to invite friends in your circle to a shared video/text chat.  On Chrome for Mac I had to install a plugin (the same one used for Google talk), but apart from that it was seemless. I chatted to one friend via video, and a second friend without a webcam chatted along on the text prompt. He commented that the camera switching to the speaker was done very nicely.&lt;br /&gt;
&lt;br /&gt;
Possibly the major benefit for me at least is this integrating into the sites I use like &lt;a href=&quot;http://mail.google.com/&quot;&gt;Gmail&lt;/a&gt;, &lt;a href=&quot;http://news.google.com/&quot;&gt;Google News&lt;/a&gt; and &lt;a href=&quot;http://www.google.com/&quot;&gt;Search&lt;/a&gt;.  I know that is a controversial step, but for those of us that cannot be bothered to constantly check our Facebook status this is a low noise way of adding notificatons into the ambient background of your daily browsing experience. This may be Google+&#39;s only way of competing with the likes of Facebook.  After all they have not had much success with social media given the failures of &lt;a href=&quot;http://www.orkut.com/&quot;&gt;Orkut&lt;/a&gt;, &lt;a href=&quot;http://wave.google.com/&quot;&gt;Google Wave&lt;/a&gt; and &lt;a href=&quot;http://buzz.google.com/&quot;&gt;Buzz&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
As a clean but featured re-entrance back into the social media game, Google+ shows that Google has learnt many of its lessons.  But whether it can attract a following anything like Facebook and Twitter remains to be seen.</content><link rel='replies' type='application/atom+xml' href='http://thinking-in-code.blogspot.com/feeds/7289745005476818641/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1613193234145521679/7289745005476818641' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1613193234145521679/posts/default/7289745005476818641'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1613193234145521679/posts/default/7289745005476818641'/><link rel='alternate' type='text/html' href='http://thinking-in-code.blogspot.com/2011/07/google-first-impressions.html' title='Google+ - First Impressions'/><author><name>Dean Povey</name><uri>http://www.blogger.com/profile/09086367210893430445</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCEQXgY3WXgevxZXsbbV8IUum-LjN8mEG_KVzOwwoormgzqucAkoLyxsv8dO36BqJgadae2uob6oqM_E0i6jVAkZP0l2MElDXVGEhxfOGFeB98sIbYvVGjPskiZpFhVw/s220/profile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1613193234145521679.post-6118525838911732087</id><published>2011-06-26T14:34:00.000-07:00</published><updated>2011-06-26T14:36:16.858-07:00</updated><title type='text'>Awesome hidden feature in Skype for Mac</title><content type='html'>The other day I was text chatting to a friend of mine on Skype. As you inevitably do when chatting I accidentally sent a typo (let&#39;s say I typed awrsome instead of awesome).&lt;br /&gt;
&lt;br /&gt;
Since I mostly chat with geeks who know what a sed search and replace command looks like, I have developed the convention over the years of doing the following when I accidentally type something I shouldn&#39;t have:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;&lt;/code&gt;&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;s/awrsome/awesome/&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
To my surprise, when I did that in the Skype chat it actually &lt;i&gt;did&lt;/i&gt; replace awrsome with awesome in the previous message!  Sadly it doesn&#39;t look like it supports regular expressions or full sed commands, but still nice!</content><link rel='replies' type='application/atom+xml' href='http://thinking-in-code.blogspot.com/feeds/6118525838911732087/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1613193234145521679/6118525838911732087' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1613193234145521679/posts/default/6118525838911732087'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1613193234145521679/posts/default/6118525838911732087'/><link rel='alternate' type='text/html' href='http://thinking-in-code.blogspot.com/2011/06/awesome-hidden-feature-in-skype-for-mac.html' title='Awesome hidden feature in Skype for Mac'/><author><name>Dean Povey</name><uri>http://www.blogger.com/profile/09086367210893430445</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCEQXgY3WXgevxZXsbbV8IUum-LjN8mEG_KVzOwwoormgzqucAkoLyxsv8dO36BqJgadae2uob6oqM_E0i6jVAkZP0l2MElDXVGEhxfOGFeB98sIbYvVGjPskiZpFhVw/s220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1613193234145521679.post-8045446188239825286</id><published>2010-07-22T23:48:00.000-07:00</published><updated>2010-07-23T00:07:00.432-07:00</updated><title type='text'>Train Model of Software Development</title><content type='html'>Traditionally software development has been considered a process in managing a classic 3 way trade-off, which looks something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSB6hKpV8NdUv_LnG_-JbewpPMnuhE0Z-jGAWfycokZcblb39pIE43l9N_Jpuxd1J88lRb44E-G4BG-Xgx0gQHxoqL0jciA54-VMKrhsaK-GXezcVwE4MsG7p5s7GVavcScaz8-XAhlPCg/s1600/3-way-tradeoff.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSB6hKpV8NdUv_LnG_-JbewpPMnuhE0Z-jGAWfycokZcblb39pIE43l9N_Jpuxd1J88lRb44E-G4BG-Xgx0gQHxoqL0jciA54-VMKrhsaK-GXezcVwE4MsG7p5s7GVavcScaz8-XAhlPCg/s320/3-way-tradeoff.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
The basic idea is that there is always a tension pulling in opposite directions in each of these dimensions. If you add more features you need to lower the quality or deliver later. If you compress the schedule you will need to reduce the quality or the number of features.&lt;br /&gt;
&lt;br /&gt;
However, the relationship is not that simple. Because software development is an exercise in constant refinement of unknowns, the three way trade-off ignores the fact that these decisions are made in the face of imprecise information. As a result there is a tendency to underestimate the effects of one of choosing these trade-offs. In particular trading off quality almost always leads to schedule slip, due to the accumulation of technical debt.&lt;br /&gt;
&lt;br /&gt;
Agile development in part works because there is a recognition that this three way trade-off model is fundamentally flawed. In a classic Agile project (e.g. SCRUM) you have a fixed schedule (the iteration), a fixed level of quality (passes the acceptance tests), and it is only the features that change.&lt;br /&gt;
&lt;br /&gt;
In a pure Scrum project, you would end every sprint with a release candidate. However, in practice the length of iterations does not accurately reflect the ebb and flow of a traditional software lifecycle, and as a result there has been a move towards a higher level release cycle which layers on top of this.&lt;br /&gt;
&lt;br /&gt;
The analogy used is to think of software releases like a train. A train leaves the station at regular intervals following a timetable published in advance. If someone/something misses the train then another one will come along soon. Releases are planned at regular intervals (e.g. quarterly, every six months), and features are sized accordingly to fit that schedule. If a feature looks like it won&#39;t make it, it will be dropped and appear in the next release.&lt;br /&gt;
&lt;br /&gt;
This model is used very successfully in a number of products (e.g. Eclipse, Ubuntu), and is well suited to software products. The customers and the Product Manager (PM) know that there is going to be a certain release at a certain time and can plan around it. If the PM has a high priority feature/bug fix, they can tell the customer with some degree of certainty when that will appear. Marketing knows in advance when a product will be released (although they don&#39;t necessarily know in advance exactly what will be in it). Developers have a clear goal on what to deliver, and performance can be easily measured on a regular basis.&lt;br /&gt;
&lt;br /&gt;
Each release has a lifecycle that gets it out on the release train. While obviously those processes can vary, there are some basic phases which I have given below:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;i&gt;Envisioning&lt;/i&gt;: This is the initial planning and R&amp;amp;D phase that begins each major release cycle. Features are planned for the release and broken down into user stories; UI mockups are developed and reviewed; any design or prototyping that needs to be done is covered.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Feature development&lt;/i&gt;: This is the standard sprint/iteration where features are developed and delivered. Care must be taken to ensure that this development is sustainable meaning that the testing effort can keep up with the development pace. Features should not be considered finished until they pass all their User Acceptance Tests which should be written at the time the story/feature is defined (and ideally automated).&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Hardening&lt;/i&gt;: This is the end of phase when much more rigorous testing is performed, release engineering and packaging is performed and bug fixes are made to ready for release. If the feature development phase is done properly the bug fixing is going to be minimal, however there will always be some as testing becomes less confirming and more adverserial.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
For example, suppose we want to develop a train schedule that allows for about 2 major releases a year, and allows for a minor release in the off quarters if required. This would require splitting the team into maintenance and research for about one quarter, before merging the development together. The train would look something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiovBUm62V5xr4BGyBjTOIs36_47ilQnihNibdHkRq6YoUDkZe4r3auV5tPA3qA3CT3P4ADXJ2qemfrkryvhFudGZ3C52Zzr_6HDR0L2YgRXZ9wiQcI4ivHhTN28GPeMXXiX5dwhsn79_dK/s1600/train-schedule.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;147&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiovBUm62V5xr4BGyBjTOIs36_47ilQnihNibdHkRq6YoUDkZe4r3auV5tPA3qA3CT3P4ADXJ2qemfrkryvhFudGZ3C52Zzr_6HDR0L2YgRXZ9wiQcI4ivHhTN28GPeMXXiX5dwhsn79_dK/s640/train-schedule.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
At the end of every major release the team splits into two, with most people working on maintenance (bug fixes that didn&#39;t make the previous train, minor refactoring, automating tests etc), while a smaller group move into the envisioning phase for the next major release. In the second sprint, the minor release team moves onto minor features before hardening for a dot release in the third sprint. A fairly modest amount of work can be done in this amount of time so the focus is on improving quality and getting features that missed the last train. Meanwhile envisioning will take about 4-8 weeks after which time work on major features can begin. Depending on the resource needs there can be some drift between teams in this phase. If the needs of the minor release are modest more work can be done on starting the major features. If the minor release needs more polish/testing then resources can move on to this. At the end of the quarter the minor release should go out. Alternatively it may be decided that there is no pressing urgency to do a minor release and these fixes can simply go out in the next major release.&lt;br /&gt;
&lt;br /&gt;
Now the major feature development begins in earnest. It is critically important at this stage that major features are correctly prioritized and that development is proceeding at a sustainable pace. The goal is to deliver only finished features, so that means not starting on features until others are finished in order to reduce the risk that in the hardening phase there will be an unsustainably large number of bugs.&lt;br /&gt;
&lt;br /&gt;
There is a fair degree of flexibility in this release process. For example, a minor release can be all maintenance with no additional features, or not released at all. Envisioning may take only a short amount of time leaving more time for feature development, or it may take a full quarter meaning only a minor amount can be done. I have used a quarter as a unit of release, but six months, or an off number (say 7 or 9 months) may be more appropriate. &lt;br /&gt;
&lt;br /&gt;
The only thing that needs to stay consistent are the release points. The reason for this is that if the tidal flow of the project stays consistent, then there will be much better predictability, a lot more happiness and much better results for customers and PM.&lt;br /&gt;
&lt;br /&gt;
The train model has been well proven. I would argue it is a sign of maturity in most teams that they move to something like this more predictable process than the chaos that attends most software development. PM needs to be prepared to give up the fact that major releases will not have everything they want, but the train model allows them to get the things that are important out to customers sooner. I would argue that this delivers considerably more value to customers than shipping them features late that they may or may not need. &lt;br /&gt;
&lt;br /&gt;
It also allows a much more agile response to the inevitable customer feedback you get as a result of releasing your product. If you can only do a major release once every 18 or 24 months then customers will die of boredom waiting for new features. If you can do it twice a year, with minor releases between for those things that are important but can&#39;t be delivered on time, your customers will love you.</content><link rel='replies' type='application/atom+xml' href='http://thinking-in-code.blogspot.com/feeds/8045446188239825286/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1613193234145521679/8045446188239825286' title='34 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1613193234145521679/posts/default/8045446188239825286'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1613193234145521679/posts/default/8045446188239825286'/><link rel='alternate' type='text/html' href='http://thinking-in-code.blogspot.com/2010/07/train-model-of-software-development.html' title='Train Model of Software Development'/><author><name>Dean Povey</name><uri>http://www.blogger.com/profile/09086367210893430445</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCEQXgY3WXgevxZXsbbV8IUum-LjN8mEG_KVzOwwoormgzqucAkoLyxsv8dO36BqJgadae2uob6oqM_E0i6jVAkZP0l2MElDXVGEhxfOGFeB98sIbYvVGjPskiZpFhVw/s220/profile.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSB6hKpV8NdUv_LnG_-JbewpPMnuhE0Z-jGAWfycokZcblb39pIE43l9N_Jpuxd1J88lRb44E-G4BG-Xgx0gQHxoqL0jciA54-VMKrhsaK-GXezcVwE4MsG7p5s7GVavcScaz8-XAhlPCg/s72-c/3-way-tradeoff.png" height="72" width="72"/><thr:total>34</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1613193234145521679.post-7884568806248976999</id><published>2010-06-05T19:09:00.000-07:00</published><updated>2010-06-05T19:17:07.161-07:00</updated><title type='text'>Preventing Internet Explorer from caching AJAX requests when using GWT RequestBuilder</title><content type='html'>I recently spent the best part of a few days trying to work out why some GWT HTTP code I had written was not working (well specifically why it was not working on Internet Explorer).  The code was talking to an existing server API that used HTTP GET for a handshake to establish a session-id with the server, and thereafter used HTTP POST to retrieve data.  The problem occurred when it attempted to re-handshake.  It would always return the same session-id, whereas the server would expect a different session-id. It was all very confusing, until I did some HTTP level tracing and noticed that past the first GET call, the server would never see another GET request.&lt;br /&gt;
&lt;br /&gt;
It turns out, for reasons best known to itself, Internet Explorer will aggressively cache GET requests when using the XMLHttpRequest object.  When writing an AJAX application this is particularly painful if you want your result to be dynamic.&lt;br /&gt;
&lt;br /&gt;
If you can modify the server, the best approach is to ensure that the server correctly sets the &lt;code&gt;Cache-Control: no-cache&lt;/code&gt; header, but this is not always possible if you are working with a legacy backend.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;Another solution is to use an HTTP POST instead, but again that&#39;s a problem if you working with existing code, or you are writing to a REST API and you want to keep the GET = Read and POST = Create idiom.&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
If you want to force the client to get it right this narrows your choices.&lt;br /&gt;
&lt;br /&gt;
A commonly suggested approach is to generate a random request parameter and add this to your request either by appending &lt;code&gt;?requestId=r4nd0m-v4lu3&lt;/code&gt; to the URI, or if your request already includes parameters appending &lt;code&gt;&amp;amp;requestId=r4nd0m-v4lu3&lt;/code&gt;. While this means you won&#39;t see the cached responses, the browser still does put these items in the cache, and if you are doing a large number of these requests, this will start to evict things that you actually want to be in there! It may also be a problem if your application enforces strict checking of the passed in parameters.&lt;br /&gt;
&lt;br /&gt;
The best approach I have found is to use the &lt;code&gt;If-Modified-Since&lt;/code&gt; header with the date set to the Epoch (1970-01-01 00:00:00 GMT).  The browser will not cache the result, and you will not have to worry about clashing with existing parameters.  The nice thing about this approach is it is a general solution which you can put in a library and then not worry about problems with the backend.&lt;br /&gt;
&lt;br /&gt;
To do this when using the Google Web Toolkit (GWT) RequestBuilder interface it is simply a matter of using the setHeader method as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: java&quot; name=&quot;code&quot;&gt;void nonCachingHttpGet(String uri, String data, RequestCallback callback)
     RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, uri);
     // This header is required to force Internet Explorer to not cache values from
     // the GET response.
     builder.setHeader(&quot;If-Modified-Since&quot;, &quot;01 Jan 1970 00:00:00 GMT&quot;);
     builder.setHeader(&quot;Content-type&quot;,
                       &quot;application/x-www-form-urlencoded&quot;);
     builder.setCallback(callback);
     builder.send();
}
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://thinking-in-code.blogspot.com/feeds/7884568806248976999/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1613193234145521679/7884568806248976999' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1613193234145521679/posts/default/7884568806248976999'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1613193234145521679/posts/default/7884568806248976999'/><link rel='alternate' type='text/html' href='http://thinking-in-code.blogspot.com/2010/06/preventing-internet-explorer-from.html' title='Preventing Internet Explorer from caching AJAX requests when using GWT RequestBuilder'/><author><name>Dean Povey</name><uri>http://www.blogger.com/profile/09086367210893430445</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCEQXgY3WXgevxZXsbbV8IUum-LjN8mEG_KVzOwwoormgzqucAkoLyxsv8dO36BqJgadae2uob6oqM_E0i6jVAkZP0l2MElDXVGEhxfOGFeB98sIbYvVGjPskiZpFhVw/s220/profile.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1613193234145521679.post-3995825436913898347</id><published>2010-05-24T23:56:00.000-07:00</published><updated>2010-05-25T18:42:12.015-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="gwt"/><category scheme="http://www.blogger.com/atom/ns#" term="i18n"/><category scheme="http://www.blogger.com/atom/ns#" term="java"/><title type='text'>Writing unit tests when using GWT&#39;s Static String Internationalization (I18n) feature</title><content type='html'>The &lt;a href=&quot;http://code.google.com/webtoolkit/&quot;&gt;Google Web Toolkit (GWT)&lt;/a&gt; has a fairly simple infrastructure for managing internationalization.  While there are a number of different options, the easiest one to use is called &lt;a href=&quot;http://code.google.com/webtoolkit/doc/1.6/DevGuideI18nAndA11y.html&quot;&gt;Static String Internationalization&lt;/a&gt; The basic idea is that you create a properties file for each language and GWT&#39;s deferred binding process creates an instance of a Interface which will be loaded depending on the locale.  It works something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Create a properties file (e.g. FooConstants.properties).  This will contain definitions of the form &lt;code&gt;bar=A string that I want to i18n.&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Use the &lt;code&gt;i18nCreator&lt;/code&gt; script to generate the Interface definition: &lt;code&gt;i18nCreator -eclipse Foo com.example.foo.client.FooConstants&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;In your code call &lt;code&gt;GWT.create()&lt;/code&gt; to instantiate an instance. e.g:&lt;br /&gt;
&lt;pre name=&quot;code&quot; class=&quot;brush: java&quot;&gt;public static class MessageDisplayer {
    public MessageDisplayer(Alerter alerter) {
        FooConstants constants = (FooConstants) GWT.create(FooConstants.class);
            alerter.alert(FooConstants.bar());
        }
    }
}
&lt;/pre&gt;&lt;/ol&gt;The problem with this is that calling GWT.create from within your code makes it difficult to unit test.  If your code calls this directly then you will have to create your unit tests using GWT&#39;s &lt;a href=&quot;http://code.google.com/webtoolkit/doc/1.6/DevGuideTesting.html#DevGuideJUnitIntegration&quot;&gt;Junit3 hack&lt;/a&gt;.  Running unit tests this way is very slow, and I find it much better to try and factor out as much GWT specific code as possible so that you can write normal boring tests (for example using JUnit 4, or using mocks, or whatever else that GWT tests don&#39;t support that takes your fancy).  The trick is that if you have any code that relies on an instance of these Constants/Messages files then you are screwed.  The solution is to use a DynamicProxy to generate an instance of the interface and then inject these into your code.  First we need to refactor our class to have the Constants interface injected, e.g:      &lt;pre name=&quot;code&quot; class=&quot;brush: java&quot;&gt;public static class MessageDisplayer {
    public MessageDisplayer(Alerter alerter, FooConstants constants) {
        alerter.alert(FooConstants.bar());
    }
}&lt;/pre&gt;Next we need to write some code to generate the constants.  When the i18nCreator generates the interface it helpfully annotates it with the default text it needs.  We can exploit this to generate an instance for testing:     &lt;pre name=&quot;code&quot; class=&quot;brush: java&quot;&gt;public class ConstantsMocker implements InvocationHandler {
     @SuppressWarnings(&quot;unchecked&quot;)
     public static &amp;lt;T&amp;gt; T get(Class&amp;lt;? extends T&amp;gt; i18nInterface) {
         return (T) Proxy.newProxyInstance(i18nInterface.getClassLoader(),
                  new Class&amp;lt;?&amp;gt;[] { i18nInterface },
                  new ConstantsMocker());
     }
     public static final String NO_DEFAULT_MESSAGE = &quot;[No Default Message Defined]&quot;;

     @Override
     public Object invoke(Object proxy, Method method, Object[] args)
             throws Throwable {
         DefaultMessage message = method.getAnnotation(DefaultMessage.class);
         if (message == null) {
             return NO_DEFAULT_MESSAGE;
         }
         return message.value();
     }
} &lt;/pre&gt;Now when we write our test we can pass down an instance, e.g  &lt;pre name=&quot;code&quot; class=&quot;brush: java&quot;&gt;@Test
    public void whenConstructorIsCalledAlerterAlertIsCalled {
        AtomicBoolean wasAlerted = new AtomicBoolean(false);
        FooConstants fooConstants = ConstantsMocker.get(FooConstants.class);
        final String expected = fooConstants.bar();
        Alerter alerter = new Alerter() {
            void alert(String msg) {
                assertEquals(expected, msg);
                wasAlerted.set(true);
            }
        }
        new MessageDisplayer(alerter, fooConstants);
        assertTrue(wasAlerted.get());
    }
&lt;/pre&gt;Whilst this is a toy example it can be a very useful technique if used carefully.  Note that regular GWT code just injects the instance from GWT.create() as follows:    &lt;pre name=&quot;code&quot; class=&quot;brush: java&quot;&gt;MessageDisplayer displayer = 
      new MessageDisplayer(Alerter, (FooConstants)GWT.create(FooConstants.java));
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://thinking-in-code.blogspot.com/feeds/3995825436913898347/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1613193234145521679/3995825436913898347' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1613193234145521679/posts/default/3995825436913898347'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1613193234145521679/posts/default/3995825436913898347'/><link rel='alternate' type='text/html' href='http://thinking-in-code.blogspot.com/2010/05/writing-unit-tests-when-using-gwts.html' title='Writing unit tests when using GWT&#39;s Static String Internationalization (I18n) feature'/><author><name>Dean Povey</name><uri>http://www.blogger.com/profile/09086367210893430445</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCEQXgY3WXgevxZXsbbV8IUum-LjN8mEG_KVzOwwoormgzqucAkoLyxsv8dO36BqJgadae2uob6oqM_E0i6jVAkZP0l2MElDXVGEhxfOGFeB98sIbYvVGjPskiZpFhVw/s220/profile.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1613193234145521679.post-2068900809247833239</id><published>2010-05-16T01:35:00.001-07:00</published><updated>2010-05-25T18:33:11.358-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="cache"/><category scheme="http://www.blogger.com/atom/ns#" term="java collections"/><title type='text'>Creating a bounded LRU Cache with LinkedHashMap</title><content type='html'>I recently had cause to implement a fixed size cache in some code was writing.  I wanted a straightforward map, but with a fixed size and the ability to evict on a least-recently-used (LRU) basis.  I thought quickly to get something up and running that I would use a LinkedHashMap and then have my get and put methods use the ordering to implement the LRU policy.&lt;br /&gt;
&lt;br /&gt;
Well it turns out that LinkedHashMap already has this support built-in if you know what you&#39;re doing.  There are two parts of this jigsaw:&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Override the protected &lt;code&gt;removeEldestEntry&lt;/code&gt; method which returns a boolean if the eldest entry should be removed.  This method is called for every put with the element that&lt;br /&gt;
is eldest according the LRU policy.&lt;br /&gt;
&lt;li&gt;Call the &lt;code&gt;LinkedHashMap(int capacity, float loadFactor, boolean accessOrder)&lt;/code&gt; constructor.  Specifying &lt;code&gt;true&lt;/code&gt; for &lt;code&gt;accessOrder&lt;/code&gt; means that the order of the elements will be sorted in the order they were last accessed (from least recently used to most recently used).&lt;br /&gt;
&lt;/ol&gt;Putting this together yields: &lt;pre name=&quot;code&quot; class=&quot;brush: java&quot;&gt;public class BoundedLruCache&amp;lt;KEY, TYPE&amp;gt; extends LinkedHashMap&amp;lt;KEY, TYPE&amp;gt; {

    private static  final int DEFAULT_INITIAL_CAPACITY = 100;

    private static final float DEFAULT_LOAD_FACTOR = 0.75;

    private final int bound;

    public BoundedLruCache(final int bound) {
        super(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, true);
        this.bound = bound;
    }

    @Override
    protected boolean removeEldestEntry(Map.Entry&amp;lt;KEY, TYPE&amp;gt; eldest) {
        return size() &amp;gt; bound;
    }
}
&lt;/pre&gt;Which is remarkably compact.  Once again the JRE library proves to have some nice bits and pieces if you know where to look.</content><link rel='replies' type='application/atom+xml' href='http://thinking-in-code.blogspot.com/feeds/2068900809247833239/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1613193234145521679/2068900809247833239' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1613193234145521679/posts/default/2068900809247833239'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1613193234145521679/posts/default/2068900809247833239'/><link rel='alternate' type='text/html' href='http://thinking-in-code.blogspot.com/2010/05/creating-bounded-lru-cache-with.html' title='Creating a bounded LRU Cache with LinkedHashMap'/><author><name>Dean Povey</name><uri>http://www.blogger.com/profile/09086367210893430445</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCEQXgY3WXgevxZXsbbV8IUum-LjN8mEG_KVzOwwoormgzqucAkoLyxsv8dO36BqJgadae2uob6oqM_E0i6jVAkZP0l2MElDXVGEhxfOGFeB98sIbYvVGjPskiZpFhVw/s220/profile.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1613193234145521679.post-7968581151160966999</id><published>2010-04-20T06:04:00.000-07:00</published><updated>2010-05-16T23:02:12.260-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="java collections"/><title type='text'>Collections.addAll for adding an array of elements to a Collection</title><content type='html'>Shows there is always more that you can learn about the JRE.  I have been for ages using the following idiom to add an array of items to a collection:&lt;br /&gt;
&lt;br /&gt;
&lt;pre name=&quot;code&quot; class=&quot;brush: java&quot;&gt;Collection&amp;lt;Foo&amp;gt; foos = ...;
Foo[] foosToAdd = ...;
foos.addAll(Arrays.asList(foosToAdd);
&lt;/pre&gt;&lt;br /&gt;
What I hadn&#39;t noticed is that the &lt;code&gt;java.util.Collections&lt;/code&gt; class has a static method that does this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre name=&quot;code&quot; class=&quot;brush: java&quot;&gt;Collection&amp;lt;Foo&amp;gt; foos = ...;
Foo[] foosToAdd = ...;
Collections.addAll(foos, foosToAdd);
&lt;/pre&gt;&lt;br /&gt;
Which is not only a little bit simpler but the javadoc says is faster for most implementations of &lt;code&gt;Collection&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
Better yet, &lt;code&gt;Collections.addAll&lt;/code&gt; takes a variable length argument list and not just a straight array so you can do without the array declaration and just do:&lt;br /&gt;
&lt;br /&gt;
&lt;pre name=&quot;code&quot; class=&quot;brush: java&quot;&gt;Collection&amp;lt;Foo&amp;gt; foos = ...;
Collections.addAll(foos, foo1, foo2, etc);
&lt;/pre&gt;&lt;br /&gt;
See: &lt;a href=&quot;http://java.sun.com/javase/6/docs/api/java/util/Collections.html#addAll(java.util.Collection, T...)&quot;&gt;Collections.addAll Javadoc&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://thinking-in-code.blogspot.com/feeds/7968581151160966999/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1613193234145521679/7968581151160966999' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1613193234145521679/posts/default/7968581151160966999'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1613193234145521679/posts/default/7968581151160966999'/><link rel='alternate' type='text/html' href='http://thinking-in-code.blogspot.com/2010/04/collectionsaddall-for-adding-array-of.html' title='Collections.addAll for adding an array of elements to a Collection'/><author><name>Dean Povey</name><uri>http://www.blogger.com/profile/09086367210893430445</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCEQXgY3WXgevxZXsbbV8IUum-LjN8mEG_KVzOwwoormgzqucAkoLyxsv8dO36BqJgadae2uob6oqM_E0i6jVAkZP0l2MElDXVGEhxfOGFeB98sIbYvVGjPskiZpFhVw/s220/profile.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1613193234145521679.post-6028130757175334814</id><published>2009-07-07T18:23:00.000-07:00</published><updated>2009-07-07T18:40:53.999-07:00</updated><title type='text'>Switching between 64 bit and 32 bit JVMs in Windows</title><content type='html'>I run Vista 64 bit on my laptop to get at the ludicrous 6Gb of memory that I seem to need to do my work these days.  However I find that because of native library dependencies there are often times when I need to switch between 32 and 64 bit JVMs.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To do so I hacked together this simple batch file which allows you to simply switch &lt;code&gt;JAVA_HOME&lt;/code&gt;:&lt;/div&gt;&lt;br /&gt;&lt;div&gt;xjava.bat:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;@echo off&lt;br /&gt;@rem Allow swiching between 64 and 32 bit versions of jvm. &lt;br /&gt;&lt;br /&gt;SET OLD_JAVA_HOME=%JAVA_HOME%&lt;br /&gt;&lt;br /&gt;@rem Process switch &lt;br /&gt;set XJAVA_SWITCH=%1&lt;br /&gt;shift&lt;br /&gt;if &quot;%XJAVA_SWITCH%&quot; == &quot;&quot; goto DISPLAY_CURRENT&lt;br /&gt;if &quot;%XJAVA_SWITCH%&quot; == &quot;-64&quot; goto SET_64 &lt;br /&gt;if &quot;%XJAVA_SWITCH%&quot; == &quot;-32&quot; goto SET_32&lt;br /&gt;goto DISPLAY_JAVA_HOME_AND_CHECK_FOR_CMD_TO_EXEC&lt;br /&gt;&lt;br /&gt;:SET_32&lt;br /&gt;if &quot;%JAVA_32_HOME%&quot; == &quot;&quot; goto ERROR_32 &lt;br /&gt;set JAVA_HOME=%JAVA_32_HOME%&lt;br /&gt;goto DISPLAY_JAVA_HOME_AND_CHECK_FOR_CMD_TO_EXEC&lt;br /&gt;&lt;br /&gt;:ERROR_32&lt;br /&gt;echo Error: JAVA_32_HOME not set.&lt;br /&gt;goto DONE&lt;br /&gt;&lt;br /&gt;:SET_64&lt;br /&gt;if &quot;%JAVA_64_HOME%&quot; == &quot;&quot; goto ERROR_64 &lt;br /&gt;set JAVA_HOME=%JAVA_64_HOME%&lt;br /&gt;goto DISPLAY_JAVA_HOME_AND_CHECK_FOR_CMD_TO_EXEC&lt;br /&gt;&lt;br /&gt;:ERROR_64&lt;br /&gt;echo Error: JAVA_64_HOME not set.&lt;br /&gt;goto DONE&lt;br /&gt;&lt;br /&gt;:DISPLAY_CURRENT&lt;br /&gt;@ECHO JAVA_HOME=%JAVA_HOME%&lt;br /&gt;goto DONE&lt;br /&gt;&lt;br /&gt;:DISPLAY_JAVA_HOME_AND_CHECK_FOR_CMD_TO_EXEC&lt;br /&gt;@rem Display JAVA_HOME&lt;br /&gt;@ECHO JAVA_HOME=%JAVA_HOME%&lt;br /&gt;if &quot;%JAVA_HOME%&quot; == &quot;%JAVA_32_HOME&quot; echo &quot;Using 32 bit JVM&quot;&lt;br /&gt;if &quot;%JAVA_HOME%&quot; == &quot;%JAVA_64_HOME&quot; echo &quot;Using 64 bit JVM&quot;&lt;br /&gt;&lt;br /&gt;@rem Check for java command to execute, otherwise we just set JAVA_HOME &lt;br /&gt;if &quot;%1&quot; == &quot;&quot; goto DONE&lt;br /&gt;set _ARGS=%*&lt;br /&gt;set _ARGS=%_ARGS:-32=%&lt;br /&gt;set _ARGS=%_ARGS:-64=%&lt;br /&gt;&quot;%JAVA_HOME%/bin/java&quot; %_ARGS% &lt;br /&gt;set JAVA_HOME=%OLD_JAVA_HOME%&lt;br /&gt;goto DONE&lt;br /&gt;&lt;br /&gt;:DONE&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Save as xjava.bat somwhere on your path. You then need to define the environment variables: &lt;code&gt;JAVA_32_HOME&lt;/code&gt; and &lt;code&gt;JAVA_64_HOME&lt;/code&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You then use this as follows:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Print the current &lt;code&gt;JAVA_HOME&lt;/code&gt;: &lt;code&gt;xjava&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Switch to 32 bit VM: &lt;code&gt;xjava -32&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Switch to 64 bit VM: &lt;code&gt;xjava -64&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Run java with &lt;code&gt;JAVA_HOME&lt;/code&gt; set to the appropriate vm: &lt;code&gt;xjava [-32|-64]  MyClass&lt;/code&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thinking-in-code.blogspot.com/feeds/6028130757175334814/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1613193234145521679/6028130757175334814' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1613193234145521679/posts/default/6028130757175334814'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1613193234145521679/posts/default/6028130757175334814'/><link rel='alternate' type='text/html' href='http://thinking-in-code.blogspot.com/2009/07/switching-between-64-bit-and-32-bit.html' title='Switching between 64 bit and 32 bit JVMs in Windows'/><author><name>Dean Povey</name><uri>http://www.blogger.com/profile/09086367210893430445</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCEQXgY3WXgevxZXsbbV8IUum-LjN8mEG_KVzOwwoormgzqucAkoLyxsv8dO36BqJgadae2uob6oqM_E0i6jVAkZP0l2MElDXVGEhxfOGFeB98sIbYvVGjPskiZpFhVw/s220/profile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1613193234145521679.post-1602311648412859513</id><published>2009-03-18T17:53:00.000-07:00</published><updated>2009-03-18T18:13:18.860-07:00</updated><title type='text'>Running GWTTestSuite in JUnit 4.4 without the ClassCastException</title><content type='html'>Running unit tests using the Google Web Toolkit that extends GWTTestCase can be very slow and time consuming, since the JUnitShell has to be restarted for each test.  You can speed up testing a lot by instead using GWTTestSuite to group these tests into a single suite than only needs to start the JUnitShell once.  The &lt;a href=&quot;http://code.google.com/docreader/#p=google-web-toolkit-doc-1-5&amp;amp;s=google-web-toolkit-doc-1-5&amp;amp;t=DevGuideJUnitSuites&quot;&gt;developer&#39;s guide&lt;/a&gt; gives the following example:&lt;code&gt;&lt;br /&gt;&lt;pre&gt;public class MapsTestSuite extends GWTTestSuite {&lt;br /&gt;    public static Test suite() {&lt;br /&gt;        TestSuite suite = new TestSuite(&quot;Test for a Maps Application&quot;);&lt;br /&gt;        suite.addTestSuite(MapTest.class);&lt;br /&gt;        suite.addTestSuite(EventTest.class);&lt;br /&gt;        suite.addTestSuite(CopyTest.class);&lt;br /&gt;        return suite;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/code&gt;However, running this using the junit.testui.TestRunner in JUnit4.4  (for example if you are running from the command line using the Maven GWT plugin) gives the following helpful error:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Error: java.lang.ClassCastException&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Instead you want to do the following:&lt;br /&gt;&lt;pre&gt;public class MapsTestSuite extends TestCase {&lt;br /&gt;    public static Test suite() {&lt;br /&gt;        GWTTestSuite suite = new GWTTestSuite(&quot;Test for a Maps Application&quot;);&lt;br /&gt;        suite.addTestSuite(MapTest.class);&lt;br /&gt;        suite.addTestSuite(EventTest.class);&lt;br /&gt;        suite.addTestSuite(CopyTest.class);&lt;br /&gt;        return suite;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;i.e. Extend TestCase rather than GWTTestSuite to overcome this problem.&lt;br /&gt;&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://thinking-in-code.blogspot.com/feeds/1602311648412859513/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1613193234145521679/1602311648412859513' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1613193234145521679/posts/default/1602311648412859513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1613193234145521679/posts/default/1602311648412859513'/><link rel='alternate' type='text/html' href='http://thinking-in-code.blogspot.com/2009/03/running-gwttestsuite-in-junit-44.html' title='Running GWTTestSuite in JUnit 4.4 without the ClassCastException'/><author><name>Dean Povey</name><uri>http://www.blogger.com/profile/09086367210893430445</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCEQXgY3WXgevxZXsbbV8IUum-LjN8mEG_KVzOwwoormgzqucAkoLyxsv8dO36BqJgadae2uob6oqM_E0i6jVAkZP0l2MElDXVGEhxfOGFeB98sIbYvVGjPskiZpFhVw/s220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1613193234145521679.post-4641697310094573662</id><published>2008-11-13T16:54:00.000-08:00</published><updated>2008-11-16T18:32:02.162-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="code"/><category scheme="http://www.blogger.com/atom/ns#" term="duck typing"/><category scheme="http://www.blogger.com/atom/ns#" term="dynamic proxies"/><category scheme="http://www.blogger.com/atom/ns#" term="java"/><title type='text'>Duck Typing in Java using Dynamic Proxies</title><content type='html'>&lt;div&gt;I have a confession to make: I am a lazy typer. And if there is one thing I can&#39;t stand it&#39;s having to type the same thing more times than I have to. If you had to pick the most useful thing about Object Oriented languages, it would be the fact that using them results in less typing.  And if you had to pick the one concept in OO that makes that possible, polymorphism would be it.  The idea that you can take objects that represent different concepts and treat them similarly is a powerful one, presenting a lot of opportunities for code reuse that would otherwise be difficult or impossible.&lt;/div&gt;&lt;br /&gt;In Java, polymorphism (as in other strongly type languages) is achieved by using inheritance, either by having Classes extend a common base class, or by implementing shared interfaces. This allows the compiler to enforce strict checking about which objects can and can not be used polymorphically.&lt;br /&gt;&lt;br /&gt;However, there are a number of downsides to requiring inheritance for polymorphism. Sometimes you may be dealing with legacy classes that you cannot change to extend a base class, or implement a specific interface, requiring you to write wrapper classes or adapters.  In other cases there may not be a natural common interface leading you to torture your hierarchy to come up with an artificial one.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;In addition, requiring classes to implement a specific interface just so that they can be used polymorphically, is unecessary coupling that represents bad design. One of the lessons learnt from Spring and other container frameworks is that there is virtue in not binding yourself to a specific type hierarchy in order to provide generic functionality.  Rather than having classes which either extend abstract classes or implement a bunch of interfaces, you should be able to just write POJOs and have the framework work out what to do with them.  In Spring we use either annotations, convention, or XML mapping files to tell the framework how to make sense of what a particular POJO is attempting to do.  The virtue of this is that you can get the benefits of&lt;/div&gt;&lt;div&gt;running in Spring, without binding yourself to anything about the Spring container. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In dynamic languages such as Python and Groovy we are able to take a different approach to polymorphism that avoids some of these problems, using a concept known as Duck Typing. Rather than using the type hierarchy to determine whether we can use classes polymorphically, we just assume that if two methods have the same signature, then they probably mean the same thing, ie. rather than determining whether something IS-A duck, we just care that it WALKS-like-a duck and QUACKS-like-a duck[&lt;a href=&quot;http://www.blogger.com/post-edit.g?blogID=1613193234145521679&amp;amp;postID=4641697310094573662#1&quot;&gt;1&lt;/a&gt;].&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;This concept is best illustrated by an example[&lt;a href=&quot;http://www.blogger.com/post-edit.g?blogID=1613193234145521679&amp;amp;postID=4641697310094573662#2&quot;&gt;2&lt;/a&gt;].  Suppose we have the following Groovy code:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;class Duck {&lt;br /&gt;def quack() { &quot;a loud Quaaaaaaaaaaaaack!&quot; }&lt;br /&gt;def walk()  { &quot;waddle&quot; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Person {&lt;br /&gt;def quack() { &quot;a person making a quacking sound.&quot; }&lt;br /&gt;def walk()  { &quot;walk&quot; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def tellAStoryAbout(something) {&lt;br /&gt;println &quot;One day while walking in the forest I heard &quot; + something.quack()&lt;br /&gt;println &quot;Intrigued, I turned round to see a dark shape &quot; + something.walk() +&lt;br /&gt;        &quot; off into the bushes.&quot;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;tellAStoryAbout(new Duck())&lt;br /&gt;tellAStoryAbout(new Person())&lt;/code&gt;&lt;/pre&gt;Which generates the following output:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;One day while walking in the forest I heard a loud Quaaaaaaaaaaaaack!&lt;br /&gt;Intrigued, I turned round to see a dark shape waddle off into the bushes.&lt;br /&gt;One day while walking in the forest I heard a person making a quacking sound.&lt;br /&gt;Intrigued, I turned round to see a dark shape walk off into the bushes.&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;We can see here, that using duck typing (which Groovy supports natively), allows us to treat the two classes Person and Duck polymorphically, without requiring them to be part of the same type hierarchy.  This is nice, because in this particular example, it&#39;s hard to think of a really good superclass for both a duck and a person that encapsulates this functionality.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;h3&gt;Duck Typing in Java&lt;/h3&gt;&lt;div&gt;Being that Java is a strongly typed language, providing this sort of Duck Typing support is not exactly straightforward.  Of course it is possible to use reflection to directly invoke the methods on each of the classes, but this is somewhat cumbersome and inelegant.  Another approach is to specify an interface with the methods you wish to use, and then use a Dynamic Proxy to generate an implementation that wraps the classes you wish to invoke methods on.  This has the benefit of a very compact syntax and the fact that as far as consumers of the Duck-typed objects they are just seeing normal interfaces.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To do this we first create a DuckType class with a static factory method:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;public static DuckType coerce(Object object)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;and then create a single method which will then allow us to specify the type we&lt;br /&gt;wish to coerce to:&lt;br /&gt;&lt;pre&gt;&lt;code&gt; public &lt;t&gt; T to(Class&lt;t&gt; iface)&lt;/t&gt;&lt;/t&gt;&lt;/code&gt;&lt;/pre&gt;This gives us a rather simple syntax for specifying type coercions.  We can then&lt;br /&gt;either then pass in already coerced types to methods, e.g:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;static import example.DuckType.*;&lt;br /&gt;&lt;br /&gt;interface Foo {&lt;br /&gt;String bar();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Bar {&lt;br /&gt;String bar() { &quot;A man walks into a bar...&quot;; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class FooBar {&lt;br /&gt;String bar() { &quot;foo bar baz qux&quot;; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;void method(Foo foo) {&lt;br /&gt;System.out.println(foo.bar());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;method(coerce(new Bar()).to(Foo.class));&lt;br /&gt;method(coerce(new FooBar()).to(Foo.class));&lt;/code&gt;&lt;/pre&gt;or alternatively we can just have a method take an Object and perform the type&lt;br /&gt;coercion itself, e.g.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;static import example.DuckType.*;&lt;br /&gt;&lt;br /&gt;interface Foo {&lt;br /&gt;String bar();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Bar {&lt;br /&gt;String bar() { &quot;A man walks into a bar...&quot;; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class FooBar {&lt;br /&gt;String bar() { &quot;foo bar baz qux&quot;; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void method(Object object) {&lt;br /&gt;System.out.println(coerce(object).to(Foo.class).bar());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;method(new Bar());&lt;br /&gt;method(new FooBar());&lt;/code&gt;&lt;/pre&gt;Occasionally it&#39;s useful to test up front whether a particular class will support the methods we want to call so for this purpose I&#39;ve added the following method:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;public &lt;t&gt; boolean quacksLikeA(Class&lt;t&gt; iface)&lt;/t&gt;&lt;/t&gt;&lt;/code&gt;&lt;/pre&gt;And that&#39;s all there is to it.  See &lt;a href=&quot;http://www.blogger.com/post-edit.g?blogID=1613193234145521679&amp;amp;postID=4641697310094573662#Appendix A&quot;&gt;Appendix A&lt;/a&gt; for the full class listing, but for now let&#39;s look at some more useful ways to use Duck Typing with this mechanism.&lt;br /&gt;&lt;h3&gt;Useful examples&lt;/h3&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;Okay, so those examples were kind of cheesy; let&#39;s try doing something useful with&lt;br /&gt;duck typing.  &lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Copying a Reader/InputStream&lt;/h4&gt;&lt;br /&gt;In JDK 1.1, Sun introduced the java.io.Reader and java.io.Writer class to deal&lt;/div&gt;&lt;div&gt;properly with some bugs they had introduced when they had written the InputStream class&lt;/div&gt;&lt;div&gt;to handle character encodings.  Because Sun still hadn&#39;t worked out exactly how to use &lt;/div&gt;&lt;div&gt;interfaces correctly both the InputStream and Reader classes are abstract classes.  Code all over the place mixes and matches Reader and InputStream requiring you to handle both cases.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now suppose you want to write a simple copy function that will handle either a Reader or InputStream and write output to a Writer.  With duck typing it is easy to do this without having&lt;/div&gt;&lt;div&gt;to handle cases for both classes.  First define the interface with the common method you&lt;/div&gt;&lt;div&gt;want to access:&lt;pre&gt;&lt;code&gt;interface Readable {&lt;br /&gt;int read() throws IOException;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Next create your copy function taking an Object as the initial parameter and internally coercing to the Readable interface:&lt;pre&gt;&lt;code&gt;static void copy(Object readerOrInputStream, Writer writer) throws IOException {&lt;br /&gt;int b;&lt;br /&gt;Readable readable = coerce(readerOrInputStream).to(Readable.class);&lt;br /&gt;while ((b = readable.read()) != -1) {&lt;br /&gt;    writer.write(b);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Note that not only will this method now work with InputStream and Reader, but with&lt;br /&gt;any other class that has a read method with the same semantics.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Using annotations polymorphically&lt;/h4&gt;Another example where polymorphism is difficult in Java is when using JDK 1.5 Annotations.  An annotation is a pseudo-interface that represents meta-data about a class (or elements of a class).  However, apart from the implictly extended Annotation interface there is no way to access annotations polymorpically.  While this is not a big deal for most people, if you find yourself writing code that processes a lot of annotations, you will find yourself writing a bunch of duplicated code to deal with different annotation types.&lt;div&gt;&lt;br /&gt;However, with Duck Typing it becomes possible to write an annotation processor that&lt;br /&gt;can deal polymorphically with annotations.&lt;br /&gt;&lt;br /&gt;Let&#39;s suppose we are wanting to write a simple persistence layer for some classes&lt;br /&gt;using annotations.  We start by adding the following annotations to classes:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;@Persistent&lt;br /&gt;@Immutable&lt;br /&gt;@Transient&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;We will then create a PersistenceHandler strategy interface that will be used by our annotation processor to work out what to do with these annotations:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;interface PersistenceHandler {&lt;br /&gt;void persist(Object object);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;We define the annotations so they include a default handler implementation.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;public @interface Persistent {&lt;br /&gt;Class handler() : default PersistentPersistenceHandler.class;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public @interface Immutable {&lt;br /&gt;Class handler() : default ImmutableHandler.class;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public @interface Transient {&lt;br /&gt;Class handler() : default TransientPersistenceHandler.class;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Next we define the interface we are going to use access the handler attribute of&lt;br /&gt;the annotation:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;public interface PersistenceAnnotation {&lt;br /&gt;Class handler();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;And lastly we write our annotation processor:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;void processAnnotations(Object object) throws Exception {&lt;br /&gt;  for (Annotation annotation : object.getClass().getAnnotations()) {&lt;br /&gt;      DuckType annotationToCoerce = coerce(annotation);&lt;br /&gt;      if (annotationToCoerce.quacksLikeA(PersistenceAnnotation.class)) {&lt;br /&gt;          Class handler =&lt;br /&gt;              annotationToCoerce.to(PersistenceAnnotation.class).handler();&lt;br /&gt;          handler.newInstance().persist(object);&lt;br /&gt;      }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The nice thing about this is we have completely decoupled our code from which&lt;br /&gt;particular annotations it can support.  We can add new annotations as much as we&lt;br /&gt;like, and providing they support the handler() attribute then we can support them. Also we can add other annotations to our classes that we don&#39;t handle and these are simply ignored.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Allowing mocking/testing of legacy classes that don&#39;t have interfaces&lt;/h4&gt;If you are writing your code using Test Driven Development you&#39;ll know about the power of mocking and dependency injection to make your code testable.  Using a package such as EasyMock it is very easy to quickly create Mocks/Stubs of classes that would be very difficult to otherwise test.&lt;br /&gt;&lt;br /&gt;The way these things work is they generate a Dynamic Proxy for the Interface you want to mock and then allow you to specify your expectations of how that class will be called.&lt;br /&gt;&lt;br /&gt;That&#39;s all well and good, but it assumes that the things you want to mock are already Interfaces[&lt;a href=&quot;http://www.blogger.com/post-edit.g?blogID=1613193234145521679&amp;amp;postID=4641697310094573662#3&quot;&gt;3&lt;/a&gt;] and not concrete classes that you have no ability to make changes over.&lt;br /&gt;&lt;br /&gt;Sounds like a problem for Duck typing.  Let&#39;s use for example the java.io.File class.  File has a large number of methods, but typically we&#39;ll only want to be using a couple of them.  Let&#39;s define the interface that we want to use:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;interface DeleteableFile {&lt;br /&gt;String getName();&lt;br /&gt;String exists();&lt;br /&gt;boolean delete();&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Now the method we want to test should be written as:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;public deleteTmpFileIfExists(Object fileToDelete) {&lt;br /&gt;DeletableFile file = coerce(fileToDelete).to(DeletableFile.class);&lt;br /&gt;if (file.exists() &amp;amp;&amp;amp;&lt;br /&gt;    Pattern.matches(&quot;(\\.tmp|~)$&quot;, file.getName()) {&lt;br /&gt;    file.delete();&lt;br /&gt;}  &lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;We can now test this with a mock using the DeletableFile interface or a standard&lt;br /&gt;File object.&lt;br /&gt;&lt;h4&gt;Creating an encrypted String class&lt;/h4&gt;One of the decisions made by the early Sun engineers was to make the String class final.  This was done mainly for security reasons that I won&#39;t bore you with here, but suffice it to say it makes it very difficult to do a lot of extended String classes that add more functionality.  Let&#39;s suppose we have an encrypted String class that apes the standard String interface:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;public final class EncryptedString {&lt;br /&gt;...&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;By now the process for writing methods that handle both this and a standard String should be fairly obvious.  We create the interface with the methods we care about:&lt;pre&gt;&lt;code&gt;interface StringLike {&lt;br /&gt;boolean startsWith(String prefix);&lt;br /&gt;String subString(int beginIndex);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And then we use Duck Typing to refer to either:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;String skipLeadingSlash(Object stringLikeThing) {&lt;br /&gt;StringLike s = coerce(stringLikeThing).to(StringLike.class);&lt;br /&gt;if (s.startsWith(&quot;/&quot;)) {&lt;br /&gt;  return s.subString(1);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Parting words&lt;/h2&gt;While Duck Typing is a useful concept, it&#39;s not all sweetness and light.  You do give up a significant amount of compile-time checking to make the concept work.  However, if you are practicing Test Driven Development (and give yourself a slap now if you are not), then with good testing you can make this fact largely irrelevant.  What duck typing does give you is an incredibly flexible mechanism for polymorphism that buys out many of the disadvantages of inheritance based approaches.  Try it in your own code and see what you can do.&lt;br /&gt;&lt;br /&gt;&lt;a name=&quot;Appendix A&quot;&gt;&lt;h2&gt;Appendix A: DuckType.java code listing&lt;/h2&gt;&lt;/a&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;package example;&lt;br /&gt;&lt;br /&gt;import java.lang.reflect.InvocationHandler;&lt;br /&gt;import java.lang.reflect.Method;&lt;br /&gt;import java.lang.reflect.Proxy;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* Allows &quot;duck typing&quot; or dynamic invocation based on method signature rather&lt;br /&gt;* than type hierarchy. In other words, rather than checking whether something&lt;br /&gt;* IS-a duck, check whether it WALKS-like-a duck or QUACKS-like a duck.&lt;br /&gt;*&lt;br /&gt;* To use first use the coerce static method to indicate the object you want to&lt;br /&gt;* do Duck Typing for, then specify an interface to the to method which you want&lt;br /&gt;* to coerce the type to, e.g:&lt;br /&gt;*&lt;br /&gt;*   public interface Foo {&lt;br /&gt;*      void aMethod();&lt;br /&gt;*   }&lt;br /&gt;*   class Bar {&lt;br /&gt;*      ...&lt;br /&gt;*      public void aMethod() { ... }&lt;br /&gt;*      ...&lt;br /&gt;*   }&lt;br /&gt;*   Bar bar = ...;&lt;br /&gt;*   Foo foo = DuckType.coerce(bar).to(Foo.class);&lt;br /&gt;*   foo.aMethod();&lt;br /&gt;*&lt;br /&gt;*&lt;br /&gt;*/&lt;br /&gt;public class DuckType {&lt;br /&gt;&lt;br /&gt;private final Object objectToCoerce;&lt;br /&gt;&lt;br /&gt;private DuckType(Object objectToCoerce) {&lt;br /&gt;  this.objectToCoerce = objectToCoerce;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private class CoercedProxy implements InvocationHandler {&lt;br /&gt;  public Object invoke(Object proxy, Method method, Object[] args)&lt;br /&gt;          throws Throwable {&lt;br /&gt;      Method delegateMethod = findMethodBySignature(method);&lt;br /&gt;      assert delegateMethod != null;&lt;br /&gt;      return delegateMethod.invoke(DuckType.this.objectToCoerce, args);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* Specify the duck typed object to coerce.&lt;br /&gt;*&lt;br /&gt;* @param object the object to coerce&lt;br /&gt;* @return&lt;br /&gt;*/&lt;br /&gt;public static DuckType coerce(Object object) {&lt;br /&gt;  return new DuckType(object);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* Coerce the Duck Typed object to the given interface providing it&lt;br /&gt;* implements all the necessary methods.&lt;br /&gt;*&lt;br /&gt;* @param &lt;t&gt;&lt;br /&gt;* @param iface&lt;br /&gt;* @return an instance of the given interface that wraps the duck typed&lt;br /&gt;*         class&lt;br /&gt;* @throws ClassCastException if the object being coerced does not implement&lt;br /&gt;*             all the methods in the given interface.&lt;br /&gt;*/&lt;br /&gt;public &lt;t&gt; T to(Class&lt;t&gt; iface) {&lt;br /&gt;  assert iface.isInterface() : &quot;cannot coerce object to a class, must be an interface&quot;;&lt;br /&gt;  if (isA(iface)) {&lt;br /&gt;      return iface.cast(objectToCoerce);&lt;br /&gt;  }&lt;br /&gt;  if (quacksLikeA(iface)) {&lt;br /&gt;      return generateProxy(iface);&lt;br /&gt;  }&lt;br /&gt;  throw new ClassCastException(&quot;Could not coerce object of type &quot;&lt;br /&gt;          + objectToCoerce.getClass() + &quot; to &quot; + iface);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private &lt;t&gt; boolean isA(Class&lt;t&gt; iface) {&lt;br /&gt;  return objectToCoerce.getClass().isInstance(iface);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* Determine whether the duck typed object can be used with&lt;br /&gt;* the given interface.&lt;br /&gt;*&lt;br /&gt;* @param &lt;t&gt; Type of the interface to check.&lt;br /&gt;* @param iface Interface class to check&lt;br /&gt;* @return true if the object will support all the methods in the&lt;br /&gt;* interface, false otherwise.&lt;br /&gt;*/&lt;br /&gt;public &lt;t&gt; boolean quacksLikeA(Class&lt;t&gt; iface) {&lt;br /&gt;  for (Method method : iface.getMethods()) {&lt;br /&gt;      if (findMethodBySignature(method) == null) {&lt;br /&gt;          return false;&lt;br /&gt;      }&lt;br /&gt;  }&lt;br /&gt;  return true;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@SuppressWarnings(&quot;unchecked&quot;)&lt;br /&gt;private &lt;t&gt; T generateProxy(Class&lt;t&gt; iface) {&lt;br /&gt;  return (T) Proxy.newProxyInstance(iface.getClassLoader(),&lt;br /&gt;          new Class[] { iface }, new CoercedProxy());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private Method findMethodBySignature(Method method) {&lt;br /&gt;  try {&lt;br /&gt;      return objectToCoerce.getClass().getMethod(method.getName(),&lt;br /&gt;              method.getParameterTypes());&lt;br /&gt;  } catch (NoSuchMethodException e) {&lt;br /&gt;      return null;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/code&gt;&lt;p&gt;&lt;/p&gt;&lt;/pre&gt;&lt;h2&gt;Footnotes&lt;/h2&gt;&lt;br /&gt;&lt;a name=&quot;1&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-size:x-small;&quot;&gt;[1]&lt;/span&gt;&lt;/a&gt; Attributed to Alex Martelli in &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=1613193234145521679&quot; hl=&quot;en&amp;amp;&#39;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-size:x-small;&quot;&gt;a message to the comp.lang.python newsgroup&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-size:x-small;&quot;&gt; [&lt;/span&gt;&lt;a href=&quot;http://www.blogger.com/=&quot; org=&quot;&quot; wiki=&quot;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-size:x-small;&quot;&gt;Wikipedia&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-size:x-small;&quot;&gt;].&lt;br /&gt;&lt;/span&gt;&lt;a name=&quot;2&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-size:x-small;&quot;&gt;[2]&lt;/span&gt;&lt;/a&gt; Adapted from the example in the [&lt;a href=&quot;http://en.wikipedia.org/wiki/Duck_typing&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-size:x-small;&quot;&gt;Wikipedia Duck Typing Article&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-size:x-small;&quot;&gt;.&lt;/span&gt;&lt;br /&gt;&lt;a name=&quot;3&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-size:x-small;&quot;&gt;[3]&lt;/span&gt;&lt;/a&gt; More recent versions of EasyMock do class instrumentation to overcome this limitation, but we&#39;ll ignore that for now.&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thinking-in-code.blogspot.com/feeds/4641697310094573662/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1613193234145521679/4641697310094573662' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1613193234145521679/posts/default/4641697310094573662'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1613193234145521679/posts/default/4641697310094573662'/><link rel='alternate' type='text/html' href='http://thinking-in-code.blogspot.com/2008/11/duck-typing-in-java-using-dynamic.html' title='Duck Typing in Java using Dynamic Proxies'/><author><name>Dean Povey</name><uri>http://www.blogger.com/profile/09086367210893430445</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCEQXgY3WXgevxZXsbbV8IUum-LjN8mEG_KVzOwwoormgzqucAkoLyxsv8dO36BqJgadae2uob6oqM_E0i6jVAkZP0l2MElDXVGEhxfOGFeB98sIbYvVGjPskiZpFhVw/s220/profile.jpg'/></author><thr:total>5</thr:total></entry></feed>