<?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: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-20485368</id><updated>2011-12-03T16:48:06.619Z</updated><category term='performance'/><category term='tempus-fugit'/><category term='testing'/><category term='agile'/><category term='coaching'/><category term='java'/><category term='mocking'/><category term='concurrency'/><category term='swt'/><category term='rant'/><title type='text'>bad.robot</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>46</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-20485368.post-8590288188037772313</id><published>2011-10-29T10:11:00.000Z</published><updated>2011-10-29T10:11:14.788Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Java source on Mac</title><content type='html'>Mostly as a reminder to myself, getting the Java source on your Mac involves the following.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Go to the &lt;a href="https://developer.apple.com/downloads"&gt;Apple Developer Connection downloads page&lt;/a&gt;, search for &lt;b&gt;Java for Mac OS X 10.x Developer Package&lt;/b&gt; where 10.x matches your version of OS X. The developer bundle includes the source whereas the regular software update version does not.&lt;/li&gt;&lt;li&gt;Download and install. Running &lt;code&gt;/Applications/Utilities/Java Preferences.app&lt;/code&gt; should now show "Java SE 6 (System)" in the list.&lt;/li&gt;&lt;li&gt;Open a Terminal.app window&lt;/li&gt;&lt;li&gt;&lt;code&gt;cd $JAVA_HOME&lt;/code&gt; (aka &lt;code&gt;/System/Library/Frameworks/JavaVM.framework/Home)&lt;/code&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Setup a symlink to the source archive with &lt;code&gt;sudo ln -s /Library/Java/JavaVirtualMachines/1.6.0_26-b03-383.jdk/Contents/Home/src.jar&lt;/code&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;And for the JavaDoc, &lt;code&gt;sudo ln -s /Library/Java/JavaVirtualMachines/1.6.0_24-b07-334.jdk/Contents/Home/docs.jar&lt;/code&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Now point your IDE of choice to the new source folder symlink.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Any update to Java will set things up to point to Maven 3, so if you use Maven 2, it'll break things with &lt;br /&gt;&lt;code&gt;java.lang.NoClassDefFoundError: org/codehaus/plexus/classworlds/launcher/Launcher&lt;/code&gt; Reset things by;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;code&gt;cd /usr/share&lt;/code&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;sudo mv maven maven.new&lt;/code&gt; (a symlink which should incorrectly be pointing to &lt;code&gt;java/maven-3.0.3)&lt;/code&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;sudo ln -s /maven2/install/folder maven&lt;/code&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;run &lt;code&gt;maven -version&lt;/code&gt; to check its back up.&lt;/li&gt;&lt;li&gt;Have a cup of tea.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;div&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5283328307719135378" src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" style="cursor: pointer; float: left; height: 22px; margin: 0pt 10px 10px 0pt; width: 22px;" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-8590288188037772313?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/8590288188037772313/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=8590288188037772313' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/8590288188037772313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/8590288188037772313'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2011/10/java-source-on-mac.html' title='Java source on Mac'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-5077709373438283681</id><published>2011-08-29T12:30:00.000Z</published><updated>2011-08-29T12:30:15.150Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='coaching'/><title type='text'>Reflecting on Interviewing Mistakes</title><content type='html'>Recruiting for the next guy on your team is hard. At first glance it doesn't seem to be, we've developed techniques like pair tests but as I start to look at it more closely, I've started to notice that even the more progressive techniques don't preclude us from making the same mistakes as the traditional interview.&lt;br /&gt;&lt;br /&gt;Let's take an example from two teams...&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;Team A's process starts off by favoring buzz word heavy CVs and CVs that meet a minimum number of years of experience. A unattended pen and paper test, characterised by very closed questioning against specialist areas of the programming language. This might include questions around language syntax semantics (keywords and modifiers, object equality etc etc).  Things like bubble sorts algorithms are requested. Scores out of 100 are tallied. Things are fairly black and white.&lt;br /&gt;&lt;br /&gt;Team B's process favors mention of agile experience in the CV. Follow up questions prompt genuine conversation but often an implied hurdle that the candidate must jump is "has he reached the same conclusion as me on topic X?". The unattended coding exercise is not a test, at least it should be more of an exercise to explore the way a candidate approaches things. The team might require the presence of unit tests and evidence of TDD but should actively not persecute style or syntax. Something that's harder in practice to do than in theory.&lt;br /&gt;&lt;br /&gt;Hopefully, its clear that Team A's selection process is heavily biased towards developers with good memories. It's probably unfairly prejudice against candidates that haven't had specific exposure to specific scenarios / solutions. I experienced this when I was asked to write a algorithm to calculate prime numbers with pen and paper. I fumbled through and handed over my scrawl. I explained that I'd prefer write tests, experiment with the code and improve the design; basically to learn as I went along. The response from the interviewer, looking down at my scribbling, was "that's not really what we're looking for... have you heard of the Sieve of Eratosthenes?". Obviously, I hadn't. &lt;br /&gt;&lt;br /&gt;Rather than assess my approach, the interviewer was looking for a specific piece of knowledge but what for? If I got the job I'm pretty sure my first task wouldn't be to write something to work out prime numbers. Would that fix some production problem? Would it introduce a new feature that had no other solution? No. &lt;br /&gt;&lt;br /&gt;A huge part of what we do is learn, or at least it should be. Failure is what makes us better and in environments where failure is embraced and we write code that we can (fairly) easily rework, we get better systems (as we refine our understanding). We never now what the real problems are going to be when we start a story. The interviewer above simply brushed over this, it seemed he wanted me to reach the same conclusion he had without explaining the steps I took to get there. Without any advocacy on my part, how would he know I could do it again with a different problem?&lt;br /&gt;&lt;blockquote&gt;"Right or wrong answers don't really have a place because there's never a right or wrong answer in what we do."&lt;/blockquote&gt;Having said all that, I'm sure we'd all favour a process like Team Bs but I'm starting to see that Team B are making at least some of the same mistakes just in a more subtle way...&lt;br /&gt;&lt;br /&gt;For the CV selection, Team A look for "spring", "hibernate" and other technology buzzwords. Team B look for "refactoring", "TDD", "XP" and other development buzz words, the reason usually cited as being because the technologies aren't as import. Team B are favouring the &lt;i&gt;why&lt;/i&gt; over the &lt;i&gt;how&lt;/i&gt;, they're assuming given the right approach and smart people, specifics around technologies can be learnt. Both teams are trying to expose characteristics of the candidates that mirror their own.&lt;br /&gt;&lt;br /&gt;Team B asks candidates to complete a short programming exercise off-line. Implement a library, a DVD store, a robot explorer, whatever. It should only take an hour or so and demonstrates the candidates style. I've certainly seen it as an effective tool to eliminate people that really can't code for toffee but I've also seen people fall into the same old trap and eliminate people who missed something specific hidden there. A trivial example might be "oh! they didn't use dependency injection. Fail!". &lt;br /&gt;&lt;br /&gt;Team B's pair test should be a great way to understand how a candidate operates in front of an IDE and if you'll actually be able to work with him. A bit like the unattended test, it's a good way to eliminate extreme cases. If the candidate behaves completely anti-socially, wont listen and codes like mad man, you can probably reject him with confidence. It's easy to let bad interview habits creep in though; to focus more on some obscure gotcha in the code than how the candidate is actually pairing.&lt;br /&gt;&lt;blockquote&gt;"I think the problem with both these techniques (unattended exercise and the pair test) is when too much specificity comes in at the start. When you are looking for something specific, you'll often be disappointed." &lt;/blockquote&gt;I've certainly heard myself say "oh, he didn't spot that there was a precision issue with double there...". In all honesty, I'd miss that kind of bug as often as I'd spot it but I'd hire me! The upshot there, especially when we doing a couple of pair tests a week, is to stay focused on why you're doing the pair test and not on the test itself. Are we doing this to see if the candidate can spot all the traps and pitfalls that we spent so long putting in or do we want to see how they pair? In my view, if they get the "right" answer is almost irrelevant, it's how they explore the problem.&lt;br /&gt;&lt;br /&gt;I guess what I'm reflecting on here is how as a peer group, we pretty much realise that closed questioning limits our choices and that open ended questions lead to real conversations that are more relevant to the types of conversations we have day to day. Right or wrong answers don't really have a place because there's never a right or wrong answer in what we do. If I implement a prime number finder without the Colander of Eratosthenes, am I wrong? The tests still pass so I must be right? Is Eratosthenes more right? Despite this realisation though, we can easily fall into a more subtle way of behaving where we mentally start ticking off specifics for a candidate. &lt;br /&gt;&lt;br /&gt;I guess we have to keep reminding ourselves what's important and what we're looking for in a candidate. I guess I'm mellowing in the way I assess candidates and probably rejected a fair few unfairly in the past. Sorry.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5283328307719135378" src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" style="cursor: pointer; float: left; height: 22px; margin: 0pt 10px 10px 0pt; width: 22px;" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-5077709373438283681?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/5077709373438283681/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=5077709373438283681' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/5077709373438283681'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/5077709373438283681'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2011/08/reflecting-on-interviewing-mistakes.html' title='Reflecting on Interviewing Mistakes'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-7358500814296965448</id><published>2011-08-29T12:09:00.001Z</published><updated>2011-08-29T12:09:33.079Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Catching Multiple Exceptions (and rethrowing them all!)</title><content type='html'>Sometimes, we may want to catch an exception, temporarily ignoring it to continue work before rethrowing it when its more appropriate to do so. I recently saw a slight variation of this whereby the developer wanted to (potentially) catch multiple exceptions, perform some processing then throw. However, it left the question that if more than one was caught, which exception should we actually rethrow. We certainly don't want to loose any information and should really allow the client to catch the exception in a standard way.&lt;br /&gt;&lt;br /&gt;This got me thinking about how we should deal with this kind of thing. In the end, I came up with the idea of a collection class to capture the &lt;code&gt;Exceptions&lt;/code&gt; and a sub-class of &lt;code&gt;Exception&lt;/code&gt; to represent an exception containing other, embedded exceptions. When you're done collecting exceptions, you can just check and rethrow as a new exception type.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;For example, the domain cleaning class below can throw an exception during the &lt;code&gt;deleteAll&lt;/code&gt; method. Rather than abandon the cleanup of subsequent objects, we can employ this tactic to continue the cleanup and throw an exception containing the underlying problems when we're done.&lt;br /&gt;&lt;br /&gt;&lt;pre class="java:nogutter:nocontrols" name="code"&gt;public class DomainCleaner {&lt;br /&gt; &lt;br /&gt;    public static void clean(Domain domain) throws CompositeException {&lt;br /&gt;        Exceptions exceptions = new Exceptions();&lt;br /&gt;        clean(domain.customers(), exceptions);&lt;br /&gt;        clean(domain.suppliers(), exceptions);&lt;br /&gt;        clean(domain.invoices(), exceptions);&lt;br /&gt;        exceptions.checkAndThrow();&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    private static void clean(Repository repository, Exceptions exceptions) {&lt;br /&gt;        try {&lt;br /&gt;            ((TestRepository) repository).deleteAll();&lt;br /&gt;        } catch (RepositoryException e) {&lt;br /&gt;            exceptions.add(e);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;We simply add to the exception collection class (&lt;code&gt;exceptions.add(e)&lt;/code&gt;) and then when we're done, we can check it and throw a composite exception if needed with &lt;code&gt;exceptions.checkAndThrow()&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;So far, we've only been interested in the fact that multiple exception can be handled and so haven't needed to programmatically query for specific exception types. For example, we've only needed this up until now.&lt;br /&gt;&lt;br /&gt;&lt;pre class="java:nogutter:nocontrols" name="code"&gt;try {&lt;br /&gt;   // ... something that calls checkAndThrow()&lt;br /&gt;} catch (CompositeException e) {&lt;br /&gt;   // ... this is enough for now&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The details of the classes are below. &lt;br /&gt;&lt;br /&gt;&lt;pre class="java:nogutter:nocontrols" name="code"&gt;public class Exceptions implements java.lang.Iterable&amp;lt;Exception&amp;gt; {&lt;br /&gt;&lt;br /&gt;    private final List&amp;lt;Exception&amp;gt; exceptions = new ArrayList&amp;lt;Exception&amp;gt;();&lt;br /&gt;&lt;br /&gt;    public void add(Exception exception) {&lt;br /&gt;        exceptions.add(exception);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Iterator&amp;lt;Exception&amp;gt; iterator() {&lt;br /&gt;        return exceptions.iterator();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void checkAndThrow() throws CompositeException {&lt;br /&gt;        if (!exceptions.isEmpty())&lt;br /&gt;            throw new CompositeException(this);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;The &lt;code&gt;toString()&lt;/code&gt; implementation below outputs the embedded exceptions in a way that is consistent with how you'd expect to see regular exceptions.&lt;br /&gt;&lt;br /&gt;&lt;pre class="java:nogutter:nocontrols" name="code"&gt;public class CompositeException extends Exception {&lt;br /&gt;&lt;br /&gt;    private final Exceptions exceptions;&lt;br /&gt;&lt;br /&gt;    public CompositeException(Exceptions exceptions) {&lt;br /&gt;        super("composite exception was thrown with embedded exceptions (see details)");&lt;br /&gt;        this.exceptions = exceptions;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public String toString() {&lt;br /&gt;        StringBuilder builder = new StringBuilder();&lt;br /&gt;        for (Exception exception : exceptions)&lt;br /&gt;            builder.append('\t').append(new ExceptionToString(exception).toString()).append('\n');&lt;br /&gt;        return String.format("%s\n{composite exceptions=\n%s}\n%s", this.getClass().getName(), builder.toString(), super.toString());&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5283328307719135378" src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" style="cursor: pointer; float: left; height: 22px; margin: 0pt 10px 10px 0pt; width: 22px;" /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-7358500814296965448?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/7358500814296965448/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=7358500814296965448' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/7358500814296965448'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/7358500814296965448'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2011/08/catching-multiple-exceptions-and.html' title='Catching Multiple Exceptions (and rethrowing them all!)'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-7657082122151886527</id><published>2011-06-22T20:14:00.001Z</published><updated>2011-06-22T20:15:01.982Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='mocking'/><title type='text'>Loggin is still evil but...</title><content type='html'>In a &lt;a href="http://pequenoperro.blogspot.com/2010/10/logging-is-evil-but.html"&gt;previous post&lt;/a&gt;, I was going on about how evil logging is. How it's often confused as a requirement and often badly misused. The upshot of the post was that if you're going to log stuff, in our case using Log4J, lets be honest about it and test it. We should be able to say upfront what's important to log, in what situations and at what log level. Sounds like a straight forward case of test first.&lt;br /&gt;&lt;br /&gt;Mocking Log4J however can be a real pain. I've managed it in the past using Apache's logging abstraction and configuring it to use Log4J under the covers but in my previous post, I demonstrated a slightly easier way. A helper class called &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Log4J&lt;/span&gt; that we can use to represent the logging system and that we can make assertions against. Pretty cool so far.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;There was one caveat, I wasn't entirely happy with the fact that the class would rely on your external Log4J configuration. To assert that a log message appeared at the level INFO for example, you'd have to make sure that the test environment sets up the appropriate class to log at that level. It made for a kind of integration / environmental test which in some cases might be a sensible test but for the most part, I kept seeing test failures down to configuration on different environments. Yuk.&lt;br /&gt;&lt;br /&gt;So I updated the helper class to include a log level override which will ignore what the actual configuration says. This means you can write less brittle tests to say things like "ensure my log message is output at debug level regardless of the runtime configuration". &lt;br /&gt;&lt;br /&gt;The updated class looks like this.&lt;br /&gt;&lt;br /&gt;&lt;pre class="java:nogutter:nocontrols" name="code"&gt;public class Log4J {&lt;br /&gt; &lt;br /&gt;    private final StringWriter writer = new StringWriter();&lt;br /&gt;    private final Logger logger;&lt;br /&gt;    private final String uuid = UUID.randomUUID().toString();&lt;br /&gt; &lt;br /&gt;    public static Log4J appendTo(Logger logger) {&lt;br /&gt;        return new Log4J(logger, ALL);&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    public static Log4J appendTo(Logger logger, Level level) {&lt;br /&gt;        return new Log4J(logger, level);&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    private Log4J(Logger logger, Level level) {&lt;br /&gt;        this.logger = logger;&lt;br /&gt;        WriterAppender appender = new WriterAppender(new SimpleLayout(), writer);&lt;br /&gt;        appender.setName(uuid);&lt;br /&gt;        logger.addAppender(appender);&lt;br /&gt;        logger.setLevel(level);&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    public void clean() {&lt;br /&gt;        logger.removeAppender(uuid);&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    public void assertThat(Matcher&amp;lt;String&amp;gt; matcher) {&lt;br /&gt;        org.junit.Assert.assertThat(writer.toString(), matcher);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Which means you can setup to expect a log level at say the ERROR level like this.&lt;br /&gt;&lt;br /&gt;&lt;pre class="java:nogutter:nocontrols" name="code"&gt;private final Log4J logger = Log4J.appendTo(Logger.getLogger(Post.class), LogLevel.ERROR);&lt;/pre&gt;&lt;br /&gt;The make assertions like this (which would fail if the matcher fails or because its not logged at the expected level.&lt;br /&gt;&lt;br /&gt;&lt;pre class="java:nogutter:nocontrols" name="code"&gt;logger.assertThat(containsString(EXCEPTION_MESSAGE));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I still think logging is evil and try &lt;i&gt;really&lt;/i&gt; hard not to use a single log statement but if you have to, I hope the helper class helps keep you honest in your tests ;) Have a look at the &lt;a href="http://pequenoperro.blogspot.com/2010/10/logging-is-evil-but.html"&gt;previous post&lt;/a&gt; for more details and extended examples.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5283328307719135378" src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" style="cursor: pointer; float: left; height: 22px; margin: 0pt 10px 10px 0pt; width: 22px;" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-7657082122151886527?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/7657082122151886527/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=7657082122151886527' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/7657082122151886527'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/7657082122151886527'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2011/06/loggin-is-still-evil-but.html' title='Loggin is still evil but...'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-4802425666383070797</id><published>2011-06-10T15:52:00.003Z</published><updated>2011-07-14T08:50:21.006Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>JDK7 Artcile in JavaTech Journal</title><content type='html'>My article "Java the language vs Java the platform" (about the new release of JDK7) has been published in this months &lt;a href="http://jaxenter.com/java-tech-journal/"&gt;Java Tech Journal&lt;/a&gt;. You can download the full issue directly below.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://badrobot.googlecode.com/svn/trunk/bad.robot/JTJ-2011-05.pdf"&gt;&lt;img border="0" src="http://jaxenter.com/assets/125/150/JTJ-2011-05.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I'd love to get some feedback, so please feel free to comment here.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5283328307719135378" src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" style="cursor: pointer; float: left; height: 22px; margin: 0pt 10px 10px 0pt; width: 22px;" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-4802425666383070797?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/4802425666383070797/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=4802425666383070797' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/4802425666383070797'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/4802425666383070797'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2011/06/jdk7-artcile-in-javatech-journal.html' title='JDK7 Artcile in JavaTech Journal'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-606365147913768930</id><published>2011-04-13T09:36:00.001Z</published><updated>2011-04-13T09:36:51.722Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='tempus-fugit'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrency'/><title type='text'>tempus-fugit 1.1 released</title><content type='html'>Yesterday, I released the 1.1 version of my micro-library &lt;a href="http://code.google.com/p/tempus-fugit/"&gt;tempus-fugit&lt;/a&gt;. From the project's website&lt;br /&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; font-family: arial, sans-serif; font-size: 13px; line-height: 16px;"&gt;The tempus-fugit library is a small collection of classes and interfaces capturing common abstractions useful when writing concurrent and time sensitive code.&lt;/span&gt;&lt;/blockquote&gt;It's now available from the &lt;a href="http://repo2.maven.org/maven2/com/google/code/tempus-fugit/tempus-fugit/"&gt;Maven Central&lt;/a&gt; repository having had a bad experience with &lt;a href="http://repo2.maven.org/maven2/com/google/code/tempus-fugit/tempus-fugit/"&gt;java.net&lt;/a&gt; since their migration (and no longer being able to publish, see this &lt;a href="http://java.net/projects/maven-repository/lists/users/archive/2011-03/message/0"&gt;post&lt;/a&gt; and &lt;a href="http://java.net/projects/wagon/lists/users/archive/2011-02/message/0"&gt;another&lt;/a&gt; if you're interested).&lt;br /&gt;&lt;br /&gt;See the &lt;a href="http://tempus-fugit.googlecode.com/svn/site/documentation/changes.html"&gt;change list&lt;/a&gt;&amp;nbsp;for what's included in this release.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5283328307719135378" src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" style="cursor: pointer; float: left; height: 22px; margin: 0pt 10px 10px 0pt; width: 22px;" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-606365147913768930?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/606365147913768930/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=606365147913768930' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/606365147913768930'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/606365147913768930'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2011/04/tempus-fugit-11-released.html' title='tempus-fugit 1.1 released'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-5100755803794529782</id><published>2011-03-04T15:44:00.011Z</published><updated>2011-09-03T20:53:08.099Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>JDK7 Previwed</title><content type='html'>Oracle put out the preview release of JDK7 last month. I guess they felt they had to. So, it's not what was once heralded (will &lt;a href="http://openjdk.java.net/projects/lambda/"&gt;8 see lamdas&lt;/a&gt;?) but still has one or two interesting language features. The ones that caught my eye include;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Type Inference on Generic Object Creation&lt;/h3&gt;&lt;br /&gt;Which allows a little brevity to the garrulity of the language, at least against generic object instantionation where the type can be infered. For example,&lt;br /&gt;&lt;pre class="brush: java;" name="code"&gt;private Map&amp;lt;Size, List&amp;lt;Shoe&amp;gt;&amp;gt; stock = new HashMap&amp;lt;Size, List&amp;lt;Shoe&amp;gt;&amp;gt;();&lt;br /&gt;&lt;/pre&gt;can be reduced to &lt;br /&gt;&lt;pre class="brush: java;" name="code"&gt;private Map&amp;lt;Size, List&amp;lt;Shoe&amp;gt;&amp;gt; stock = new HashMap&amp;lt;&amp;gt;();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;where the &lt;i&gt;diamond operator&lt;/i&gt; can be filled in or inferred from the declaration. It's subtly different than leaving out the generic completely which will reduce your type to being of &lt;code&gt;Object&lt;/code&gt; Things don't get much better than this.&lt;br /&gt;&lt;br /&gt;Actually, it does. Just a little. Constructor generics always used to be fun and that hasn't really changed, although with JDK7 you can do a little more. For example,&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;pre class="brush: java;" name="code"&gt;public class Bob&amp;lt;Y&amp;gt; {&lt;br /&gt;    public &amp;lt;T&amp;gt; Bob(T t) {&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void example() {&lt;br /&gt;        Bob&amp;lt;Integer&amp;gt; bob = new Bob&amp;lt;&amp;gt;("yum");&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void anotherExample() {&lt;br /&gt;        Bob&amp;lt;Integer&amp;gt; bob = new &amp;lt;String&amp;gt; Bob&amp;lt;&amp;gt;("yum");&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;The examples are the same as the one Oracle gives, they both work with JDK7 only and show the &lt;code&gt;Integer&lt;/code&gt; type inferred as the class generic (&lt;code&gt;Y&lt;/code&gt;) in combination with the diamond operator. The second example shows new syntax to explicitly set type of the method generic and give some additional compile time checks. &lt;br /&gt;&lt;br /&gt;&lt;h3&gt;try-with-resource and &lt;code&gt;AutoClosable&lt;/code&gt;&lt;/h3&gt;&lt;br /&gt;Another bugbear with the verbosity of Java has always been the try-catch-finally syntax. The new language feature try-with-resource allows you to chop this down some what in combination with auto-closable resources. Here, rather than the familiar, try-finally to close a resource, you can "open" the resource within the parenthesis of the try statement (as long as the object implements &lt;code&gt;AutoCloassable&lt;/code&gt; and the resource will always close itself in a &lt;code&gt;finally&lt;/code&gt; like way.&lt;br /&gt;&lt;br /&gt;For example,&lt;br /&gt;&lt;pre class="brush: java;" name="code"&gt;private String example() throws IOException {&lt;br /&gt;    BufferedReader reader = new BufferedReader(...);&lt;br /&gt;    try {&lt;br /&gt;        return reader.readLine();&lt;br /&gt;    } finally {&lt;br /&gt;        reader.close();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;gets replaced with&lt;br /&gt;&lt;pre class="brush: java;" name="code"&gt;private String example() throws IOException {&lt;br /&gt;    try(BufferedReader reader = new BufferedReader(...) {&lt;br /&gt;         return reader.readLine();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Dr Heinz combined this technique with a way to automatically unlock locked resources in a &lt;a href="http://www.javaspecialists.eu/archive/Issue190.html"&gt;recent news letter&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;There may be a little gotcha using this where exceptions can be suppressed and have to be retrieved using &lt;code&gt;Throwable.getSuppressed()&lt;/code&gt;. This seems like it could be nasty.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Catching Multiple Exceptions&lt;/h3&gt;&lt;br /&gt;This one allows you to catch multiple exceptions using a pipe to separate the exception types. This looks like another work around for the general grips with Java but removes the duplicated code you often get catching several exceptions and treating them in the same way. For example, &lt;br /&gt;&lt;pre class="brush: java;" name="code"&gt;catch (IOException | SQLException e) {&lt;br /&gt;    logger.log(e);&lt;br /&gt;    throw ex;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;I usually end up pushing the code to execute as a &lt;code&gt;Callable&lt;/code&gt; and dealing with the exception in a lamda-like piece of code, or decorating the fragment to deal with exceptions (logging or wrapping) or even trying really hard to throw around runtime exceptions, so this one is at odds with my general approach. Given the example from Oracle above, I suspect this will just facilitate ugly, jammed in code. It seems to say "it's ok to deal with a bunch of exceptions in the same way. in fact, we'll make it easier for you" without any warning about if you actually &lt;i&gt;should&lt;/i&gt; be doing this type of thing. The fact the example above (Oracle's example, by the way) logs then re-throws is a smell in it's self. Perhaps I'm being premenstrual, but I'm not a fan of this one.  &lt;br /&gt;&lt;br /&gt;Have a look &lt;a href="http://download.java.net/jdk7/docs/#NewFeature"&gt;here&lt;/a&gt; for on the new features and download from &lt;a href="http://www.oracle.com/technetwork/java/javase/downloads/ea-jsp-142245.html"&gt;here&lt;/a&gt; (unfortunately, not for the Mac).&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: red;"&gt;&lt;b&gt;UPDATE:&lt;/b&gt;&lt;/span&gt; An extended version of this post has been published in &lt;a href="http://pequenoperro.blogspot.com/2011/06/jdk7-artcile-in-javatech-journal.html"&gt;May edition of the JavaTech Journal&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5283328307719135378" src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" style="cursor: pointer; float: left; height: 22px; margin: 0pt 10px 10px 0pt; width: 22px;" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-5100755803794529782?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/5100755803794529782/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=5100755803794529782' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/5100755803794529782'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/5100755803794529782'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2011/03/jdk7-previwed.html' title='JDK7 Previwed'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-3066094950221186624</id><published>2010-10-18T19:51:00.005Z</published><updated>2011-08-29T11:25:52.335Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='mocking'/><title type='text'>Logging is evil but...</title><content type='html'>Logging is a nightmare. I don't mean here that conveying information about exceptional circumstances is a nightmare, I mean the combination of over eager developers and [&lt;i&gt;insert your current logging framework here&lt;/i&gt;] is a recipe for disaster. We've all seen too much of &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java;" name="code"&gt;Logger log = Logger.getLogger(ThisSucks.class);&lt;br /&gt;    ...&lt;br /&gt;    try {&lt;br /&gt;        somethingRisky();&lt;br /&gt;    } catch (SomethingVeryBadException e) {&lt;br /&gt;       log.error(e);&lt;br /&gt;       throw e;&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;which is just one example where the exception handling policy for the system (it's a system-wide concern remember) is muddled at best. Nothing is saying that the same exception isn't logged elsewhere or that the exception is even handled correctly or the right people notified. It's not ok to just log and rethrow and every single time we go to declare a new logger, we should think twice.&lt;br /&gt;&lt;br /&gt;We've taken this very literally in my current project and everyone is actively discouraged from instantiating a logger. I'd rather be explicit that some exception event has occurred and fire an event that some interested party can listen for. This makes perfect sense when you think about the huge log files that someone has to trawl through, armed only with for some vague clue as to what went wrong, a grep manual and the futile hope that developers actually log something useful. All without the context of the code to actually guide them. Good luck.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The disseminated log problem is exacerbated if there is no clear audit trail tying pieces of information together. In a system with thousands of request per second, how do you tie the logged request inputs to some stack trace embedded in the middle of another thousand requests? What should have been a clear set of requirements from the business (in this case, presumably the support team) can easily get lost in the technical translation. &lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Logging is evil, but if I really *have* to log, be honest about it...&lt;/blockquote&gt;&lt;br /&gt;Asking the business &lt;i&gt;"what information do you want to see in the event of x happening"&lt;/i&gt; rather than assuming they want to see some stack trace in a huge log can make a lot of sense. We're often not logging for ourselves (we have debuggers for that), we're often logging for our customers. If we start to think about this stuff early, in terms of exception events and their audience, we can build systems that tell the outside world something meaningful in flexible ways. We start to define a system wide exception handling policy rather than relying of the default exception handler (&lt;code&gt;System.out&lt;/code&gt; is rarely the right choice!).&lt;br /&gt;&lt;br /&gt;So back to my current project... people are regularly beaten with a chair leg for creating loggers but I'll admit that on occasion, I've actually logged stuff and didn't resort to some Opus Dei style self-flagellation. Logging is evil, but if I really *have* to log, my saving grace is to be explicit about it. I'll hunt down a customer and I'll write a test to advertise the fact the log contains what they asked for.&lt;br /&gt;&lt;br /&gt;Most of the common logging frameworks make it troublesome to inject a logger instance, and I'm reluctant to subvert behaviour just because some logging framework wants me to. Logging (or preferably, firing an event) should be orthogonal to the classes core behaviour, why should I compromise? My preferred approach is the canonical example of using Aspects, or less esoterically, using decorators.&lt;br /&gt;&lt;br /&gt;For example, I created a interface to handle HTTP POST requests, imaginatively called &lt;code&gt;Post&lt;/code&gt;. Why should I add logging to implementations and open the door to ad-hoc, erratic logging? I shouldn't, but when my implementation &lt;code&gt;CustomerPost&lt;/code&gt; requires logging of the request and response, I can decorate with a &lt;code&gt;LoggingPost&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java;" name="code"&gt;public class LoggingPost implements Post {&lt;br /&gt;&lt;br /&gt;    private static final Logger LOG = Logger.getLogger(Post.class);    &lt;br /&gt;    ...&lt;br /&gt;&lt;br /&gt;    public LoggingPost(Post delegate) {&lt;br /&gt;        this.delegate = delegate;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public Response post(Body body) {&lt;br /&gt;       try {&lt;br /&gt;           return delegate.post(body);&lt;br /&gt;       } catch (IOException e) {&lt;br /&gt;           LOG.error(e.getMessage(), e);&lt;br /&gt;           throw e;&lt;br /&gt;       }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You might be concerned that the try/catch above looks very similar to the original negative example. The good thing about our decorated example above is that by being explicit about this classes responsibility, declaring the usage in the correct context, we can actually define the system wide policy for logging the &lt;code&gt;Post&lt;/code&gt; calls in one place, without affecting the contract of the interface. We'd do this for example, on the system boundary, for example where the RESTful API is implemented.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java;" name="code"&gt;@Resource&lt;br /&gt;public class CustomerServlet {&lt;br /&gt;&lt;br /&gt;    public void doPost(Request chuck, Response up) {&lt;br /&gt;        ...&lt;br /&gt;        customer = new LoggingPost(new CustomerPost(...));&lt;br /&gt;        customer.post(...)&lt;br /&gt;        ...&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;In our &lt;code&gt;LoggingPost&lt;/code&gt; above, we haven't even tried to inject a logger in to make the testing easier. Instead, mostly because I was being lazy, I used the helper class below. This is intended to represent Log4J in the context of a test and give access to the logger for assertion purposes.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java;" name="code"&gt;public class Log4J {&lt;br /&gt; &lt;br /&gt;    private final StringWriter writer = new StringWriter();&lt;br /&gt;    private final Logger logger;&lt;br /&gt;    private final String uuid = UUID.randomUUID().toString();&lt;br /&gt; &lt;br /&gt;    public static Log4J appendTo(Logger logger) {&lt;br /&gt;        return new Log4J(logger);&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    private Log4J(Logger logger) {&lt;br /&gt;        this.logger = logger;&lt;br /&gt;        WriterAppender appender = new WriterAppender(new SimpleLayout(), writer);&lt;br /&gt;        appender.setName(uuid);&lt;br /&gt;        logger.addAppender(appender);&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    public void clean() {&lt;br /&gt;        logger.removeAppender(uuid);&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    public void assertThat(Matcher&amp;lt;String&amp;gt; matcher) {&lt;br /&gt;        org.junit.Assert.assertThat(writer.toString(), matcher);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Using it in the test for &lt;code&gt;LoggingPost&lt;/code&gt; is shown below&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java;" name="code"&gt;@RunWith(JMock.class)&lt;br /&gt;public class LoggingPostTest {    &lt;br /&gt;    &lt;br /&gt;    private final Mockery context = new Mockery();&lt;br /&gt;    private final Post mock = context.mock(Post.class);&lt;br /&gt;    private final Log4J logger = Log4J.appendTo(Logger.getLogger(Post.class));&lt;br /&gt; &lt;br /&gt;    private static final String EXCEPTION_MESSAGE = "bar bar black sheep...";&lt;br /&gt; &lt;br /&gt;    @Test&lt;br /&gt;    public void shouldDelegate() throws Exception {&lt;br /&gt;        context.checking(new Expectations() {{&lt;br /&gt;            one(mock).post(...);&lt;br /&gt;        }});&lt;br /&gt;        new LoggingPost(mock).post(...);&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    @Test&lt;br /&gt;    public void shouldLogWhenExceptionIsThrown() {&lt;br /&gt;        try {&lt;br /&gt;            postWill(throwException(new IOException(EXCEPTION_MESSAGE)));&lt;br /&gt;            new LoggingPost(mock).post(...);&lt;br /&gt;            fail();&lt;br /&gt;        } catch (IOException e) {&lt;br /&gt;            logger.assertThat(allOf(containsString("ERROR"), containsString(EXCEPTION_MESSAGE)));&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    @After&lt;br /&gt;    public void cleanupLogger() {&lt;br /&gt;        logger.clean();&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    private void postWill(final Action action) {&lt;br /&gt;        context.checking(new Expectations(){{&lt;br /&gt;            allowing(mock); will(action);&lt;br /&gt;        }});&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;It relies on nasty statics to dynamically add a logger to Log4J's list of loggers and thereby appending any generated logs to something that the &lt;code&gt;Log4J&lt;/code&gt; test helper can assert on. I can't decide if I like this or not. It gives you an extra test that your class under test is using a logger with the name that you expect (&lt;code&gt;"Post.class"&lt;/code&gt; in the example above), testing your logger configuration as a by-product. &lt;br /&gt;&lt;br /&gt;What I found interesting about this though was that it was always seemed a lot of effort making some logging framework play nicely with mocks, or writing and configuring a custom in memory appender and asserting on it. With the above example, I very quickly added confirmation to existing Log4J infrastructure. It seemed almost too easy... so I'd love to hear your comments and how you write tests for logging.&lt;br /&gt;&lt;br /&gt;PS. Logging is evil.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5283328307719135378" src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" style="cursor: pointer; float: left; height: 22px; margin: 0pt 10px 10px 0pt; width: 22px;" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-3066094950221186624?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/3066094950221186624/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=3066094950221186624' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/3066094950221186624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/3066094950221186624'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2010/10/logging-is-evil-but.html' title='Logging is evil but...'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-3047982440113269757</id><published>2010-08-15T10:39:00.006Z</published><updated>2010-08-15T10:46:50.541Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='coaching'/><title type='text'>Pairing Honestly</title><content type='html'>Recently we had particularly good retrospective where the team were able to admit that each of us has had difference experiences pairing. We were honest in saying that despite having "done pairing" we'd all done different amounts of pairing and that, at times, we weren't even sure what we were supposed to get out of it. There can be a fair amount of peer pressure to pair but if the pair don't know what they can get out of it, it's unlikely to succeed. We should be honest about that. What makes a good pair (see a &lt;a href="http://pequenoperro.blogspot.com/2008/12/what-makes-good-pair.html"&gt;previous post&lt;/a&gt;) and how do we know that we're getting something out of it?&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;Once we honest in our experiences and expectations around pairing, we were able to be explicit in what we &lt;i&gt;want&lt;/i&gt; to achieve. We had the conversation along the lines of "do we even believe we &lt;i&gt;could&lt;/i&gt; get something out of pairing? Do we want to try?" and when the team bought into that idea we could be explicit about starting from scratch and putting tools in place to help us.&lt;br /&gt;&lt;br /&gt;Some techniques I favour include&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;when sitting down to start a session, stating explicitly what each individual hopes to get out of the session and what isn't helpful. In short, what they think a pairing session should be like.&lt;/li&gt;&lt;li&gt;each pair can set up one or two "rules", written on cards and placed&amp;nbsp;prominently&amp;nbsp;to remind each other about something they feel is important to the session. For example, I often have a rule "ask don't tell" to remind me to be asked before I go rambling on about something in the code.&lt;/li&gt;&lt;li&gt;the silent partner; saying up front that when not driving, the silent partner should hold their&amp;nbsp;tongue&amp;nbsp;and make notes / record a task stack. Interruption is interruption, so be considerate about when to make a comment. This one should be agreed up front, it may or may not be appropriate for your pair.&lt;/li&gt;&lt;li&gt;&lt;b&gt;most important one of all&lt;/b&gt;; have a mini pair-retrospective at the end of the session. It's a great chance to ask the question "how was that for you?" and a great way to let the other person know if some aspect didn't go well.&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Another useful tool can be the pair stairs. It's very easy to avoid pairing rather than face it's&amp;nbsp;challenges&amp;nbsp;so &lt;a href="http://www.natpryce.com/articles/000522.html"&gt;pair stairs&lt;/a&gt; can be a good way to keep you honest.&amp;nbsp;Probably the most helpful thing though is having people on the team that have lots of experience pairing, know what the team can get out of it and are able to help guide pairing sessions for the less experienced.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Pairing is hard. It's probably one of the hardest things we do as developers but it can also be one of the most rewarding, personally and for the team as a whole. Collaboration has given the world some of its greatest achievements but you have to be honest that in this case, you might have to work for it.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5283328307719135378" src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" style="cursor: pointer; float: left; height: 22px; margin: 0pt 10px 10px 0pt; width: 22px;" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-3047982440113269757?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/3047982440113269757/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=3047982440113269757' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/3047982440113269757'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/3047982440113269757'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2010/08/pairing-honestly.html' title='Pairing Honestly'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-6021241204130039426</id><published>2010-07-13T22:21:00.001Z</published><updated>2011-03-29T20:21:21.160Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='tempus-fugit'/><title type='text'>Lamdas vs. Closures</title><content type='html'>When writing Java in a functional style, apart from the verbosity of it all, it always bugged me about the terminology we use. I tend to talk about closure-like arguments but revisiting some old University materials when clearing out the loft, I've adjusted my vocabulary somewhat. Taking the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;WaitFor&lt;/span&gt; class from t&lt;a href="http://code.google.com/p/tempus-fugit/"&gt;empus-fugit&lt;/a&gt; as an example, passing an anonymous class instance as a parameter to a method that will later call the instance is a kind of functional programming. I say kind-of because its not really functional programming, Java isn't a functional language but we can bend it into a style that's similar. For example,&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java;" name="code"&gt;...&lt;br /&gt;server.start();&lt;br /&gt;waitOrTimeout(new Condition() {&lt;br /&gt;   @Override&lt;br /&gt;   public boolean isSatisfied() {&lt;br /&gt;      return server.isRunning();&lt;br /&gt;   }&lt;br /&gt;}, timeout(seconds(5)));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The annonymoose class implementing &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;Condition&lt;/span&gt; is evaluated by the method &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;waitOrTimeout&lt;/span&gt; (it's that which will call the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;isSatisfied&lt;/span&gt;) method (an annonymoose class is a type of Moose that keeps himself to himself).&lt;br /&gt;&lt;br /&gt;The recent shift to this functional style has lead to eager anticipation of JDK7 and the promise of closures. More accurately however, it's the inclusion of lamdas that we're waiting for, not closures. Closures have in fact have been available in Java since 1.1, so what's the difference?&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Lambs to the Slaughter&lt;/h3&gt;&lt;br /&gt;So, we want to be able to define anonymous functions on the fly, the result of the function is purely dependent on it's arguments and this is called a lamda. Those functions that depend on external values (not just it's arguments) are when closures come into it. The act of binding those external values to the anonymous function is referred to as &lt;i&gt;closure&lt;/i&gt;. After closure, when all variables have been captured and bound to the function, the term is closed.&lt;br /&gt;&lt;br /&gt;For example, the code snippet above will return a new &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;Condition&lt;/span&gt; instance on each invocation. Because it will bind the variable server to the anonymous function, it will return a closure. To put it another way, we'll extract the anonymous part to a method to explicitly create a new instance, such&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java;" name="code"&gt;private static Condition isRunning(final Server server) {&lt;br /&gt;   return new Condition() {&lt;br /&gt;      @Override&lt;br /&gt;      public boolean isSatisfied() {&lt;br /&gt;         return server.isRunning();&lt;br /&gt;      }&lt;br /&gt;   };&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This should make it more obvious that the variable outside the scope of the anonymous &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;Condition&lt;/span&gt; is required (the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;server&lt;/span&gt; variable), each call to the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;isRunning&lt;/span&gt; method will return a closure over the argument, the instance of which captures the value of &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;server&lt;/span&gt;. Java implements the closure by passing a reference to the outer scoped (lets say &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Foo.class&lt;/span&gt;&lt;/span&gt;) to the anonymous class (&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;Foo$1.class&lt;/span&gt;). The &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;access$000&lt;/span&gt; call accesses the appropriate private field in the outer class directly as bytecode&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java;" name="code"&gt;class Foo$1 implements Condition {&lt;br /&gt;&lt;br /&gt;    final Foo this$0;&lt;br /&gt;&lt;br /&gt;    Foo$1() {&lt;br /&gt;        this$0 = Foo.this;&lt;br /&gt;        super();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public boolean isSatisfied() {&lt;br /&gt;        return Foo.access$000(Foo.this).isRunning();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So, if, we have update the example again, this time removing the out of scope variable, we're left with something like this;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: java;" name="code"&gt;private static Condition isRunning() {&lt;br /&gt;   return new Condition() {&lt;br /&gt;      @Override&lt;br /&gt;      public boolean isSatisfied() {&lt;br /&gt;         return true; // optimistic!&lt;br /&gt;      };&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Then no out of scope variables are required, the term doesn't need to be closed. The annonymouse function that is left is effectively a lamda (not a shy Mouse).&lt;br /&gt;&lt;br /&gt;What JDK7 will (finger's crossed) bring is more explicit, concise way of expressing the same ideas. It will support lamdas as a language feature although I can't quite figure out what the example would look like in those terms. See the &lt;a href="http://cr.openjdk.java.net/%7Emr/lambda/straw-man/"&gt;straw man proposal&lt;/a&gt; and see if you can figure it out!&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5283328307719135378" src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" style="cursor: pointer; float: left; height: 22px; margin: 0pt 10px 10px 0pt; width: 22px;" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-6021241204130039426?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/6021241204130039426/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=6021241204130039426' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/6021241204130039426'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/6021241204130039426'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2010/07/lamdas-vs-closures.html' title='Lamdas vs. Closures'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-3890141409648463366</id><published>2010-07-11T16:15:00.000Z</published><updated>2010-07-11T16:15:22.436Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='coaching'/><title type='text'>Growing Team Skills</title><content type='html'>I love the idea of growing teams, the lure of the gardening analogy is just too strong... they have to be nurtured to flourish blar blar blar. What is obvious though is that team dynamics are really important and we have to be conscious of how we work together if we want to be able to reflect on how well we, the team, are doing. It's useful to understand the strengths and weaknesses of the team, together and individually so that we can a) improve and b) match people to tasks, and teams to projects. It all contributes to a happy working environment.&lt;br /&gt;&lt;br /&gt;Often, new or junior developers worry about the barrage of new and unfamiliar technologies. Technologies are such a small part of what we do in my opinion but it can be useful to be explicit about individual competencies to re-assure the bedazzled new developer. In this post, I present a tool I came up with to help, a kind of competency depth distribution chart (that makes a nice palindrome so it's a good a name as any).&lt;br /&gt;&lt;br /&gt;It works like this;&lt;br /&gt;&lt;br /&gt;As a team, define the technologies that are important / exotic / of interest. Rank them by importance. Try to limit to around 5-10. Start the distribution chart, along the Y axis you'll list the technologies, ranked by importance and on the X, the &lt;a href="http://en.wikipedia.org/wiki/Dreyfus_model_of_skill_acquisition"&gt;Dreyfus Scale of Competency&lt;/a&gt;. The team must agree on the ranking of technologies and agree on their understanding of the Dreyfus scale.&lt;br /&gt;&lt;br /&gt;Next, each team member grades themselves on the scale for each technology. It's important to be honest. The team can then agree and plot the desired competency in each area on a separate sheet (the black line in the example below). Each individual can then see immediately their delta and use it to focus their personal development.&lt;br /&gt;&lt;br /&gt;If the team choose to come together and share their individual charts, they'll be able to see how the team compares to their minimum requirements. It might be that some people are strong in some area and others less so. In this case, there's an obvious knowledge sharing opportunity and it might be that the urgency to close the delta changes. For example, if there is already an expert in some technology on the team, the others may not need to stress. Hopefully, you can start to look at the needs of the team and not the individual. Working through this as a team can also help build trust which is vital to healthy plants, sorry, teams.&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_-uMxV_fCbC4/TDnq1Y3LWYI/AAAAAAAAEoI/6m2PreTjioQ/s1600/depth-chart.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="342" src="http://4.bp.blogspot.com/_-uMxV_fCbC4/TDnq1Y3LWYI/AAAAAAAAEoI/6m2PreTjioQ/s640/depth-chart.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;If the Dreyfus scale seems a little too harsh, you could always try a scale to reflect general confidence in the area. This tool doesn't have to be about technologies, it can be about any competencies that you want analyse.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5283328307719135378" src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" style="cursor: pointer; height: 22px; margin: 0pt 10px 10px 0pt; width: 22px;" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-3890141409648463366?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/3890141409648463366/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=3890141409648463366' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/3890141409648463366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/3890141409648463366'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2010/07/growing-team-skills.html' title='Growing Team Skills'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/TDnq1Y3LWYI/AAAAAAAAEoI/6m2PreTjioQ/s72-c/depth-chart.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-2156870154330215758</id><published>2010-07-09T17:55:00.002Z</published><updated>2010-07-09T17:57:03.099Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='coaching'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='mocking'/><title type='text'>Changing Test Gears</title><content type='html'>Good poker players know when to change gears. They know when to alter their playing style from cautious to aggressive as the game changes and players drop out. They look at how the &lt;i&gt;odds change&lt;/i&gt; as the game progresses and react appropriately. It's the same with testing, you gotta know when to change gears.&lt;br /&gt;&lt;br /&gt;To put it development terms, good developers know when to change gears. They know when to change their testing style from cautious to aggressive as the code evolves.&lt;br /&gt;Lets pretend there is just three types of testing; unit, integration and acceptance. In the interest of stereotyping, we'll define them simplistically as&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Unit - single object tests, no collaborations (strict I know, but bear with me)&lt;/li&gt;&lt;li&gt;Integration - testing object collaborations, for the purposes of this article, lets assume end-to-end testing slot into this bracket&lt;/li&gt;&lt;li&gt;Acceptance - leaning towards end-to-end but key here is that they are customer authored. As such, to convince the customer these will likely be relatively coarse grained and start outside the system boundary&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h3&gt;Starting in a low gear with unit tests&lt;/h3&gt;&lt;br /&gt;People are probably most comfortable with this type of testing. The term unit testing and the technology JUnit have become so intertwined in the Java world, that people often confuse tests written with JUnit as unit tests. They may be, but they may not be. So where's the value in defining the term unit testing and how does knowing what type of test you've just written in JUnit help with changing gears?&lt;br /&gt;&lt;br /&gt;Knowing what gear you're in and knowing the terrain that’s coming up is essential for you to select the right gear. Writing a non-unit test in JUnit has value, of course it does (assuming it actually tests something) so why should I care if it’s a unit test or a chazzwazzer? Knowing where you are and where you want to be is useful because you can defer some things and avoid duplication. So for me, unit testing is good for testing the edge cases (Right BICEP) and exploring the class you're writing. It can be especially useful when you &lt;i&gt;test drive&lt;/i&gt; towards something or explore relationships and your understanding of the classes roles and responsibilities. In this sense, testing becomes a design activity or an analysis activity, a chance to phrase your thinking and understanding in code. The regression element can quickly lose value here. For example, writing a test with mocks to explore the interaction between two collaborators, A and B. Then writing a separate test to explore the same for classes B and C. Then a test for A, B and C. There was value in each test individually, but is there still value in all three when there is obvious cross-over? When might I consciously choose &lt;i&gt;not&lt;/i&gt; to write unit tests?&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Changing up to integration tests&lt;/h3&gt;&lt;br /&gt;If I know the context that a set of objects are going to work together in, I'm going to want to be confident that they work together as expected. I can't test these in isolation, so I'm going to need to test them in cooperation. At this level, my confidence is fairly high around the composites so I'm already up and running, I'm more concerned here with a broader brush approach. I'm certainly not interested in re-testing all the lower level object tests, just how they operate together. So I change up a gear and as a developer, convince myself that these object work together &lt;i&gt;in context&lt;/i&gt;. I'm most likely still using JUnit but I understand what gear I'm in.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Cruising with acceptance tests&lt;/h3&gt;&lt;br /&gt;So how about the value to the business? The unit tests in particular don't advertise value to the business, they're a developer tool and its all too easy to write individual classes well with good test coverage and yet combine them into something that doesn't work. Demonstrating to business that their specifications have been meet is the ultimate gear, and to change up to that gear and have overall confidence in the system means going through the previous gears to get there. Knowing that you'll be changing up whilst in lower gears can help you decide what to do in those lower gears.&lt;br /&gt;&lt;br /&gt;For example, lets assume the business want to &lt;i&gt;see&lt;/i&gt; the affect of a configuration file in the system. When developing the code to load and decode the contents of the file, you started by proving the component works at the unit level so why would you test that the component is wired up correctly as a unit test? You'd be forced to mock that component in some higher level component and test it calls it. But what does this give you? You can still wire the higher level component up incorrectly. The acceptance test is going to have to test this to demonstrate the affect, so there's an argument to say you can leave it to the acceptance test to verify. This might have the added bonus of avoiding "breaking up" the higher level component albeit a minor point.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The missing gear?&lt;/h3&gt;&lt;br /&gt;When we build software in a componentised way, we're often left with objects that work in isolation with their dependencies passed in. We push up and up the assembly of the objects and their ultimate iterations and are left with parts of the system that are responsible for this assembly. Hopefully this is done declaratively in code but it might be some dependency injection framework is involved. Either way, it feels like these 'assemblers' have a clear role and responsibility and so shouldn't they be tested? What gear do we test them in? Personally, I'm comfortable in limiting the assembly options and so reduce the combinations of testing required. With a single "builder" or "spring context", I'm comfortable with testing these through acceptance tests.&lt;br /&gt;&lt;br /&gt;In this article, I suppose I'm using "gears" as an analogy for pragmatism and certainly not pace. I'm not saying that good developers know when to rush, compromising quality but they do know how to optimise their testing strategies. I think its important not to get bogged down in exhaustive unit-style testing if its not of value and so understanding what gear you're in and what gear you'll soon be in can help focus your attentions. What to test and when is the question I find myself asking again and again.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5283328307719135378" src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" style="cursor: pointer; float: left; height: 22px; margin: 0pt 10px 10px 0pt; width: 22px;" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-2156870154330215758?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/2156870154330215758/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=2156870154330215758' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/2156870154330215758'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/2156870154330215758'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2010/07/changing-test-gears.html' title='Changing Test Gears'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-6272386433273093017</id><published>2010-07-07T21:01:00.000Z</published><updated>2010-07-07T21:01:31.284Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>Generate Concordion Overviews</title><content type='html'>Creating customer authored acceptance tests is awesome! I love it. Getting your users to tell you exactly what they want (and don't want) in a form that they can (ghost) write can make for a world that even the Care Bears are jealous of.&lt;br /&gt;&lt;br /&gt;I can't comment on some of the BDD targeting frameworks like &lt;a href="http://jbehave.org/"&gt;JBehave&lt;/a&gt;, &lt;a href="http://www.easyb.org/"&gt;EasyB&lt;/a&gt; or &lt;a href="http://cukes.info/"&gt;Cucumber&lt;/a&gt; but I do like using &lt;a href="http://www.concordion.org/"&gt;Concordion&lt;/a&gt;. We try and use it in such as way to fit in with a BDD approach, its flexible enough to use in almost any approach in fact. That's probably why I like it so much. It's frequently cited closest comparator is probably Fit but that's a little unfair. As I say, Concordion tries really hard not to tie you into a particular approach, so to compare it against Fit (which leans towards the inflexible in my view), doesn't serve as a fair comparison.&lt;br /&gt;&lt;br /&gt;Anyway, the point to this post isn't really to comment on Concordion but to advertise a little Ant task I wrote to help auto-generate Concordion-friendly summary pages for your existing Concordion tests.&lt;br /&gt;&lt;br /&gt;It's purpose is to collect your Concordion tests as an "overview page" which itself is a Concordion specification. You'd run just this specification and it would in turn run all your tests, giving you a nice red / green overview. You can fold it into your continuous itegration process (Ant or Maven) and publish the overview and related specifications straight to some HTTP server for your customers to review, per-build, 24/7. Nice.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;Check out the &lt;a href="http://badrobot.googlecode.com/svn/trunk/bad.robot/concordion-ant-task/manual/Overview.html"&gt;user manual&lt;/a&gt;, written as Concordion specifications and download the binaries from &lt;a href="http://code.google.com/p/badrobot/downloads/list"&gt;Google Code&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://code.google.com/p/badrobot/wiki/ConcordionAntTask"&gt;&lt;/a&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_-uMxV_fCbC4/TDTpijCjrxI/AAAAAAAAEoA/ZYmfILds2MY/s1600/concordion.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="572" src="http://4.bp.blogspot.com/_-uMxV_fCbC4/TDTpijCjrxI/AAAAAAAAEoA/ZYmfILds2MY/s640/concordion.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;As a closing note, as I mentioned Concordion, its only fair to mention &lt;a href="http://code.google.com/p/xcordion/"&gt;Xcordion&lt;/a&gt; (and more recently Xcordion2) which is essentially a fork of Concordion. The main difference being a philosophical one. If Concordion constrains some activities within the specification (mostly to encourage certain principles), Xcordion is more of a free for all. With great power comes great responsibility and all that. Whilst Xcordion2 is being worked on, be prepared to build from source. You'll notice a couple of features missing, at least in the short term.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5283328307719135378" src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" style="cursor: pointer; float: left; height: 22px; margin: 0pt 10px 10px 0pt; width: 22px;" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-6272386433273093017?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://code.google.com/p/badrobot/wiki/ConcordionAntTask' title='Generate Concordion Overviews'/><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/6272386433273093017/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=6272386433273093017' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/6272386433273093017'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/6272386433273093017'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2010/07/generate-concordion-overviews.html' title='Generate Concordion Overviews'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/TDTpijCjrxI/AAAAAAAAEoA/ZYmfILds2MY/s72-c/concordion.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-5851240037240816463</id><published>2010-06-17T07:13:00.023Z</published><updated>2010-06-18T05:53:08.795Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='coaching'/><title type='text'>Objectives</title><content type='html'>It's objective setting time for the guys at work. Aligning what's really good for you with what's good for the company shouldn't be difficult, right? Your generally heading in the same direction and have similar interests at heart. Why then do we end up with generic meaningless objectives like "attend a XXX course"? I think you can get the most out of the objective setting exercise by thinking about what you want &lt;i&gt;personally&lt;/i&gt; out of your career, don't settle for the bland, phrase your objectives so there is real value in them. So, if the company think of them in terms of&lt;br /&gt;&lt;br /&gt;S.M.A.R.T&lt;br /&gt;&lt;br /&gt;I like the think of them as &lt;br /&gt;&lt;br /&gt;S.M.A.R.T.Y&lt;br /&gt;&lt;br /&gt;Where the Y is all about YOU. Make it personal.&lt;br /&gt;&lt;br /&gt;For example, we all want to be better developers but how do you phrase that as an acceptable business objective that management can neatly label it, put in a box and pull out in twelve months time to see if it's flourished? Defining "better" in terms of SMART isn't going to be easy. How about rephrasing it and thinking about it as reflecting on your coding practice? Keep a code journal of good and bad coding choices, yours and your teams. Reflect on it regularly and update entries. Was choosing a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;ThreadsafeDooDar&lt;/span&gt; here the right decision three months on, did it ever get used in a threaded context? How about that choice of using setter over constructor injection? How's that working out for you? The responsibility to reflect is yours but you can get outside perspectives from your peers.&lt;br /&gt;&lt;br /&gt;The key personal objective here is to keep learning, the company objective is to become a better developer. It can be &lt;i&gt;specific&lt;/i&gt; because your wording will reflect something along the lines of "demonstrate a self-assessment of personal and the team coding standard and style". It's hard to avoid the word "quality" but if you do mention it, you should define it (not easy). The point is there's something the company can buy into but there's something more subtle that you can really buy into and get value from. It's all about YOU after all.&lt;br /&gt;&lt;br /&gt;It's measurable (at least from the companies perspective, and so can get signed off on) because you have your journal as evidence along with dates and conclusions. You can even emphasize a few key learning points / techniques that you've changed your opinion on. Change is good and demonstrates learning.&lt;br /&gt;&lt;br /&gt;You might be able to extend this by talking in terms of coaching. I poo poo'ed a XXX training course earlier because I feel corporate training camps are the worst place to learn anything (well, there are probably worse places but there's certainly plenty of better environments). Anyway, asking for professional and formal coaching is a great way to develop and the journal idea can be used as evidence. The coach can co-author to give it that "official stamp".&lt;br /&gt;&lt;br /&gt;An example journal template might include date, initial description (the approach you took), pros/cons of the initial decision (why you took the approach), updated thoughts (including what caused you to reflect on this specific entry), updated pros/cons, conclusion, peer comments. Try and keep an entry specific to a single decision you made in the code (coarse or fine grained). Getting a feel about what to journal and what not to journal should be pretty natural, any "niggles" you get might prompt you or spotting that you're all talking about this part of the code a lot might be a clue.&lt;br /&gt;&lt;br /&gt;The real benefit though is what you can take away from it, if you talk over your journal points with the team and keep an open mind, I'd hope it gets filled with lots of nuggets you can add to your toolbox.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5283328307719135378" src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" style="cursor: pointer; float: left; height: 22px; margin: 0pt 10px 10px 0pt; width: 22px;" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-5851240037240816463?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/5851240037240816463/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=5851240037240816463' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/5851240037240816463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/5851240037240816463'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2010/06/objectives.html' title='Objectives'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-4235315984507345365</id><published>2010-05-01T08:35:00.000Z</published><updated>2010-05-01T08:35:42.129Z</updated><title type='text'>Un/Marshalling</title><content type='html'>This post should probably be titled "Why I don't like Unmarhsalling frameworks". They just piss me off. I mean really, who wants to have to use the Java objects that they make you use? It's not that they don't represent as objects the data that the frameworks unmarshall, they do. It's more that the underlying data may or may not match your systems view of the domain. I don't want to have to run some process to generate &lt;code&gt;Foo.java&lt;/code&gt; only to convert it to &lt;code&gt;MyFoo.java&lt;/code&gt;, I'd rather go straight to &lt;code&gt;MyFoo&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;I was using Castor to do the former some time ago. It sounded like a good idea, and I got going really quickly. However, I quickly didn't like the objects its produced so had to modify the &lt;code&gt;mapping.xml&lt;/code&gt; to "tailor" the marshalling. Still fine, this was ok for a while but soon enough I descended into Castor mapping hell. I seriously spent days trying to tweak things and had to compromise the model in the end.&lt;br /&gt;&lt;br /&gt;After reflection, I thought I'd try and dump Castor. I replaced the marshalling with merging to a template and produced cleaner XML in under an hour. The unmarshalling, replaced with manually parsing the XML and inserting elements directly into objects. I couldn't believe how much less pain I was feeling!&lt;br /&gt;&lt;br /&gt;For me, the overhead of maintaining these more "manual" approaches is far less than working around any framework mismatches. If you're lucky enough to find an marhsalling framework that can grow with you, fair play, but I'm heavily biased towards a more manual approach these days. Down with [insert your framework here].&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" alt="" id="BLOGGER_PHOTO_ID_5283328307719135378" style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 22px; height: 22px;" border="0" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-4235315984507345365?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/4235315984507345365/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=4235315984507345365' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/4235315984507345365'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/4235315984507345365'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2010/05/unmarshalling.html' title='Un/Marshalling'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-2877665575382959563</id><published>2010-05-01T08:18:00.000Z</published><updated>2010-05-01T08:18:45.080Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Setter vs Constructor Injection</title><content type='html'>So what is the argument for / against? It can be a tough one to describe as I recently discovered.&lt;br /&gt;&lt;br /&gt;You can say that constructor injection forces an object to have its dependencies set explicitly and setter injection is open to forgetfulness but how powerful an argument is that really? Surely the tests would catch it if you miss a set call? Constructor injection does say upfront "this is what I need", so there's no "first call this, then this and don't forget this" - its explicit and you don't need to know the internals that setters try and expose. That's useful. But on the small, how complex do the combination of set calls get?&lt;br /&gt;&lt;br /&gt;I don't think that a large number of constructor arguments justifies defecting to the setter camp as the real smell here is often that the class is doing too much and/or has too &lt;i&gt;many&lt;/i&gt; dependencies. It's often cited that the reason there are lots of setters is because of particular dependency injection framework leads you in that direction but why compromise (I should probably say, &lt;i&gt;comply&lt;/i&gt;) because you're &lt;i&gt;told&lt;/i&gt; to?&lt;br /&gt;&lt;br /&gt;How about the way the system would grow using constructors vs setters? I think this is where the real argument lies. You can move forward perfectly happily with either approach, content with the fact that dependencies are isolated. Testing becomes simpler, more focused on the objects under test and the earth continues to orbit the sun. Its only much later when the system is all but grown up that you can look back and reflect. Have setters contributed to creating a system that is assembled in a complex, disheveled way? Are you leaning on external (ahem, xml) configuration to manage this? Alternatively, has a constructor centric approach left you with a system with a more concise declarative assembly strategy? Which has more noise? You tell me...&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" alt="" id="BLOGGER_PHOTO_ID_5283328307719135378" style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 22px; height: 22px;" border="0" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-2877665575382959563?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/2877665575382959563/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=2877665575382959563' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/2877665575382959563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/2877665575382959563'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2010/05/setter-vs-constructor-injection.html' title='Setter vs Constructor Injection'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-594689996510575973</id><published>2010-04-25T17:19:00.004Z</published><updated>2010-05-01T07:58:52.706Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='tempus-fugit'/><title type='text'>Wrapping Exceptions zzzZZ</title><content type='html'>I'm totally bored of wrapping exceptions in Java, &lt;br /&gt;&lt;br /&gt;&lt;pre class="java:nogutter:nocontrols" name="code"&gt;try {&lt;br /&gt;   // do something&lt;br /&gt;} catch (BoredomException e) {&lt;br /&gt;   // do something else&lt;br /&gt;} &lt;br /&gt;&lt;/pre&gt;It's verbose, ugly and has nothing to do with what you're really trying to convey. It's just noise (more or less). For example, when using the just &lt;i&gt;dreadful&lt;/i&gt; Google Data API to access my calendar, I wrapped a couple of underlying Google services to be able to mock. Each service wanted to throw a bunch of Google specific exceptions which I, of course, wanted to rethrow as application specific. Boring...&lt;br /&gt;&lt;br /&gt;&lt;pre class="java:nogutter:nocontrols" name="code"&gt;public O call() throws CalendarException {&lt;br /&gt;    try {&lt;br /&gt;        return service.call();  // the call to the google service&lt;br /&gt;    } catch (MalformedURLException e) {&lt;br /&gt;        throw new CalendarException(BAD_URL_MESSAGE, e); &lt;br /&gt;    } catch (IOException e) {&lt;br /&gt;        throw new CalendarException(IO_EXCEPTION_MESSAGE, e);&lt;br /&gt;    } catch (AuthenticationException e) {&lt;br /&gt;        throw new CalendarException(AUTHENTICATION_MESSAGE, e);&lt;br /&gt;    } catch (ServiceException e) {&lt;br /&gt;        throw new CalendarException(SERVICE_EXCEPTION_MESSAGE, e);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If I didn't delegate like this, every service call would have to wrap and handle the google exceptions. As I've done this a few times, I decided to add it to &lt;a href="http://code.google.com/p/tempus-fugit/"&gt;tempus-fugit&lt;/a&gt; as a &lt;code&gt;ExceptionWrapper&lt;/code&gt; class. Using this class, you can wrap a &lt;code&gt;Callable&lt;/code&gt; to rethrow any caught exception as some other (including the underlying exception as the &lt;code&gt;cause&lt;/code&gt;).&lt;br /&gt;&lt;br /&gt;So, in a similar way to the above, the client can ignore any declared exceptions and just rethrow them in-line. For example,&lt;br /&gt;&lt;br /&gt;&lt;pre class="java:nogutter:nocontrols" name="code"&gt;wrapAnyException(new Callable&amp;lt;Object&amp;gt;() {     &lt;br /&gt;    @Override     &lt;br /&gt;    public Object call() throws ServiceException {&lt;br /&gt;         // nasty code throwing a bunch of exceptions     &lt;br /&gt;    } &lt;br /&gt;}, with(CalendarException.class));&lt;br /&gt;&lt;/pre&gt;when this is in-lined further, it hopefully becomes more succinct.  &lt;br /&gt;&lt;pre class="java:nogutter:nocontrols" name="code"&gt;wrapAnyException(serviceCall(), with(CalendarException.class));&lt;/pre&gt;&lt;br /&gt;This will wrap any exception and rethrow as a new &lt;code&gt;CalendarException&lt;/code&gt; to include as the cause any underlying exception. It uses reflection to create the new exception, and forces the syntactically sugary &lt;code&gt;with&lt;/code&gt; by taking a &lt;code&gt;WithException&lt;/code&gt; as the second parameter.&lt;br /&gt;&lt;br /&gt;It's a candidate feature for tempus-fugit 1.1 for now, and will go in for sure if it gets some millage. Let me know if you find it useful. Source is &lt;a href="http://code.google.com/p/tempus-fugit/source/browse/trunk/tempus-fugit/src/main/java/com/google/code/tempusfugit/ExceptionWrapper.java"&gt;here&lt;/a&gt; with the test &lt;a href="http://code.google.com/p/tempus-fugit/source/browse/trunk/tempus-fugit/src/test/java/com/google/code/tempusfugit/SimpleExceptionWrapperTest.java"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5283328307719135378" src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" style="cursor: pointer; float: left; height: 22px; margin: 0pt 10px 10px 0pt; width: 22px;" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-594689996510575973?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/594689996510575973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=594689996510575973' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/594689996510575973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/594689996510575973'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2010/04/wrapping-exceptions-zzzzz.html' title='Wrapping Exceptions zzzZZ'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-5605379093481668727</id><published>2010-03-19T21:39:00.002Z</published><updated>2011-08-29T11:26:43.420Z</updated><title type='text'>Nibbles the Cat</title><content type='html'>What has Nibbles the Cat got to do with deadlocks? I'm glad you asked. It all started when I introduced a deadlock in some performance monitoring. I inadvertently prevented a statistic collection daemon I wrote from shutting down thanks to some unlucky timing and bad synchronisation policy. Because the synchronisation that was involved was distributed across a couple of classes (including some external classes) it wasn't obvious where they clashed. It got me thinking more about deadlocks and how many times we &lt;i&gt;actually &lt;/i&gt;see them in real systems and gave rise to me creating the &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;DeadlockDetector&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; &lt;/span&gt;class in tempus-fugit.&lt;br /&gt;&lt;br /&gt;I'm talking here about Java level deadlocks really and to illustrate the point, poor old Nibbles got himself in quite a pickle. This situation is like this; Nibbles has been abducted and the &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Kidnapper&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; &lt;/span&gt;and &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Negotiator&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; &lt;/span&gt;have started a dialogue...&lt;br /&gt;&lt;br /&gt;&lt;pre class="java:nogutter:nocontrols" name="code"&gt;public void potentialDeadlock() {&lt;br /&gt;     new Kidnapper().start();&lt;br /&gt;     new Negotiator().start();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;However, in the process of negotiation it becomes apparent that the &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;Kidnapper&lt;/span&gt;&lt;/span&gt; is unwilling to release poor Nibbles until he has received the &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;Cash&lt;/span&gt;&lt;/span&gt; and the &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;Negotiator&lt;/span&gt;&lt;/span&gt; is unwilling to part with the &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Cash&lt;/span&gt;&lt;/span&gt; until he has poor Nibbles back in his arms.&lt;br /&gt;&lt;br /&gt;By synchronising on &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;nibbles &lt;/span&gt;&lt;/span&gt;below, the &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Kidnapper&lt;/span&gt;&lt;/span&gt; is holding onto him (more specifically his monitor) until the end of the synchronised block. However, within this block the&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Kidnapper&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;is trying to take the &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;cash&lt;/span&gt;&lt;/span&gt;. The access to this method is itself synchronised on the &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;cash&lt;/span&gt;&lt;/span&gt;, meaning that no one else can access the &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;cash&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; &lt;/span&gt;whilst the&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Kidnapper&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;is grabbing it. Meanwhile, the&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Negotiator&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;is synchronising on the &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;cash&lt;/span&gt;&lt;/span&gt;, holding onto it (or again, more specifically, it's monitor) until the end of the synchronised block then within that block, it requires &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;nibbles&lt;/span&gt;&lt;/span&gt;. We can start to see the potential for deadlock.&lt;br /&gt;&lt;br /&gt;&lt;pre class="java:nogutter:nocontrols" name="code"&gt;public class Kidnapper extends Thread {&lt;br /&gt;   public void run() {&lt;br /&gt;      synchronized (nibbles) {&lt;br /&gt;         synchronized (cash) {&lt;br /&gt;            take(cash);&lt;br /&gt;         }&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class Negotiator extends Thread {&lt;br /&gt;   public void run() {&lt;br /&gt;      synchronized (cash) {&lt;br /&gt;         synchronized (nibbles) {&lt;br /&gt;            take(nibbles);&lt;br /&gt;         }&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The deadlock detector displays this woeful situation as follows.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Deadlock detected&lt;br /&gt;=================&lt;br /&gt;&lt;br /&gt;"Negotiator-Thread-1":&lt;br /&gt;  waiting to lock Monitor of com.google.code.tempusfugit.concurrency.DeadlockDetectorTest$Cat@ce4a8a&lt;br /&gt;  which is held by "Kidnapper-Thread-0"&lt;br /&gt;&lt;br /&gt;"Kidnapper-Thread-0":&lt;br /&gt;  waiting to lock Monitor of com.google.code.tempusfugit.concurrency.DeadlockDetectorTest$Cash@7fc8b2&lt;br /&gt;  which is held by "Negotiator-Thread-1"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If you fire up the example and point jconsole at it, you'll get similar results from the Thread tab. You can see how tempus-fugit tests the &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;DeadlockDetector&lt;/span&gt;&lt;/span&gt; class &lt;a href="http://tempus-fugit.googlecode.com/svn/site/documentation/xref-test/com/google/code/tempusfugit/concurrency/DeadlockDetectorTest.html"&gt;here&lt;/a&gt; and to find out more about see the project &lt;a href="http://tempus-fugit.googlecode.com/svn/site/documentation/concurrency.html#Deadlock_Detection"&gt;documentation&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;oh and don't worry, Nibbles was released and the &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Kidnapper &lt;/span&gt;&lt;/span&gt;arrested in the end.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5283328307719135378" src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" style="cursor: pointer; float: left; height: 22px; margin: 0pt 10px 10px 0pt; width: 22px;" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-5605379093481668727?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/5605379093481668727/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=5605379093481668727' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/5605379093481668727'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/5605379093481668727'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2010/03/nibbles-cat.html' title='Nibbles the Cat'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-8700079729981476480</id><published>2010-01-04T20:51:00.011Z</published><updated>2011-03-31T18:21:12.233Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='tempus-fugit'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrency'/><title type='text'>Type Safe Annotation</title><content type='html'>A new year and another Java gripe! This time its annotations and the lack of anything useful by way of parameters. Implementing the Goetz annotations from &lt;a target="_blank"  href="http://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601?ie=UTF8&amp;tag=diyfiesta&amp;link_code=btl&amp;camp=213689&amp;creative=392969"&gt;Concurrency In Practice&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=diyfiesta&amp;l=btl&amp;camp=213689&amp;creative=392969&amp;o=1&amp;a=0321349601" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important; padding: 0px !important" /&gt;, I wanted to include an enum as a parameter type. Kind of like this&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;public @interface GuardedBy {&lt;br /&gt;   Type value();&lt;br /&gt;&lt;br /&gt;   public enum Type { FIELD, CLASS; }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;So far so good. I then wanted to somehow parameterise the enum constants themselves to give extra information.&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;public @interface GuardedBy {&lt;br /&gt;   Type value();&lt;br /&gt;&lt;br /&gt;   public enum Type {&lt;br /&gt;      CLASS, FIELD;&lt;br /&gt;&lt;br /&gt;      public static Type FIELD(String field) {&lt;br /&gt;         return FIELD;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      public static Type CLASS(String type) {&lt;br /&gt;         return CLASS;&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Now, here's where the trouble began. Using the static constructor method is fine when I want to create an instance of a &lt;span style="font-family: courier new;font-size:85%;" &gt;Type&lt;/span&gt; but not when I want to annotate some method. For example,&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;@GuardedBy(GuardedBy.Type.CLASS("more info")) // javac cries &lt;br /&gt;public void foo() {&lt;br /&gt;   GuardedBy.Type type = GuardedBy.Type.CLASS("more info"); // fine&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;The compiler very quickly complains that the attribute value must be constant. Specifically,&lt;br /&gt;&lt;pre&gt;an enum annotation value must be an enum constant&lt;/pre&gt;&lt;br /&gt;To get round things, you can just create several attributes for the annotation. Rather than have a nice CLASS type which can optionally have a description, I was forced to have one attribute of type and another to capture the additional information. grrrr.&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;public @interface GuardedBy {&lt;br /&gt;   Type value();&lt;br /&gt;   String details() default "";&lt;br /&gt;&lt;br /&gt;   public enum Type { CLASS, FIELD; }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Shame on you Java for leading me on a merry dance! I'd love to know more about why things are like this, so if you've got any more details, feel free to post a comment.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;img src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" alt="" id="BLOGGER_PHOTO_ID_5283328307719135378" style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 22px; height: 22px;" border="0" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-8700079729981476480?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/8700079729981476480/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=8700079729981476480' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/8700079729981476480'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/8700079729981476480'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2010/01/type-safe-annotation.html' title='Type Safe Annotation'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-6405873026468658862</id><published>2009-12-29T19:03:00.004Z</published><updated>2010-01-02T11:46:28.688Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='tempus-fugit'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrency'/><title type='text'>Running JUnit tests in parallel</title><content type='html'>I've been playing with running tests in their own threads for a while now (in particular with reference to &lt;a href="http://pequenoperro.blogspot.com/2008/12/be-explicit-about-ui-thread-in-swt.html"&gt;GUI testing&lt;/a&gt;) and am settling on a warm fuzzy feeling towards my general approach. I'm trying to capture this warm feeling more explicitly in the &lt;a href="http://code.google.com/p/tempus-fugit/"&gt;tempus-fugit&lt;/a&gt; project and today I was working on running tests in parallel with JUnit.&lt;br /&gt;&lt;br /&gt;Looking more into recent versions of JUnit, there seems to be lots and lots of integration points for you to play with. I've been playing with &lt;span style=";font-family:courier new;font-size:85%;"  &gt;Rule&lt;/span&gt;s, &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Statement&lt;/span&gt;&lt;/span&gt;s and &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Runner&lt;/span&gt;&lt;/span&gt;s mostly and when creating your own &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;BlockJUnit4ClassRunner&lt;/span&gt;&lt;/span&gt;, I spotted you can override the scheduler which, er, schedules the actual test methods to be run.&lt;br /&gt;&lt;br /&gt;After experimenting with much less straight forward integrations, overriding the scheduler gave the following.&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;&lt;br /&gt;public class ConcurrentTestRunner extends BlockJUnit4ClassRunner {&lt;br /&gt;&lt;br /&gt;public ConcurrentTestRunner(Class type) throws Exception {&lt;br /&gt;    super(type);&lt;br /&gt;    setScheduler(new ConcurrentScheduler());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private static class ConcurrentScheduler implements RunnerScheduler {&lt;br /&gt;&lt;br /&gt;    private ExecutorService executor;&lt;br /&gt;&lt;br /&gt;    public ConcurrentScheduler() {&lt;br /&gt;        executor = newCachedThreadPool(new ThreadFactory() { ... });&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void schedule(Runnable childStatement) {&lt;br /&gt;        executor.submit(childStatement);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void finished() {&lt;br /&gt;        shutdown(executor).waitingForCompletion(seconds(10));&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;This results in all the test methods within a given class running in parallel. I'm excited about speeding up the execution time of my tests, next step would be run all tests across classes in parallel! hmmm.&lt;br /&gt;&lt;br /&gt;This is all available to use via the &lt;a href="http://code.google.com/p/tempus-fugit/"&gt;tempus-fugit&lt;/a&gt; project by the way. See the tempus-fugit &lt;a href="http://tempus-fugit.googlecode.com/svn/site/documentation/concurrency.html#Parallel_Tests"&gt;documentation&lt;/a&gt; for more details on the runner.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;img src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" alt="" id="BLOGGER_PHOTO_ID_5283328307719135378" style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 22px; height: 22px;" border="0" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-6405873026468658862?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/6405873026468658862/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=6405873026468658862' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/6405873026468658862'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/6405873026468658862'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2009/12/running-junit-tests-in-parallel.html' title='Running JUnit tests in parallel'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-4506272359758878565</id><published>2009-12-24T15:55:00.004Z</published><updated>2009-12-24T16:27:10.528Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='tempus-fugit'/><title type='text'>Flickering tests and a JUnit Rule</title><content type='html'>Occasionally I'll see pesky flickering tests. Sometimes they're green, sometimes they're red and this can happen without any code changes! Something is afoul for sure. What bugs me the most though is that when trying to fix the problem, I can never be sure that I haven't just been lucky and the green I'm seeing isn't really a false positive. I'll have to manually run the test several times before my confidence grows.&lt;br /&gt;&lt;br /&gt;In an attempt to ease this heavy burden and make light work of this drudgery, I created an &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;@Intermittent &lt;/span&gt;&lt;/span&gt;annotation with a corresponding JUnit &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Rule&lt;/span&gt;&lt;/span&gt; and &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Runner&lt;/span&gt;&lt;/span&gt;. Now, I can mark up a suspect test and get someone else to do the repetition. Joy.&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;&lt;br /&gt;@Test&lt;br /&gt;@Intermittent&lt;br /&gt;public void flickering() {&lt;br /&gt;   // ...&lt;br /&gt;}&lt;/pre&gt;I can then use the &lt;code&gt;IntermittentRule&lt;/code&gt; to run the test method repeatedly.&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;&lt;br /&gt;public class FlickeringTest {&lt;br /&gt;&lt;br /&gt; @Rule public IntermittentRule rule = new IntermittentRule();&lt;br /&gt;&lt;br /&gt; @Test&lt;br /&gt; @Intermittent&lt;br /&gt; public void flickering() {&lt;br /&gt;     // ...&lt;br /&gt; }&lt;br /&gt;} &lt;/pre&gt;Or  use the &lt;code&gt;@RunWith&lt;/code&gt; annotation to run the test using the &lt;code&gt;IntermittentTestRunner&lt;/code&gt;.          &lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;&lt;br /&gt;@RunWith(IntermittentTestRunner.class)&lt;br /&gt;public class FlickeringTest {&lt;br /&gt;&lt;br /&gt; @Rule public IntermittentRule rule = new IntermittentRule();&lt;br /&gt;&lt;br /&gt; @Test&lt;br /&gt; @Intermittent&lt;br /&gt; public void flickering() {&lt;br /&gt;     // ...&lt;br /&gt; }&lt;br /&gt;} &lt;/pre&gt;What's interesting here is the way in which the &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Rule&lt;/span&gt;&lt;/span&gt; and &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Runner&lt;/span&gt;&lt;/span&gt; interact with JUnit. Newer versions of JUnit have introduced the idea of &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Rule&lt;/span&gt;&lt;/span&gt;s and &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Statement&lt;/span&gt;&lt;/span&gt;s. Using a &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Rule&lt;/span&gt;&lt;/span&gt; allows access to the underlying &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Statement&lt;/span&gt;&lt;/span&gt; which in our case is the action to run the test method. So we're able to run the underlying statement again and again. Nice.&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Runner&lt;/span&gt;&lt;/span&gt; however, can hook into JUnit's framework a different way. It can access more than one statement and so position itself slightly differently. What this means for us is that using the &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Rule&lt;/span&gt;&lt;/span&gt; above, any             &lt;code&gt;@Before&lt;/code&gt; or &lt;code&gt;@After&lt;/code&gt; methods will only be run once but the test method will run multiple times. Using the &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Runner&lt;/span&gt;&lt;/span&gt; above however, will run any &lt;code&gt;@Before&lt;/code&gt; or &lt;code&gt;@After&lt;/code&gt; methods once for each test repetition.&lt;br /&gt;&lt;br /&gt;The code is available as part of the &lt;a href="http://code.google.com/p/tempus-fugit/"&gt;tempus-fugit&lt;/a&gt; library so feel free to &lt;a href="http://code.google.com/p/tempus-fugit/source/browse/#svn/trunk/tempus-fugit/src/main/java/com/google/code/tempusfugit/concurrency"&gt;browse&lt;/a&gt; and feedback your comments.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" alt="" id="BLOGGER_PHOTO_ID_5283328307719135378" style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 22px; height: 22px;" border="0" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-4506272359758878565?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/4506272359758878565/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=4506272359758878565' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/4506272359758878565'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/4506272359758878565'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2009/12/flickering-tests.html' title='Flickering tests and a JUnit Rule'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-6686495597067247223</id><published>2009-12-24T15:41:00.007Z</published><updated>2010-01-02T11:49:01.365Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='tempus-fugit'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrency'/><title type='text'>Deadlock detection in Java</title><content type='html'>I recently added a basic deadlock detection mechanism to &lt;a href="http://code.google.com/p/tempus-fugit/"&gt;tempus-fugit&lt;/a&gt;. The &lt;span style="font-size:85%;"&gt;&lt;a style="font-family: courier new;" href="http://code.google.com/p/tempus-fugit/source/browse/trunk/tempus-fugit/src/main/java/com/google/code/tempusfugit/concurrency/DeadlockDetector.java"&gt;DeadlockDetector&lt;/a&gt;&lt;/span&gt; class allows you to programmatically detect basic deadlocks in your Java code. You can output deadlocks using the following code (note that printing a thread dump using the &lt;span style=";font-family:courier new;font-size:85%;"  &gt;ThreadDump&lt;/span&gt; class will automatically attempt to find any deadlocks).&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;&lt;br /&gt;DeadlockDetector.printDeadlocks(System.out);&lt;br /&gt;&lt;/pre&gt;The &lt;code&gt;DeadlockDecector&lt;/code&gt; class can only spot Java monitor cyclic locking problems. It's implementation                  is basically the same as that used by &lt;code&gt;jconsole&lt;/code&gt; and &lt;code&gt;jstack&lt;/code&gt; although                  Java 1.6 versions&lt;code&gt;&lt;/code&gt; can additionally detect &lt;code&gt;Lock&lt;/code&gt;                  based cyclic problems. The types of deadlock it can detect can be illustrated in the example below.     &lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;@Test&lt;br /&gt;public void potentialDeadlock() {&lt;br /&gt;  new Kidnapper().start();&lt;br /&gt;  new Negotiator().start();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class Kidnapper extends Thread {&lt;br /&gt;  public void run() {&lt;br /&gt;     synchronized (nibbles) {&lt;br /&gt;        synchronized (cash) {&lt;br /&gt;            take(cash);&lt;br /&gt;        }&lt;br /&gt;     }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class Negotiator extends Thread {&lt;br /&gt;  public void run() {&lt;br /&gt;     synchronized (cash) {&lt;br /&gt;        synchronized (nibbles) {&lt;br /&gt;            take(nibbles);&lt;br /&gt;        }&lt;br /&gt;     }&lt;br /&gt;  }&lt;br /&gt;} &lt;/pre&gt;&lt;br /&gt;Here, the &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Kidnapper&lt;/span&gt;&lt;/span&gt; is unwilling to release poor Nibbles the &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Cat&lt;/span&gt;&lt;/span&gt; until he has the &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Cash&lt;/span&gt;&lt;/span&gt; but our &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Negotiator&lt;/span&gt;&lt;/span&gt; is unwilling to part with the &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Cash&lt;/span&gt;&lt;/span&gt;  until he has poor Nibbles back in his arms. The deadlock detector displays this woeful situation as follows.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; Deadlock detected&lt;br /&gt; =================&lt;br /&gt;&lt;br /&gt; "Negotiator-Thread-1":&lt;br /&gt;    waiting to lock Monitor of ...DeadlockDetectorTest$Cat@ce4a8a&lt;br /&gt;    which is held by "Kidnapper-Thread-0"&lt;br /&gt;&lt;br /&gt; "Kidnapper-Thread-0":&lt;br /&gt;    waiting to lock Monitor of ...DeadlockDetectorTest$Cash@7fc8b2&lt;br /&gt;    which is held by "Negotiator-Thread-1"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I don't imagine you'll need to print out information about deadlocks or thread dumps from within your code very often, but on the off chance you'll need to during debugging, they are both available for you to use in the &lt;a href="http://code.google.com/p/tempus-fugit/"&gt;tempus-fugit&lt;/a&gt; project.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" alt="" id="BLOGGER_PHOTO_ID_5283328307719135378" style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 22px; height: 22px;" border="0" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-6686495597067247223?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/6686495597067247223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=6686495597067247223' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/6686495597067247223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/6686495597067247223'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2009/12/deadlock.html' title='Deadlock detection in Java'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-3700763889994877521</id><published>2009-12-10T09:18:00.009Z</published><updated>2009-12-10T22:48:46.125Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='tempus-fugit'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrency'/><title type='text'>Atomiticy of the Thread class</title><content type='html'>I had an interesting time getting a couple of tests running for &lt;a href="http://code.google.com/p/tempus-fugit/"&gt;tempus-fugit&lt;/a&gt; recently. It threw up a couple of interesting aspects about using threads that I hadn't come across before.&lt;br /&gt;&lt;br /&gt;In one particular test, I wanted to show that &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;interrupt&lt;/span&gt;&lt;/span&gt; is called on a thread and so followed what's becoming a common pattern for me.&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;@Test&lt;br /&gt;public void sleepInterrupted() throws Exception {&lt;br /&gt;   Thread thread = threadSleepsForever();&lt;br /&gt;   thread.start();&lt;br /&gt;   waitForStartup(thread);&lt;br /&gt;   thread.interrupt();&lt;br /&gt;   waitForShutdown(thread);&lt;br /&gt;   assertThat(thread.isInterrupted(), is(true));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;The alternative patten is to wait for the assertion and avoid the wait for shutdown method above. Either way, the test above is testing the the thread created has been interrupted by checking the interrupt flag.&lt;br /&gt;&lt;br /&gt;The test was failing for me even though I was able to show that the interrupt is called and the interrupt flag is set immediately after the sleeping thread is woken. However, when the test reached the assert, it was false. Weird.&lt;br /&gt;&lt;br /&gt;I setup another thread to just poll the sleeping thread for its status and it showed the following.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;thread.isInterrupted() = false, thread.getState() = RUNNABLE&lt;br /&gt;thread.isInterrupted() = false, thread.getState() = RUNNABLE&lt;br /&gt;thread.isInterrupted() = false, thread.getState() = RUNNABLE&lt;br /&gt;thread.isInterrupted() = false, thread.getState() = TIMED_WAITING&lt;br /&gt;thread.isInterrupted() = true, thread.getState() = RUNNABLE&lt;br /&gt;thread.isInterrupted() = false, thread.getState() TERMINATED&lt;br /&gt;&lt;/pre&gt;So my thread &lt;span style="font-weight: bold; font-style: italic;"&gt;was&lt;/span&gt; interrupted! It seems to say that when a thread terminates, it will reset the interrupt status flag. Looking at the source, it looks like Java maintains the flag at the native level and not as a member of the &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Thread&lt;/span&gt;&lt;/span&gt; class.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;private native void interrupt0();&lt;/pre&gt;Looking at another run, I got the following&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;thread.isInterrupted() = false, thread.getState() = RUNNABLE&lt;br /&gt;thread.isInterrupted() = false, thread.getState() = RUNNABLE&lt;br /&gt;thread.isInterrupted() = false, thread.getState() = RUNNABLE&lt;br /&gt;thread.isInterrupted() = false, thread.getState() = TIMED_WAITING&lt;br /&gt;thread.isInterrupted() = true, thread.getState() = TIMED_WAITING&lt;br /&gt;thread.isInterrupted() = false, thread.getState() = TERMINATED&lt;br /&gt;&lt;/pre&gt;This is even more interesting as it would suggest that an &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;interrupt&lt;/span&gt;&lt;/span&gt; doesn't update the thread's state and the interrupt flag atomically.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;blockquote&gt;It would seem thread termination will reset the interrupt status flag and that an interrupt doesn't update the interrupt status flag and state atomically.&lt;/blockquote&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;As an couple of caveats to the type of test above where I want to check the interrupt status flag, its a good idea to avoid side affects by using the terribly named method &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Thread.interrupted &lt;/span&gt;&lt;/span&gt;rather than &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;isIntrrupted&lt;/span&gt;&lt;/span&gt;. I also had to use a stubbed thread to reliably tell if the interrupt was called.&lt;br /&gt;&lt;br /&gt;See the code &lt;a href="http://code.google.com/p/tempus-fugit/source/browse/trunk/tempus-fugit/src/test/java/com/google/code/tempusfugit/concurrency/ThreadUtilsTest.java"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" alt="" id="BLOGGER_PHOTO_ID_5283328307719135378" style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 22px; height: 22px;" border="0" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-3700763889994877521?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/3700763889994877521/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=3700763889994877521' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/3700763889994877521'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/3700763889994877521'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2009/12/atomiticy-of-thread-class.html' title='Atomiticy of the Thread class'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-2809568387746887678</id><published>2009-11-11T22:01:00.005Z</published><updated>2009-12-10T22:46:32.762Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='tempus-fugit'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrency'/><title type='text'>Time Flies</title><content type='html'>I've just published tempus-fugit 1.0-SNAPSHOT to &lt;a href="https://maven-repository.dev.java.net/"&gt;java.net's public maven repository&lt;/a&gt; with a view to synchronising it with Apache's uber-repo. Download &lt;a href="http://download.java.net/maven/2/com/google/code/tempus-fugit/tempus-fugit/1.0-SNAPSHOT/"&gt;here&lt;/a&gt;, or point your &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;pom&lt;/span&gt;&lt;/span&gt; at it to enjoy all the fanciful goodness inside.&lt;br /&gt;&lt;br /&gt;oh, I should mention... tempus-fugit represents two things to me&lt;br /&gt;&lt;ol&gt;&lt;li&gt;A focal point to a lot of thinking done by a lot of very smart people I've been fortunate to work with (along with my own special kind of magic) themed around concurrency and time.&lt;/li&gt;&lt;li&gt;An attempt to consolidate this thinking into a single place that can be easily reused before finally being discarded with mild disdain*.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;What it actually is, is&lt;br /&gt;&lt;ol&gt;&lt;li&gt;a dozen or so classes that capture key abstractions we've found are frequently shared across domains.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;a even smaller number of wrapper or helper classes that we've found can help using concurrency in Java that little bit nicer.&lt;/li&gt;&lt;li&gt;all with an underlying theme of testing and improving testability.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;* more specifically, in collaborative projects, it represents a move away from collaboration into a more socially introvert culture whereby collective code ownership becomes uncooperative code ownership. Eat my JAR and don't dare dream of refactoring it. Bad, robot.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" alt="" id="BLOGGER_PHOTO_ID_5283328307719135378" style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 22px; height: 22px;" border="0" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-2809568387746887678?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://download.java.net/maven/2/com/google/code/tempus-fugit/tempus-fugit/1.0-SNAPSHOT/' title='Time Flies'/><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/2809568387746887678/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=2809568387746887678' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/2809568387746887678'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/2809568387746887678'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2009/11/time-flies.html' title='Time Flies'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-1004424815510660026</id><published>2009-11-11T19:48:00.005Z</published><updated>2009-11-11T19:55:25.948Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Thawte claim I'm not to be trusted...</title><content type='html'>...well, not quite, but they have recently announced that they'd be discontinuing the Personal E-mail Certificates and Web of Trust. These were free services and it comes as bit of a blow as I've been using them to sign my JARs for WebStart deployment. As Thawte are the root authority, it meant no annoying prompts from WebStart claiming I was a would-be terrorist. Looks like I'm back to hiding in shadows.&lt;br /&gt;&lt;br /&gt;A couple of useful links below.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ciardhubh.de/node/4"&gt;http://ciardhubh.de/node/4&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.dallaway.com/acad/webstart/"&gt;http://www.dallaway.com/acad/webstart/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;img src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" alt="" id="BLOGGER_PHOTO_ID_5283328307719135378" style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 22px; height: 22px;" border="0" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-1004424815510660026?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/1004424815510660026/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=1004424815510660026' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/1004424815510660026'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/1004424815510660026'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2009/11/thawte-claim-im-not-to-be-trusted.html' title='Thawte claim I&apos;m not to be trusted...'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-7263323842146353806</id><published>2009-10-31T20:15:00.034Z</published><updated>2009-11-01T20:30:47.667Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='performance'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Performance Monitoring (Part 1)</title><content type='html'>Keeping an eye on the performance of your applications is something that it easy to neglect. We all know that we should be regularly recording key performance indicators and regularly leaning on the profiler to spot dangers early, but how often is the dust actually blown off?&lt;br /&gt;&lt;br /&gt;I've been doing a fair bit of this lately  (blowing off that is) and thought it might be a good idea to capture a few thoughts in a mini-series of posts that will be rivaled in drama only by the likes of Dynasty and Dallas. Enjoy...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Part 1. The Beginning&lt;/h3&gt;&lt;br /&gt;It's probably a shrewd move whatever your application to setup performance measurement early. I'm usually interested in two areas, the real-time &lt;span style="font-style: italic;"&gt;performance&lt;/span&gt; and the &lt;span style="font-style: italic;"&gt;resource usage&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Performance&lt;/h3&gt;&lt;br /&gt;What you define as "performance" is completely down to you and your application. It may be in the request / response world, the time taken to process a request and return a response. It may reflect the ability to handle thousands of requests within a SLA agreed time or it may be around reliability and up time, scalability or accuracy. Whatever. Some things that are usually constant though are an emphasis on time, correctness and robustness of system &lt;span style="font-style: italic;"&gt;under load&lt;/span&gt;. This is all about &lt;span style="font-style: italic;"&gt;measurement&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;optimisation&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;Response times&lt;/span&gt; - of your critical path&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;Throughput&lt;/span&gt; - typically the number of requests / transactions / operations per second&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;Load&lt;/span&gt; - the number of request / transactions / operations being observed. &lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;Success / failure counts&lt;/span&gt; - it's no good being quick if you're always wrong!&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;Garbage collection profile&lt;/span&gt; - you'll probably be more interested in this if your system is already highly performant. In these cases you can potentially see dramatic differences in critical path processing times when excessive or inefficient GC is taking place. Tuning is a specialist skill, good luck. Google Sun's G1 for renewed hope.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;h3&gt;Resources&lt;/h3&gt;&lt;br /&gt;The section on resources is more open ended, I mean hear both hardware resources and software resources (including the resources available to the JVM). Of course, taking into account the resource usage of interrelated external systems may also be of interest to the happy tuner and its all about avoiding &lt;span style="font-style: italic;"&gt;resources starvation&lt;/span&gt; and spotting &lt;span style="font-style: italic;"&gt;bottlenecks&lt;/span&gt;.&lt;br /&gt;&lt;ul&gt;&lt;li style="font-style: italic; font-weight: bold;"&gt;CPU&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;Memory&lt;/span&gt; - The JVM can theoretically allocate only 2GB to the heap on 32 bit machines and 16GB on 64 bit machines. In practice, hitting this upper bound with&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; -Xmx&lt;/span&gt;&lt;/span&gt; can be tricky. Either way, you'll want to understand the memory characteristics of your application and how it behaves if you start to reach the upper bound of the heap.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;IO&lt;/span&gt; - I mean here things like handles, database connections, physical network connections and other tasty bites. Without these, all is lost and managing these to avoid resource starvation can be of primary importance.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;Threads&lt;/span&gt; - there is a relationship between the number of threads your software requires and hardware resources available to you, &lt;span style="font-weight: bold;"&gt;threads are not unbounded in your application&lt;/span&gt; so the prudent coder will seek insight into the affect creating lots of threads will have. See a previous &lt;a href="http://pequenoperro.blogspot.com/2009/02/less-is-more.html"&gt;post&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h3&gt;Statistic Gathering&lt;/h3&gt;&lt;br /&gt;Once we have an idea of what we want to measure, the next step is to think about how to capture and represent the raw data. We need to capture the raw data and turn it into information that's useful. It turns out that turning this data into information will influence how we capture it...&lt;br /&gt;&lt;br /&gt;You could capture all the data about every single request but it's unlikely that this is the information you'll need without doing some form of manipulation. Instead, I prefer to capture information, manipulating and aggregating the data from each request as we go.&lt;br /&gt;&lt;br /&gt;For example, typically you might be interested in the means, samples or percentile based information.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Arithmetic_mean"&gt;Mean&lt;/a&gt; values are probably the simplest to get started with, recording figures like mean response time are useful but not always the full picture. Average figures can be skewed by extreme results or extreme results may be lost in the mean. Supplementing with unmodified &lt;a href="http://en.wikipedia.org/wiki/Sample_%28statistics%29"&gt;samples&lt;/a&gt; can help give a fuller picture.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Percentile_rank"&gt;Percentile&lt;/a&gt; based reporting gives more insight than a smoothed average figure. For example, if most of the requests are sub-second, it can be hard to spot the small number of slow requests. By reviewing at a particular percentile you can gain visibility of these and help determine what's an acceptable level. For example, the mean response time at the 95th percentile will likely be noticeably different than the mean.&lt;br /&gt;&lt;br /&gt;Another option is to implement a sliding view on the data. Here, you record information for, say, an hour and as time progresses beyond that hour, you start to loose past data and include new data. At most, an hour of data is available. This can be useful as rather than cumulative counts, the sliding window is visually more responsive to changes (in particular, drops). For example, once charted, a drop in a cumulative chart will show as a slow in accent of the series where with a sliding window chart, it will show as a clear drop. A subsequent post in the series will talk in more detail about this sliding window approach.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Implementing&lt;/h3&gt;&lt;br /&gt;There's plenty of ways you can as statistics to your application. Instrumenting the code at key points through decoration is a good option. Using something like AspectJ is another option and both free your code from any clutter that would otherwise pollute and distract from your classes real responsibilities. Logging is a good example of instrumentation polluting things. Typically, the act of logging has nothing to do with the role of the class doing the logging.&lt;br /&gt;&lt;br /&gt;The instrumenting code will likely be modifying objects in memory that collect and manipulate the raw data. You'll almost certainly want to make sure this memory object is thread safe and performant, it should be light weight and non-obtrusive.&lt;br /&gt;&lt;br /&gt;What happens to the memory object is up to you, but you'll need to output it for analysis at some point. I prefer to publish the objects via JMX, that way you can setup a separate 'collector' to periodically read the values and have it's wicked way with them. With this approach, its even more important to keep the object lightweight - the MBean will always be in memory (the MBean server will see to this) and so if it contains rogue references to big objects, they'll never get garbage collected. The other tip is to create one of these such objects per request type, don't create a new one per request for example.&lt;br /&gt;&lt;br /&gt;In the next exciting post in the series, I'll talk about interpreting the results you get. Hope that wasn't too dull.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;img src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" alt="" id="BLOGGER_PHOTO_ID_5283328307719135378" style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 22px; height: 22px;" border="0" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-7263323842146353806?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/7263323842146353806/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=7263323842146353806' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/7263323842146353806'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/7263323842146353806'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2009/10/performance-monitoring-part-1.html' title='Performance Monitoring (Part 1)'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-1333924875864467392</id><published>2009-08-01T11:53:00.002Z</published><updated>2010-01-08T19:08:37.946Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><title type='text'>Java source for Mac OSX</title><content type='html'>Grrrr arrrrh Apple, &lt;a href="https://connect.apple.com/cgi-bin/WebObjects/MemberSite.woa/106/wo/w6of3SKKyobz2KekZhju0abCRtK/0.0"&gt;grrrr&lt;/a&gt;... &lt;br /&gt;&lt;br /&gt;See &lt;a href="http://tech.puredanger.com/2007/09/21/java-source-mac/"&gt;here&lt;/a&gt; for a more balanced view.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-1333924875864467392?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/1333924875864467392/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=1333924875864467392' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/1333924875864467392'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/1333924875864467392'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2009/08/java-source-for-mac-osx.html' title='Java source for Mac OSX'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-7599448843063923415</id><published>2009-08-01T09:47:00.015Z</published><updated>2010-07-07T21:16:24.787Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='tempus-fugit'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrency'/><title type='text'>Abstracting ReentrantReadWriteLock</title><content type='html'>All locks in Java are reentrant, they have to be in case the owner of the monitor ends up calling a method that needs that monitor. So, if a thread requests a lock that it already holds, it'll be given it. Without this, a subclass couldn't override a snynchronised method and then call the superclass method without deadlocking.&lt;br /&gt;&lt;br /&gt;Java's &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html"&gt;&lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;ReenstrantReadWriteLock&lt;/span&gt;&lt;/span&gt;&lt;/a&gt; is about acquiring seperate &lt;span style="font-style: italic; font-weight: bold;"&gt;read&lt;/span&gt; and &lt;span style="font-style: italic; font-weight: bold;"&gt;write&lt;/span&gt; locks for efficiency. For example, in the case where you may have infrequent writes but frequent reads, it &lt;i&gt;may&lt;/i&gt; be more efficient to not synchronise &lt;span style="font-weight: bold;"&gt;all&lt;/span&gt; access with just one lock. Instead, &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html"&gt;&lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;ReenstrantReadWriteLock&lt;/span&gt;&lt;/span&gt;&lt;/a&gt; can allow all read access to only block when a write is taking place. You'll end up with multiple simultaneous reads but synchronised writes and all the reads will have guaranteed visibility of the writes.&lt;br /&gt;&lt;br /&gt;How to know when to actually use the &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html"&gt;&lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;ReenstrantReadWriteLock&lt;/span&gt;&lt;/span&gt;&lt;/a&gt; is going to have to be the subject of a followup post, but as you'd expect, profiling is going help you make decisions against your specific situation.&lt;br /&gt;&lt;br /&gt;With all &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/concurrent/locks/Lock.html"&gt;&lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;Lock&lt;/span&gt;&lt;/span&gt;&lt;/a&gt; implementations, you specifically acquire the lock and are politely asked to release the lock within a &lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;finally&lt;/span&gt;&lt;/span&gt; block. Makes sense but it always bugs me that we're forced into Java's verbosity trap, yet again.&lt;br /&gt;&lt;br /&gt;So, vanilla Java would have you;&lt;br /&gt;&lt;pre class="java:nogutter:nocontrols" name="code"&gt;Lock l = ...;&lt;br /&gt;l.lock();&lt;br /&gt;try {&lt;br /&gt;    // access the resource protected by this lock&lt;br /&gt;} finally {&lt;br /&gt;    l.unlock();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;So why not wrap the boiler plate code up in a micro-DSL and pass a closure-like thing to execute? Any implementation must call both &lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;lock&lt;/span&gt;&lt;/span&gt; and &lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;unlock&lt;/span&gt;&lt;/span&gt; and re-throw any exceptions. The following test shows this to be true.&lt;br /&gt;&lt;pre class="java:nogutter:nocontrols" name="code"&gt;@RunWith(JMock.class)&lt;br /&gt;public class ExecuteUsingLockTest {&lt;br /&gt;&lt;br /&gt;    private final Mockery context = new JUnit4Mockery() {{&lt;br /&gt;        setImposteriser(ClassImposteriser.INSTANCE);&lt;br /&gt;    }};&lt;br /&gt;&lt;br /&gt;    ReadLock readLock = context.mock(ReadLock.class);&lt;br /&gt;    WriteLock writeLock = context.mock(WriteLock.class);&lt;br /&gt;&lt;br /&gt;    @Test&lt;br /&gt;    public void readLock() {&lt;br /&gt;        setExpectationsOn(readLock);&lt;br /&gt;        execute(something()).using(readLock);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Test&lt;br /&gt;    public void writeLock() {&lt;br /&gt;        setExpectationsOn(writeLock);&lt;br /&gt;        execute(something()).using(writeLock);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Test (expected = Exception.class)&lt;br /&gt;    public void readLockThrowingException() throws Exception {&lt;br /&gt;        setExpectationsOn(readLock);&lt;br /&gt;        execute(somethingThatThrowsException()).using(readLock);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Test(expected = Exception.class)&lt;br /&gt;    public void writeLockThrowingException() throws Exception {&lt;br /&gt;        setExpectationsOn(writeLock);&lt;br /&gt;        execute(somethingThatThrowsException()).using(writeLock);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private Callable&amp;lt;Void, RuntimeException&amp;gt; something() {&lt;br /&gt;        return new Callable&amp;lt;Void, RuntimeException&amp;gt;() {&lt;br /&gt;            public Void call() throws RuntimeException {&lt;br /&gt;                return null;&lt;br /&gt;            }&lt;br /&gt;        };&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private Callable&amp;lt;Void, Exception&amp;gt; somethingThatThrowsException() {&lt;br /&gt;        return new Callable&amp;lt;Void, Exception&amp;gt;() {&lt;br /&gt;            public Void call() throws Exception {&lt;br /&gt;                throw new RuntimeException("bad robot");&lt;br /&gt;            }&lt;br /&gt;        };&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private void setExpectationsOn(final Lock lock) {&lt;br /&gt;        context.checking(new Expectations() {{&lt;br /&gt;            one(lock).lock();&lt;br /&gt;            one(lock).unlock();&lt;br /&gt;        }});&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;The implementation is fairly straight forward with a couple of interesting points to note around generics.&lt;br /&gt;&lt;pre class="java:nogutter:nocontrols" name="code"&gt;public class ExecuteUsingLock&amp;lt;T, E extends Exception&amp;gt; {&lt;br /&gt;&lt;br /&gt;    private final Callable&amp;lt;T, E&amp;gt; callable;&lt;br /&gt;&lt;br /&gt;    private ExecuteUsingLock(Callable&amp;lt;T, E&amp;gt; callable) {&lt;br /&gt;        this.callable = callable;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static &amp;lt;T, E extends Exception&amp;gt; ExecuteUsingLock&amp;lt;T, E&amp;gt; execute(Callable&amp;lt;T, E&amp;gt; callable) {&lt;br /&gt;        return new ExecuteUsingLock&amp;lt;T, E&amp;gt;(callable);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public T using(ReentrantReadWriteLock.WriteLock write) throws E {&lt;br /&gt;        try {&lt;br /&gt;            write.lock();&lt;br /&gt;            return callable.call();&lt;br /&gt;        } finally {&lt;br /&gt;            write.unlock();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public T using(ReentrantReadWriteLock.ReadLock read) throws E {&lt;br /&gt;        try {&lt;br /&gt;            read.lock();&lt;br /&gt;            return callable.call();&lt;br /&gt;        } finally {&lt;br /&gt;            read.unlock();&lt;br /&gt;        }&lt;br /&gt;    }  &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Having the &lt;a href="http://pequenoperro.blogspot.com/2009/02/more-on-micro-dsls.html"&gt;micro-DSL&lt;/a&gt; pass in the generic &lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;Callable&lt;/span&gt;&lt;/span&gt; on the static constructor meant that I couldn't make just the &lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;using&lt;/span&gt;&lt;/span&gt; method generic and instead had to link the types by making the class definition generic. You might also notice that the &lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;Callable&lt;/span&gt;&lt;/span&gt; used isn't Java's &lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;Callable&lt;/span&gt;&lt;/span&gt;, as Sun saw fit not to have the &lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;Exception&lt;/span&gt;&lt;/span&gt; as a generic type. By creating the new &lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;Callable&lt;/span&gt;&lt;/span&gt; interface below, I was able to neaten up the &lt;a href="http://pequenoperro.blogspot.com/2009/02/more-on-micro-dsls.html"&gt;micro-DSL&lt;/a&gt; so that we're not forced to throw &lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;Exception&lt;/span&gt;&lt;/span&gt; from a method that uses the &lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;ExecuteUsingLock&lt;/span&gt;&lt;/span&gt; class. Instead, you define your closure-like function to throw &lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;RuntimeException&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;A real world example might be something that updates a status probe where the variable &lt;span style="font-size: 85%;"&gt;&lt;span style="font-family: courier new;"&gt;lock&lt;/span&gt;&lt;/span&gt; below is an instance of &lt;span style="font-family: courier new; font-size: 85%;"&gt;ReentrantReadWriteLock&lt;/span&gt;.&lt;br /&gt;&lt;pre class="java:nogutter:nocontrols" name="code"&gt;public void setStatus(final Status status) {&lt;br /&gt;    execute(settingStatus(status)).using(lock.writeLock());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public String getStatus() {&lt;br /&gt;    return execute(gettingStatus()).using(lock.readLock());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private Callable&amp;lt;Void, RuntimeException&amp;gt; settingStatus(final Status status) {&lt;br /&gt;    return new Callable&amp;lt;Void, RuntimeException&amp;gt;() {&lt;br /&gt;        public Void call() {&lt;br /&gt;            EnclosingClass.this.status = status;&lt;br /&gt;            return null;&lt;br /&gt;        }&lt;br /&gt;    };&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private Callable&amp;lt;Status, RuntimeException&amp;gt; gettingStatus() {&lt;br /&gt;    return new Callable&amp;lt;Status, RuntimeException&amp;gt;() {&lt;br /&gt;        public Status call() {&lt;br /&gt;            return EnclosingClass.this.status.toString();&lt;br /&gt;        }&lt;br /&gt;    };&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;All this to avoid the boiler plate code! Fresh.&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;"&gt;Update:&lt;/span&gt; Since writing this entry, I created the&lt;a href="http://code.google.com/p/tempus-fugit/"&gt; tempus-fugit&lt;/a&gt; project to capture these kinds of ideas.&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5283328307719135378" src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" style="cursor: pointer; float: left; height: 22px; margin: 0pt 10px 10px 0pt; width: 22px;" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-7599448843063923415?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/7599448843063923415/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=7599448843063923415' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/7599448843063923415'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/7599448843063923415'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2009/08/abstracting-reentrantreadwritelock.html' title='Abstracting ReentrantReadWriteLock'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-4427345549525256045</id><published>2009-07-29T18:17:00.008Z</published><updated>2009-07-31T18:37:43.630Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>is(not(instanceOf(smell)));</title><content type='html'>For some reason, common perception is that using &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;instanceof&lt;/span&gt;&lt;/span&gt; is a bit of smell. I think its fallen in with a bad crowd and isn't really as bad as its cracked up to be.&lt;br /&gt;&lt;br /&gt;For example, given the following, what's clearer in the following exception handling code?&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;&lt;br /&gt;try {&lt;br /&gt; ...&lt;br /&gt;} catch (InvocationTargetException e) {&lt;br /&gt; if (RuntimeException.class.isAssignableFrom(e.getCause().getClass())) {&lt;br /&gt;    throw new ApplicationException(...);&lt;br /&gt; }&lt;br /&gt; throw e.getCause();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;or&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;&lt;br /&gt;try {&lt;br /&gt; ...&lt;br /&gt;} catch (InvocationTargetException e) {&lt;br /&gt; if (e.getCause() instanceof RuntimeException) {&lt;br /&gt;    throw new ApplicationException(...)&lt;br /&gt; }&lt;br /&gt; throw e.getCause();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;There seems very little difference in the semantics of the two calls, both handle class hierarchies and both handle interfaces. I think the legitimate use for &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Class.isAssignableFrom&lt;/span&gt;&lt;/span&gt; is around scenarios where reflective-type checks are more suited (for example, where the class to check against is only known or may change at runtime). Using &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Class.isInstance&lt;/span&gt;&lt;/span&gt; is a similar alternative. The other point that the &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Class.html#isAssignableFrom%28java.lang.Class%29"&gt;API documentation&lt;/a&gt; points out is that &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;isAssignableFrom &lt;/span&gt;&lt;/span&gt;works with primitives whereas &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;instanceof&lt;/span&gt;&lt;/span&gt; can not.&lt;br /&gt;&lt;br /&gt;I wonder if the bad reputation &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;instanceof&lt;/span&gt;&lt;/span&gt; suffers from is more due to often being seen in the company of strange conditional logic than anything else. The kind of stuff that seems to go against your Mumma's good advice. It may just have fallen in with a bad crowd but is itself a good kid at heart...&lt;br /&gt;&lt;br /&gt;I suspect &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;instanceof&lt;/span&gt;&lt;/span&gt;, being around since forever, is seen as a bit antiquated but given the example above using &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Class.isAssignableFrom&lt;/span&gt;&lt;/span&gt; seems to just obfuscate things. The example needs to find out why a dynamic proxy throws an exception and because the &lt;span style="font-size:85%;"&gt;&lt;a style="font-family: courier new;" href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/reflect/InvocationTargetException.html"&gt;InvocationTargetException&lt;/a&gt;&lt;/span&gt; wraps  the underlying cause, it kind of breaks checked exception handling and it feels like we need to do some conditional check. If there is a smell here, that's it. The above is trying to hide the symptom of the smell (&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;instanceof&lt;/span&gt;&lt;/span&gt;) but the smell is still there, its just harder to see. I often catch similar whiffs when catching &lt;span style="font-size:85%;"&gt;&lt;a style="font-family: courier new;" href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ExecutionException.html"&gt;ExecutionException&lt;/a&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;More conventional cases where &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;instanceof&lt;/span&gt;&lt;/span&gt; is a genuine smell may be around conditional logic making decisions based on class type where using polymrphism would be the obvious solution. It's this kind of thing that your Mumma warned you about and I suspect its this is the real smell that's rubbed off on poor downtrodden &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;instanceof&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" alt="" id="BLOGGER_PHOTO_ID_5283328307719135378" style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 22px; height: 22px;" border="0" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-4427345549525256045?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/4427345549525256045/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=4427345549525256045' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/4427345549525256045'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/4427345549525256045'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2009/07/isnotinstanceofsmell.html' title='is(not(instanceOf(smell)));'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-1295889209896485927</id><published>2009-05-29T20:37:00.009Z</published><updated>2009-12-10T22:54:07.480Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='tempus-fugit'/><category scheme='http://www.blogger.com/atom/ns#' term='mocking'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrency'/><title type='text'>Convert a Callable to a Runnable</title><content type='html'>Everytime I come accross it, it bugs me.&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Executors&lt;/span&gt;&lt;/span&gt; class has helper methods to convert from a &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Runnable&lt;/span&gt;&lt;/span&gt; to a &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Callable&lt;/span&gt;&lt;/span&gt;, presumably so you can submit an old school &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Runnable&lt;/span&gt;&lt;/span&gt; task to an exectuor, but I can never find the counterpart helper. Something to convert a &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Callable&lt;/span&gt;&lt;/span&gt; to a &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Runnable&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;I seem to keep finding myself needing one and you might think me silly for doing so but it's because I'm into the habit of coding as &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Callable&lt;/span&gt;&lt;/span&gt;s now. I tend to think of &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Runnable&lt;/span&gt;&lt;/span&gt; as simply something that can &lt;span style="font-style: italic;"&gt;run&lt;/span&gt;, not in terms of a &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Thread&lt;/span&gt;&lt;/span&gt; or concurrent task. I like the way I think about &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Runnable&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Callable&lt;/span&gt;&lt;/span&gt; is like the new cool kid, with its funky return value and the ability to throw an exception. Wow, why did I ever bother with &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Runnable&lt;/span&gt;&lt;/span&gt; in the first place? &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Callable&lt;/span&gt;&lt;/span&gt;, like &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Runnable&lt;/span&gt;&lt;/span&gt;, however is still just something that can be &lt;span style="font-style: italic;"&gt;called&lt;/span&gt;, it just so happens to fit in nicely with the executor framework and kind of looks all bling.&lt;br /&gt;&lt;br /&gt;I digress... back to jusitifying why I think I'm always needing to convert from &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Callable&lt;/span&gt;&lt;/span&gt; to &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Runnable&lt;/span&gt;&lt;/span&gt;. As I say, if both interfaces represent something that can be called, I favour &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Callable&lt;/span&gt;&lt;/span&gt; becuase its more powerful. I can return useful things and catch useful exceptions. I'm in the habit of using &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Callable&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Often then, I'll have utility classes, useful nuggets of functionality dressed up as a &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Callable&lt;/span&gt;&lt;/span&gt;, and if I want to schedule them with an executor &lt;span style="font-weight: bold; font-style: italic;"&gt;with a fixed delay or fixed rate&lt;/span&gt;, I can't. The interface wants a &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Runnable&lt;/span&gt;&lt;/span&gt; and only a &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Runnable&lt;/span&gt;&lt;/span&gt;. Most likely becuase it doesn't really make much sense to schedule a fixed rate execution of a task that returns something when it would take quite some thinking to actually do something with the return value.&lt;br /&gt;&lt;br /&gt;None the less, I'd like to schedule something at a fixed rate (ignoring the result) that I also schedule elsewhere and actually do something with the result.&lt;br /&gt;&lt;br /&gt;Starting with the tests, any helper must delegate to the &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Callable&lt;/span&gt;&lt;/span&gt; and handle any exceptions.&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;&lt;br /&gt;@RunWith(JMock.class)&lt;br /&gt;public class CallableAdapterTest {&lt;br /&gt;   private final Mockery context = new Mockery();&lt;br /&gt;   private final Callable callable = context.mock(Callable.class);&lt;br /&gt;&lt;br /&gt;   private static final Object RESULT = new Object();&lt;br /&gt;&lt;br /&gt;   @Test&lt;br /&gt;   public void delegates() throws Exception {&lt;br /&gt;      callableWill(returnValue(RESULT));&lt;br /&gt;      runnable(callable).run();&lt;br /&gt;   }  &lt;br /&gt;&lt;br /&gt;   @Test(expected=RuntimeException.class)&lt;br /&gt;   public void exceptionBubblesUp() throws Exception {&lt;br /&gt;      callableWill(throwException(new Exception()));&lt;br /&gt;      runnable(callable).run();&lt;br /&gt;   }&lt;br /&gt; &lt;br /&gt;   private void callableWill(final Action action) throws Exception {&lt;br /&gt;      context.checking(new Expectations() {{&lt;br /&gt;         one(callable).call(); will(action);&lt;br /&gt;      }});&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To get a green light, the implementation is fairly trivial.&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;&lt;br /&gt;public class CallableAdapter {&lt;br /&gt; &lt;br /&gt;   public static Runnable runnable(final Callable callable) {&lt;br /&gt;      return new Runnable() {&lt;br /&gt;         @Override&lt;br /&gt;         public void run()&lt;br /&gt;            try&lt;br /&gt;               callable.call();&lt;br /&gt;            } catch (Exception e) {&lt;br /&gt;               throw new RuntimeException(e);&lt;br /&gt;            }&lt;br /&gt;         }&lt;br /&gt;      };&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Let me know if you've got any comments,  great ideas on the subject or can improve on the implementation above.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;blockquote&gt;&lt;span style="font-weight:bold;"&gt;Update:&lt;/span&gt; Since writing this entry, I created the&lt;a href="http://code.google.com/p/tempus-fugit/"&gt; tempus-fugit&lt;/a&gt; project to capture these kinds of ideas.&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;img src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" alt="" id="BLOGGER_PHOTO_ID_5283328307719135378" style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 22px; height: 22px;" border="0" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-1295889209896485927?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/1295889209896485927/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=1295889209896485927' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/1295889209896485927'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/1295889209896485927'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2009/05/convert-callable-to-runnable.html' title='Convert a Callable to a Runnable'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-6122899162123739576</id><published>2009-03-15T11:30:00.009Z</published><updated>2009-05-29T19:20:04.514Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='swt'/><title type='text'>SWTBot vs Window Licker</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_-uMxV_fCbC4/Sb02LJ0YQQI/AAAAAAAADDc/7ubGC1lAmMs/s1600-h/GodzillaBot1972.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 144px; height: 200px;" src="http://4.bp.blogspot.com/_-uMxV_fCbC4/Sb02LJ0YQQI/AAAAAAAADDc/7ubGC1lAmMs/s200/GodzillaBot1972.png" alt="" id="BLOGGER_PHOTO_ID_5313462700609126658" border="0" /&gt;&lt;/a&gt;The title is a bit misleading because these guys arn't really squaring off like Gozilla and Gigan, the projects aren't competing and this blog isn't really a full or fair compairison. For a start Window Licker doesn't yet support SWT and as its name suggests SWTBot, er, does.&lt;br /&gt;&lt;br /&gt;My comments are really based on having a go at &lt;a href="http://groups.google.com/group/windowlicker-users/browse_thread/thread/6fb792261a9cd1e7"&gt;implementing some basic SWT support&lt;/a&gt; in Window Licker and adding some features to SWTBot so it shouldn't be taken as authoritative. This entry is more of an experience report after trying to contribute to both projects. I'll try to follow up with an API usage report when I've used both more with my applications.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Code&lt;/h3&gt;&lt;br /&gt;Window Licker supports Swing and Html (including Ajax) very elegantly and uses the Java &lt;span style="font-size:85%;"&gt;&lt;a style="font-family: courier new;" href="http://java.sun.com/j2se/1.4.2/docs/api/java/awt/Robot.html"&gt;java.awt.robot&lt;/a&gt;&lt;/span&gt; package to take control of the mouse and keyboard and generate native events. SWTBot simulates events using manual notification. That is to say it calls the SWT widget &lt;span style="font-size:85%;"&gt;notifyListeners&lt;/span&gt; method directly where as Window Licker fires native GUI events. This wouldn't necessarily be much of a distinction but it does mean SWTBot doesn't always behave exactly as expected (for example, it doesn't handle text caret movement or clearing text fields). An application under test from Window Licker behaves much more like an application driven by a user whereas SWTBot doesn't always have to wait for visual ques to move along.&lt;br /&gt;&lt;br /&gt;Window Licker feels like a more mature framework, its nicely componentised and test driven where as SWTBot seems more evolutionary and although there are plenty of nice abstractions in common with Window Licker, it is harder to test due to the lack interfaces/mocks. SWTBot's code base is sprawling and covers a lot of ground, Windows Licker feels more focused on the problem it tries to solve. Having said that, its much more straight forward contributing to SWTBot, I was able to contribute (and understand) more of the SWTBot code base upfront.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;blockquote&gt;SWTBot's project hosting presents itself as a confused, capricious old boy, shuffling papers and smelling mildly of pee&lt;/blockquote&gt;&lt;/div&gt;&lt;br /&gt;The other slight gripe I have with SWTBot is the project structure, its more suited to Eclipse than IntelliJ as its dependencies are provided via plugins rather than raw Jars. Window Licker comes with Eclipse and IntelliJ project files which is always nice. SWTBot also has several projects that make up the software, the build process isn't as obvious as others and it uses some generated code that you'll probably won't spot but still need to know about.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Project Hosting&lt;/h3&gt;&lt;br /&gt;SWTBot has recently moved to its new home on &lt;a href="http://www.eclipse.org/projects/project_summary.php?projectid=technology.swtbot"&gt;Eclipse.org&lt;/a&gt; but the team lead hasn't deprecated the &lt;a href="http://swtbot.sourceforge.net/index.html"&gt;old site&lt;/a&gt; and resources. Consequentially, it can be a bit confusing for a new user to follow when there are two subversion repositories, two sets of bug tracking instances, lots of mailings lists and so on. Window Licker is much more low key, at the time of writing there is no pre-packaged release to download, it has a minimal site on &lt;a href="http://code.google.com/p/windowlicker/"&gt;Google Code&lt;/a&gt; that invites you to just download the source and get stuck in! In lots of ways I prefer this approach.&lt;br /&gt;&lt;br /&gt;SWTBot has lots of broken links on the site and presents itself as a confused, capricious old boy, shuffling papers and smelling mildly of pee. Window Licker on the other hand, portrays itself confidently, most likely wears a monocle and speaks in a concise and authoritative tone. Even though some of what it has too say seems to go over my head.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;br /&gt;For me, SWTBot really lets itself down is how it's being run. We all realise that open source software often has to take a back seat to your day job but if you're going to release something open source and encourage participation (say by hosting it on Eclipse.org) you should really be able to take the helm and support your community. As such, I had a bit of a bad experience with SWTBot trying to get a feature committed. In short, I did a whole bunch of work after explicitly being asked to do so in order to get it committed, then when it was done, the team lead ignored it and committed a previous version I'd submitted! The previous version works fine, it did the job but i was asked to re-jig things to better fit in with the project's standards, yet it got dumped. See the &lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=259860#c28"&gt;Bugzilla trail&lt;/a&gt; less I waffle even more.&lt;br /&gt;&lt;br /&gt;It's a shame because experiences like that just lower confidence in a project, I'm unlikely to want to push any changes back now. I guess though in summary, SWTBot's code was easier to contribute to (although I was working in one small area of a large project structure). Window Licker is probably the superior technically and in terms of code quality but was harder (for me) to work with. I was working on essentially cloning some of the core Licker functionality to work with SWT and found that I didn't fully understand all the abstractions and mechanisms. I suspect that in a pairing environment, it wouldn't be a problem but contributing via email and patches is unlikely to get the most out of collaboration.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" alt="" id="BLOGGER_PHOTO_ID_5283328307719135378" style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 22px; height: 22px;" border="0" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-6122899162123739576?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/6122899162123739576/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=6122899162123739576' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/6122899162123739576'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/6122899162123739576'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2009/03/swtbot-vs-window-licker.html' title='SWTBot vs Window Licker'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/Sb02LJ0YQQI/AAAAAAAADDc/7ubGC1lAmMs/s72-c/GodzillaBot1972.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-976238070505473234</id><published>2009-02-26T19:20:00.012Z</published><updated>2009-03-17T08:59:31.804Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='performance'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Less is More</title><content type='html'>&lt;a href="http://dirtynastyfilthycode.blogspot.com/"&gt;Dirty&lt;/a&gt; and &lt;a href="http://jimsrandomrant.blogspot.com/"&gt;Jim&lt;/a&gt; were trying to convince me the other day that less is more when it comes to maximum heap size in Java. After I finally got the point, I was aghast!  Shock, horror... creating threads in Java takes up non-VM managed memory! &lt;blockquote&gt;&lt;div&gt;After running a few tests I confirmed that the lower the max heap size is, the more threads I could create. I can easily get a &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;OutOfMemoryError&lt;/span&gt;&lt;/span&gt; when allocating memory for threads way before any real heap space is used. &lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;The helpful message you'll get is.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;java.lang.OutOfMemoryError: unable to create new native thread&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I ran a simple loop that would create dozy threads (they sleep a lot) and watched how many threads could be created before the out of memory error above. I repeated this after setting the maximum heap size. Check out the results below, you can see that no real Java heap is used, still I get an out of memory error and am limited on the number of threads I can create. As a caveat, these results should in no way taken as representative on any other environment than my laptop running Java 1.6. Your mileage may vary. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_-uMxV_fCbC4/SabxCtNlpUI/AAAAAAAADCM/er62bS1oW9Y/s1600-h/64.PNG"&gt;&lt;img src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SabxCtNlpUI/AAAAAAAADCM/er62bS1oW9Y/s400/64.PNG" alt="" id="BLOGGER_PHOTO_ID_5307194239701329218" style="cursor: pointer; width: 400px; height: 129px;" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_-uMxV_fCbC4/SabxJsaTCWI/AAAAAAAADCU/WM7e4EBwsSU/s1600-h/512.PNG"&gt;&lt;img src="http://2.bp.blogspot.com/_-uMxV_fCbC4/SabxJsaTCWI/AAAAAAAADCU/WM7e4EBwsSU/s400/512.PNG" alt="" id="BLOGGER_PHOTO_ID_5307194359745284450" style="cursor: pointer; width: 400px; height: 129px;" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_-uMxV_fCbC4/SabxQc8DBkI/AAAAAAAADCc/-O6ApHci_q4/s1600-h/1512.PNG"&gt;&lt;img src="http://1.bp.blogspot.com/_-uMxV_fCbC4/SabxQc8DBkI/AAAAAAAADCc/-O6ApHci_q4/s400/1512.PNG" alt="" id="BLOGGER_PHOTO_ID_5307194475850958402" style="cursor: pointer; width: 400px; height: 129px;" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_-uMxV_fCbC4/Sab0EHyHXyI/AAAAAAAADCk/6ur4CTR3svI/s1600-h/results.PNG"&gt;&lt;img src="http://4.bp.blogspot.com/_-uMxV_fCbC4/Sab0EHyHXyI/AAAAAAAADCk/6ur4CTR3svI/s400/results.PNG" alt="" id="BLOGGER_PHOTO_ID_5307197562548608802" style="cursor: pointer; width: 344px; height: 225px;" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;I'd always considered OS native threads or light weight processes to be effectively unbounded with the restrictions being on the &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;resources&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt; &lt;/span&gt;they are associated with. I don't think this is really the case though as clearly, the act of creating a thread that does nothing and has no real resources associated with it (other than any native voodoo) requires OS memory allocation in my tests.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I thought this was really interesting as it demonstrates how small decisions can have a big impact on the run-time characteristics of a system. Being able to tune your application to suit your production requirements is always tricky. Large memory models and data manipulation can often require large heap sizes but if in &lt;span class="Apple-style-span" style="font-style: italic;"&gt;addition&lt;/span&gt;, you then want to create large numbers of threads, you might get into the murky world I've touched on here. Of course, thread pools are generally the way to go if you want to manage your resources properly, but that's another story all together.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;I'm sure Google can tell you more, but see this &lt;a href="http://www.egilh.com/blog/archive/2006/06/09/2811.aspx"&gt;random blog&lt;/a&gt; for another description.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;img src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" alt="" id="BLOGGER_PHOTO_ID_5283328307719135378" style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 22px; height: 22px;" border="0" /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-976238070505473234?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/976238070505473234/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=976238070505473234' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/976238070505473234'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/976238070505473234'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2009/02/less-is-more.html' title='Less is More'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SabxCtNlpUI/AAAAAAAADCM/er62bS1oW9Y/s72-c/64.PNG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-6249446553913436277</id><published>2009-02-23T19:34:00.008Z</published><updated>2009-02-23T21:29:29.726Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Infering the Type in a Micro DSL</title><content type='html'>In a recent &lt;a href="http://pequenoperro.blogspot.com/2009/02/more-on-micro-dsls.html"&gt;post&lt;/a&gt;, I was talking about a micro DSL to create a simple "find &lt;span style="font-style: italic;"&gt;x&lt;/span&gt; in a list" service. The key thing here is that it defines how to look for &lt;span style="font-style: italic;"&gt;x&lt;/span&gt; in the list. So the list can be a list of anything, not just a list of &lt;span style="font-style: italic;"&gt;x&lt;/span&gt;'s.&lt;br /&gt;&lt;br /&gt;Just to recap then, to find something in a list, the original client code (using a static import) looks like this.&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;&lt;br /&gt;find(needle).in(haystack)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The class (in this case &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;NeedleFinder&lt;/span&gt;&lt;/span&gt;) implements the DSL and specifically decides in the in method how to compare a &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Needle&lt;/span&gt;&lt;/span&gt; object to whatever is in the &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;haystack&lt;/span&gt;&lt;/span&gt; list. I wanted to create a more generic class so started to implement the &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;ListFinder&lt;/span&gt;&lt;/span&gt; to use generics and a couple of interesting things came out.&lt;br /&gt;&lt;br /&gt;The generified class looks like this.&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;&lt;br /&gt;public final class ListFinder&amp;lt;T, L&amp;gt; {&lt;br /&gt; private final T target;&lt;br /&gt; private List&amp;lt;L&amp;gt; list = new ArrayList&amp;lt;L&amp;gt;();&lt;br /&gt;&lt;br /&gt; private ListFinder(T target) {&lt;br /&gt;    this.target = target;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public static &amp;lt;T, L&amp;gt; ListFinder&amp;lt;T, L&amp;gt; find(T target) {&lt;br /&gt;    return new ListFinder&amp;lt;T, L&amp;gt;(target);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public ListFinder&amp;lt;T, L&amp;gt; in(List&amp;lt;L&amp;gt; list) {&lt;br /&gt;    this.list = new ArrayList&amp;lt;L&amp;gt;(list);&lt;br /&gt;    return this;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public L using(Comparator&amp;lt;T, L&amp;gt; comparator) {&lt;br /&gt;    for (L item : list) {&lt;br /&gt;       if (comparator.equals(target, item)) {&lt;br /&gt;          return item;&lt;br /&gt;       }&lt;br /&gt;    }&lt;br /&gt;    return null;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public interface Comparator&amp;lt;T, L&amp;gt; {&lt;br /&gt;    boolean equals(T target, L item);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;With the following test case showing its usage (the Needle and Bale class aren't show for brevity).&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;&lt;br /&gt;public class ListFinderTest {&lt;br /&gt;&lt;br /&gt; private final Needle needle = new Needle("Bob");&lt;br /&gt; private final Needle missing = new Needle("Billy");&lt;br /&gt; private final Bale bale1 = new Bale("Christian");&lt;br /&gt; private final Bale bale2 = new Bale("Bob in disguise");&lt;br /&gt; private final Bale bale3 = new Bale("Kelly");&lt;br /&gt; private final List&amp;lt;Bale&amp;gt; haystack = asList(bale1, bale2, bale3);&lt;br /&gt;&lt;br /&gt; private final ListFinder.Comparator&amp;lt;Needle, Bale&amp;gt; comparator = new ListFinder.Comparator&amp;lt;Needle, Bale&amp;gt;() {&lt;br /&gt;    @Override&lt;br /&gt;    public boolean equals(Needle needle, Bale bale) {&lt;br /&gt;       return bale.name.contains(needle.name);&lt;br /&gt;    }&lt;br /&gt; };&lt;br /&gt;&lt;br /&gt; @Test&lt;br /&gt; public void needleFoundInHaystack() throws Exception {&lt;br /&gt;    assertThat(find(needle).in(haystack).using(comparator), is(bale));&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Test&lt;br /&gt; public void needleNotFoundInHaystack() throws Exception {&lt;br /&gt;    assertThat(find(missing).in(haystack).using(comparator), is(nullValue()));&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private static ListFinder&amp;lt;Needle, Bale&amp;gt; find(Needle value) {&lt;br /&gt;    return ListFinder.find(value);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here we're defining the equality of a &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Needle&lt;/span&gt;&lt;/span&gt; in a list of &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Bale&lt;/span&gt;&lt;/span&gt; objects to be when the name of a &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Needle&lt;/span&gt;&lt;/span&gt; is contained in the name of the &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Bale&lt;/span&gt;&lt;/span&gt;. A silly example I know but it illustrates that we redefine what we mean by equality for the list finder by implementing the &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;ListFinder.Comparator&lt;/span&gt;&lt;/span&gt;. The concrete example that spawned the idea was when searching for a &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Race&lt;/span&gt;&lt;/span&gt; object inside a list of &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Event&lt;/span&gt;&lt;/span&gt; objects; two completely different entities.&lt;br /&gt;&lt;br /&gt;Anyway, what I thought was interesting about this example was the type inference going on in the static &lt;span style="font-style: italic;"&gt;find&lt;/span&gt; method. I originally wanted to just use &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;ListFinder.find&lt;/span&gt;&lt;/span&gt; method directly as in the following.&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;&lt;br /&gt;ListFinder.find(needle).in(haystack).using(comparator)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Where &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;ListFinder&lt;/span&gt;&lt;/span&gt; is statically imported. Usually, I'd rely on type inference here to work out that &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;needle&lt;/span&gt;&lt;/span&gt; means &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;T&lt;/span&gt;&lt;/span&gt; and therefore &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;T&lt;/span&gt;&lt;/span&gt; is of type &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Needle&lt;/span&gt;&lt;/span&gt;. However, in the case above, the compiler will complain as the &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;haystack&lt;/span&gt;&lt;/span&gt; parameter is not of type &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Object&lt;/span&gt;&lt;/span&gt;. The trick is that the generic method &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;find&lt;/span&gt;&lt;/span&gt; in &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;ListFinder&lt;/span&gt;&lt;/span&gt; needs to infer &lt;span style="font-weight: bold; font-style: italic;"&gt;two &lt;/span&gt;types (&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;T&lt;/span&gt;&lt;/span&gt; and &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;L&lt;/span&gt;&lt;/span&gt;) but only has enough information for &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;T&lt;/span&gt;&lt;/span&gt;. So it defaults &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;L&lt;/span&gt;&lt;/span&gt; to type &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Object&lt;/span&gt;&lt;/span&gt;. grrr damn Java indisputable logic.&lt;br /&gt;&lt;br /&gt;The alternative is to use the full notation as follows.&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;&lt;br /&gt;ListFinder.&amp;lt;Needle, Bale&amp;gt;find(needle).in(haystack).using(comparator)&lt;/pre&gt;&lt;br /&gt;Or (as I've done in the test) use an internal method who's return type gives the compiler enough information to infer both types. I prefer this approach as it makes the DSL expression to find a needle much more readable.&lt;br /&gt;&lt;br /&gt;So, Java can't chain methods to infer the types. I didn't really expect it to be able to so, its a bit much to ask for. Although it would be pretty sweet if it could.&lt;br /&gt;&lt;br /&gt;One last thing, &lt;a href="http://codewax.blogspot.com/"&gt;Papa Ray&lt;/a&gt; was showing me a &lt;a href="http://docs.codehaus.org/display/JEDI/Home"&gt;Jedi&lt;/a&gt; alternative to the finder. If we're lucky, he might blog about it. It seems Jedi offers some measure of insurgency against the proliferation of anonymous inner classes in lieu of closures but in all honestly, I just wanted to get in some big words in before signing off. TTFN.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;img src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" alt="" id="BLOGGER_PHOTO_ID_5283328307719135378" style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 22px; height: 22px;" border="0" /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-6249446553913436277?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/6249446553913436277/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=6249446553913436277' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/6249446553913436277'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/6249446553913436277'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2009/02/infering-type-in-micro-dsl.html' title='Infering the Type in a Micro DSL'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-946339570073213011</id><published>2009-02-16T20:06:00.015Z</published><updated>2010-03-02T10:35:41.182Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>More on Micro DSLs</title><content type='html'>I was recently talking about what I call &lt;a href="http://pequenoperro.blogspot.com/2009/01/be-more-expressive-with-builders.html"&gt;micro DSLs&lt;/a&gt; and I thought I'd follow up with another example.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So, another example of a micro DSL I found myself writing is one of finding some object within a collection of differently typed objects. In my example, I want to find a &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Race&lt;/span&gt;&lt;/span&gt; object inside a bunch of &lt;span class="Apple-style-span"  style="font-size:small;"&gt;calendar&lt;/span&gt; events objects, the finder micro DSL looks like this.&lt;/div&gt;&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;final class RaceFinder {&lt;br /&gt;&lt;br /&gt;private final Race race;&lt;br /&gt;&lt;br /&gt;   private RaceFinder(Race race) {&lt;br /&gt;      this.race = race;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   static RaceFinder find(Race race) {&lt;br /&gt;      return new RaceFinder(race);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   CalendarEventEntry in(List&amp;lt;CalendarEventEntry&amp;gt; events) {&lt;br /&gt;      for (CalendarEventEntry event : events) {&lt;br /&gt;         if (race.getName().equals(event.getTitle().getPlainText())) {&lt;br /&gt;            return event;&lt;br /&gt;         }&lt;br /&gt;      }&lt;br /&gt;      return null;&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;The way the class is built, it forces the client to use it such.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;CalendarEventEntry event = find(race).in(events);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Where &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;find&lt;/span&gt;&lt;/span&gt; is statically imported and &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;race&lt;/span&gt;&lt;/span&gt; and &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;events&lt;/span&gt;&lt;/span&gt; have been pre-populated.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;The original version had a method in the class to do the find, in the context of this class it was harder to test the find. I had a bunch of mocks and I was testing the find function amongst other behaviours of the class. The search line looked something like this.&lt;/div&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;CalendarEventEntry event = searchForRaceIn(events);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;&lt;div&gt;Why I term this a micro DSL is that it has a very specific usage (to find a race within a calendar) and it has a private constructor and public static construction method to ensure strict usage. The real thing though is the method names don't really do what they imply they're going to do. The 'in' method actually does the search, but the 'find' method doesn't do any such thing, it creates an object.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;How do you feel about this? When its used in a tiny domain like this and when it expresses the &lt;span class="Apple-style-span" style="font-style: italic;"&gt;conversation&lt;/span&gt; more concisely than the alternatives, I feel pretty good about it. It makes me realise its not the words (method names) that are important, its the sentences they put together. So I'm compromising on realistic method names for more expressive sentences. The fact that the class prevents you from constructing invalid sentences just makes the warm feeling grow.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;Micro DSLs are recognisable by their tiny-domain, the way in which construction is done to ensure they can only be called in an order that makes sense to the domain and badly named methods.&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;Micro DSLs are starting to spread in my code like jam on toast but I know I have to check myself and really justify their use before I go mad. I also had fun trying to turn the finder above into a generified class which I'll talk about in my next post. I bet you can't wait, you lucky people.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;img src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" alt="" id="BLOGGER_PHOTO_ID_5283328307719135378" style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 22px; height: 22px;" border="0" /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-946339570073213011?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/946339570073213011/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=946339570073213011' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/946339570073213011'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/946339570073213011'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2009/02/more-on-micro-dsls.html' title='More on Micro DSLs'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-1290322762870672514</id><published>2009-02-12T16:22:00.004Z</published><updated>2010-01-08T19:08:50.436Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><title type='text'>I blog, therefore, I am</title><content type='html'>Just because I blog, it doesn't mean I'm important. Just because I use commas, it doesn't mean I can grammatically correct others. Just because I use the word 'grammatically', it doesn't mean I can spell. Just becuase I can spell, it doesn't mean I can grammatically correct others spellings.&lt;br /&gt;&lt;br /&gt;Also, Twitter is shit and exists solely for the purpose of fulfilling its own wet dream.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-1290322762870672514?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/1290322762870672514/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=1290322762870672514' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/1290322762870672514'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/1290322762870672514'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2009/02/i-blog-therefore-i-am.html' title='I blog, therefore, I am'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-7226804024771639691</id><published>2009-01-24T12:12:00.014Z</published><updated>2009-01-24T12:57:23.268Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Inheritance vs Composition</title><content type='html'>When interviewing, I often like to ask a candidate to discuss inheritance vs composition using &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;Stack&lt;/span&gt; as an example.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Example 1.&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;&lt;br /&gt;public class EvilStack&amp;lt;T&amp;gt; extends Vector&amp;lt;T&amp;gt; {&lt;br /&gt;  public T pop() {&lt;br /&gt;     // ...&lt;br /&gt;  }&lt;br /&gt;  public void push(T item) {&lt;br /&gt;     // ...&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Example 2&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;&lt;br /&gt;public class Stack&amp;lt;T&amp;gt; {&lt;br /&gt;  private Vector&amp;lt;T&amp;gt; items = new Vector&amp;lt;T&amp;gt;();&lt;br /&gt;  public T pop() {&lt;br /&gt;     // ...&lt;br /&gt;  }&lt;br /&gt;  public void push(T item) {&lt;br /&gt;     // ...&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Extending &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Vector&lt;/span&gt;&lt;/span&gt; as in example 1 weakens the encapsulation of the class. Suddenly, methods to get and insert elements at specific positions are available to clients of the stack. We move from trying to create a well behaved LIFO stack to creating a socially irrisponsible monster: an &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;EvilStack&lt;/span&gt;&lt;/span&gt;.&lt;div&gt;&lt;br /&gt;So I was surprised when looking at the Java implementation to see that &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;java.util.Stack&lt;/span&gt;&lt;/span&gt; &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;extends &lt;/span&gt;Vector! Bad robot.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;img src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 22px; height: 22px;" alt="" id="BLOGGER_PHOTO_ID_5283328307719135378" border="0" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-7226804024771639691?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/7226804024771639691/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=7226804024771639691' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/7226804024771639691'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/7226804024771639691'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2009/01/inheritance-vs-composition.html' title='Inheritance vs Composition'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-7810597785529521387</id><published>2009-01-22T15:25:00.006Z</published><updated>2009-01-24T10:31:41.294Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Deprecated Annotation</title><content type='html'>Why didn't Sun add a &lt;code&gt;value&lt;/code&gt; property to the &lt;code&gt;@Deprecated&lt;/code&gt; annotation? Instead of&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;@Documented&lt;br /&gt;@Retention(RetentionPolicy.RUNTIME)&lt;br /&gt;public @interface Deprecated {&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;which kind of implies we should do the following.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;@Deprecated&lt;br /&gt;/** @deprecated use {@link Foo} instead */&lt;br /&gt;public class GoneOff {&lt;br /&gt;   // ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;why can't we have&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;@Documented&lt;br /&gt;@Retention(RetentionPolicy.RUNTIME)&lt;br /&gt;public @interface MyDeprecated{&lt;br /&gt;   public abstract String value() default "";&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;which means we can use&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;@MyDeprecated("use Foo instead")&lt;br /&gt;public class GoneOff {&lt;br /&gt;   // ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 22px; height: 22px;" alt="" id="BLOGGER_PHOTO_ID_5283328307719135378" border="0" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-7810597785529521387?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/7810597785529521387/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=7810597785529521387' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/7810597785529521387'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/7810597785529521387'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2009/01/deprecated-annotatio.html' title='Deprecated Annotation'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-8033013171341908355</id><published>2009-01-06T17:07:00.023Z</published><updated>2009-12-10T22:55:09.420Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='tempus-fugit'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrency'/><title type='text'>Be more Expressive with Builders</title><content type='html'>I came up with a neat little pattern that's helped me be more expressive in some (fairly specific) situations. Here I'll give you a feel for it using the &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;CountDownLatch&lt;/span&gt;&lt;/span&gt; class as an example.&lt;br /&gt;&lt;br /&gt;&lt;h3 style="font-family: courier new;"&gt;CountDownLatch.await()&lt;/h3&gt;Using an instance of a &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;CountDownLatch&lt;/span&gt;&lt;/span&gt;, we can wait for the latch to count down to zero, blocking the calling thread before continuing. When using a timeout, the method returns true if the count reached zero or false if the timeout expires. To make the timeout more explicit in my application code, I started with the following.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;&lt;br /&gt;public void waitForStartup() throws InterruptedException, TimeoutException {&lt;br /&gt;  if (!startup.await(5, SECONDS))&lt;br /&gt;     throw new TimeoutException();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void waitForShutdown() throws InterruptedException, TimeoutException {&lt;br /&gt;  if (!shutdown.await(5, SECONDS))&lt;br /&gt;     throw new TimeoutException();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Using a Builder with Static Constructor&lt;/h3&gt;&lt;br /&gt;To be more concise, I wanted to wrap the logic above in some kind of helper class. Thanks to lovely static imports, a private constructor and  a static factory method called &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;await()&lt;/span&gt;&lt;/span&gt;, I was able to express the same thing with the following.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;&lt;br /&gt;public void waitForStartup() throws InterruptedException, TimeoutException {&lt;br /&gt;  await(startup).with(TIMEOUT);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void waitForShutdown() throws InterruptedException, TimeoutException {&lt;br /&gt;  await(shutdown).with(TIMEOUT);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;with(...)&lt;/span&gt;&lt;/span&gt; method is the thing that actually wraps the call to the&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; await()&lt;/span&gt;&lt;/span&gt; method on the latch. I created a &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Duration&lt;/span&gt;&lt;/span&gt; class in the above case to capture the timeout constant.&lt;br /&gt;&lt;br /&gt;This can be a neat little pattern which when used sparingly can lead to little nuggets of really readable code. However, the helper class that employs the static factory can feel unnatural as the method names don't really represent their function but rather their context within the DSL that the class defines. Using a private constructor and verifying the internal state is essential to ensure that the DSL can't be used incorrectly. Basically, if there are very few methods and you make sure they can only be called in a sensible order, I'd suggest its a good pattern to follow. The helper class is shown below in full.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java:nogutter:nocontrols"&gt;&lt;br /&gt;public class CountDownLatchWithTimeout {&lt;br /&gt;&lt;br /&gt;  private final CountDownLatch latch;&lt;br /&gt;&lt;br /&gt;  private CountDownLatchWithTimeout(CountDownLatch latch) {&lt;br /&gt;     this.latch = latch;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public static CountDownLatchWithTimeout await(CountDownLatch latch) {&lt;br /&gt;     return new CountDownLatchWithTimeout(latch);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void with(Duration timeout) throws InterruptedException, TimeoutException {&lt;br /&gt;     if (!latch.await(timeout.inMillis(), MILLISECONDS))&lt;br /&gt;        throw new TimeoutException();&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 22px; height: 22px;" alt="" id="BLOGGER_PHOTO_ID_5283328307719135378" border="0" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-8033013171341908355?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/8033013171341908355/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=8033013171341908355' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/8033013171341908355'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/8033013171341908355'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2009/01/be-more-expressive-with-builders.html' title='Be more Expressive with Builders'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-811708740416796715</id><published>2008-12-31T09:15:00.006Z</published><updated>2008-12-31T09:28:18.774Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>What Makes a Good Pair?</title><content type='html'>&lt;a onblur="tryhttp://www.blogger.com/img/blank.gif {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_-uMxV_fCbC4/SVs4hfSD7JI/AAAAAAAAC3Q/FVCbxckLt6E/s1600-h/q71195623.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 200px; height: 183px;" src="http://2.bp.blogspot.com/_-uMxV_fCbC4/SVs4hfSD7JI/AAAAAAAAC3Q/FVCbxckLt6E/s200/q71195623.png" alt="" id="BLOGGER_PHOTO_ID_5285880735633501330" border="0" /&gt;&lt;/a&gt;Communication plays such a big part in what we do, we're always striving to be more expressive in our code, conveying our intent as clearly as possible. It's the same when pairing. We need to be expressive, communicate our intent, engage, listen and feedback. When we don't do these things, pairing just doesn't work. When we don't collaborate, we're not getting as much out of pairing as we could be. Perhaps it's only after working in a good pair that you realise what you're missing working in a bad pairing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-811708740416796715?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/811708740416796715/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=811708740416796715' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/811708740416796715'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/811708740416796715'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2008/12/what-makes-good-pair.html' title='What Makes a Good Pair?'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_-uMxV_fCbC4/SVs4hfSD7JI/AAAAAAAAC3Q/FVCbxckLt6E/s72-c/q71195623.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-5325055086578443443</id><published>2008-12-30T12:00:00.007Z</published><updated>2008-12-30T12:16:16.423Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='swt'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrency'/><title type='text'>Be Explicit with the UI Thread</title><content type='html'>Following up from the post &lt;a href="http://pequenoperro.blogspot.com/2008/12/swt-support-for-window-licker.html"&gt;SWT Support in Window Licker&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The thing I found most interesting about looking at this was having to be more explicit about the UI thread. When developing SWT applications, we're all aware that accessing almost anything graphical in SWT from any other thread than the UI thread spells "invalid thread access", but it was fun to be more explicit about the "UI thread".&lt;br /&gt;&lt;br /&gt;When I started to look at how I go about writing SWT applications, I noticed that&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I often run the application from a &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;main&lt;/span&gt;&lt;/span&gt; somewhere.&lt;/li&gt;&lt;li&gt;I often discover invalid thread access problems at run time.&lt;/li&gt;&lt;li&gt;I often plug the problem by wrapping the offender in a &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Display.a/sync(...)&lt;/span&gt;&lt;/span&gt; call.&lt;/li&gt;&lt;li&gt;I often have very few long running processes that need to spawn a thread and update the UI.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;It wasn't until I started looking at being able to run the application from the context of a JUnit test that I started to think in more detail about these.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Running the application from a main method&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This seems simple but being more explicit about the UI thread means that this is worth a closer look. I always used to start an SWT application from the main, in variations of the code below.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_-uMxV_fCbC4/SVjhnGg2niI/AAAAAAAAC2g/D-Oxt3L5Y_Q/s1600-h/swt-1.PNG"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; display: block; cursor: pointer; width: 400px; height: 317px;" src="http://1.bp.blogspot.com/_-uMxV_fCbC4/SVjhnGg2niI/AAAAAAAAC2g/D-Oxt3L5Y_Q/s400/swt-1.PNG" alt="" id="BLOGGER_PHOTO_ID_5285222224598834722" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The default constructor would do or delegate the work to setup the various shells and widgets and finally start the event loop. When using JFace's &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;ApplicationWindow&lt;/span&gt;&lt;/span&gt;, I'd do pretty much the same thing. Calling &lt;span style=";font-family:courier new;font-size:85%;"  &gt;window.setBlockOnOpen(true)&lt;/span&gt; just shifts the responsibility of starting the event loop to the &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;ApplicationWindow&lt;/span&gt;&lt;/span&gt; class. If you call &lt;span style=";font-family:courier new;font-size:85%;"  &gt;window.setBlockOnOpen(false)&lt;/span&gt; for example, you have to manually start an event loop.&lt;br /&gt;&lt;br /&gt;However you do it, getting into that event loop blocks the client and its the &lt;span style="font-weight: bold;"&gt;thread that executes this event loop that is called the UI thread&lt;/span&gt;. It just so happens that most SWT applications will hit that loop from the &lt;span style=";font-family:courier new;font-size:85%;"  &gt;main&lt;/span&gt; thread as you can see from the following partial thread dump.&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray;"&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Name: &lt;span style="font-weight: bold;"&gt;main&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;State: RUNNABLE&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Total blocked: 0  Total waited: 0&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Stack trace: &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;org.eclipse.swt.internal.win32.OS.WaitMessage(Native Method)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;org.eclipse.swt.widgets.Display.sleep(Unknown Source)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;com.objogate...SwtCalculator.startEventLoop(SwtCalculator.java:104)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;com.objogate...SwtCalculator.main(SwtCalculator.java:113)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;At this point, the SWT event loop is doing its thing, waiting for UI events (mouse clicks, keyboard input etc) and dispatching them to the appropriate listeners. We've also defined what we mean by the UI thread;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;div style="text-align: center; font-weight: bold;"&gt;The &lt;span style="font-style: italic;"&gt;UI thread&lt;/span&gt; or &lt;span style="font-style: italic;"&gt;event dispatching thread&lt;/span&gt; is the thread that executes the standard SWT event loop.&lt;/div&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Running the tests and GUI in different threads&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;So, if the event loop was called from within say a &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;@Before&lt;/span&gt;&lt;/span&gt; annotated method in a test, the test would block until the event loop finished, the display would be disposed and any subsequent tests against the GUI elements would quickly discover that they no longer exist.&lt;br /&gt;&lt;br /&gt;It should be pretty clear then that in order to test GUI elements the event loop has to be started in a different thread than the tests run in. The gotcha is that the test thread will likely want to interact with this UI thread in order to push buttons and make assertions and that's when we get into invalid thread access territory with SWT.&lt;br /&gt;&lt;br /&gt;The way I implemented this was to use a class extending &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Thread&lt;/span&gt;&lt;/span&gt; to represent the UI thread and to start the event loop in its &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;run()&lt;/span&gt;&lt;/span&gt; method. The tests can interact with the UI thread by either searching for the display with &lt;span style=";font-family:courier new;font-size:85%;"  &gt;Display.findDisplay(thread)&lt;/span&gt; or by cooperating and ensuring that only the default display is used (retrieving it using &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Display.getDefault()&lt;/span&gt;&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;A minor change to the application's main method is required to optionally not call the event loop when calling &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;main&lt;/span&gt;&lt;/span&gt;. For example;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_-uMxV_fCbC4/SVjqbgglEBI/AAAAAAAAC24/Ug_OpHH2xWw/s1600-h/swt-2.PNG"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; display: block; cursor: pointer; width: 400px; height: 80px;" src="http://2.bp.blogspot.com/_-uMxV_fCbC4/SVjqbgglEBI/AAAAAAAAC24/Ug_OpHH2xWw/s400/swt-2.PNG" alt="" id="BLOGGER_PHOTO_ID_5285231921023225874" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The tests can then explicitly  create a UI thread delegating shell setup to the &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;SwtCalculator&lt;/span&gt;&lt;/span&gt; class before starting the event loop and allowing the test thread to continue.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_-uMxV_fCbC4/SVjrKjq6UGI/AAAAAAAAC3A/nOVZyQi0yIY/s1600-h/swt-3.PNG"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; display: block; cursor: pointer; width: 400px; height: 180px;" src="http://3.bp.blogspot.com/_-uMxV_fCbC4/SVjrKjq6UGI/AAAAAAAAC3A/nOVZyQi0yIY/s400/swt-3.PNG" alt="" id="BLOGGER_PHOTO_ID_5285232729325719650" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The &lt;span style=";font-family:courier new;font-size:85%;"  &gt;UISetupClosure&lt;/span&gt; allows the setup code (in this case the &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;main&lt;/span&gt;&lt;/span&gt; method) to run &lt;span style="font-style: italic;"&gt;inside&lt;/span&gt; the UI thread. This uses the strategy pattern but an alternative design could just as easily sub-class the &lt;span style="font-size:85%;"&gt;UIThread&lt;/span&gt; and use the template pattern in a similar way.&lt;br /&gt;&lt;br /&gt;The interrupt allows the event loop on the UI thread to be interrupted and stop gracefully.&lt;br /&gt;&lt;br /&gt;The following partial thread dump shows it in action. As you can see, a explicit thread has started the event loop (the &lt;span style=";font-family:courier new;font-size:85%;"  &gt;Display.sleep&lt;/span&gt; and &lt;span style=";font-family:courier new;font-size:85%;"  &gt;WaitMessage&lt;/span&gt; are the hints).&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray;"&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Name: &lt;span style="font-weight: bold;"&gt;SWT-Event-Dispatcher-Thread-1&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;State: RUNNABLE&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Total blocked: 0  Total waited: 0&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Stack trace: &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;org.eclipse.swt.internal.win32.OS.WaitMessage(Native Method)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;org.eclipse.swt.widgets.Display.sleep(Unknown Source)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;com.objogate.wl.swt.UIThread.startEventLoop(UIThread.java:90)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;com.objogate.wl.swt.UIThread.run(UIThread.java:68)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;   - locked java.lang.Class@1d7fbfb&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;It was a good exercise exploring the UI thread and I encourage you to take a look at &lt;a href="http://code.google.com/p/windowlicker/"&gt;Window Licker&lt;/a&gt; (and my &lt;a href="http://windowlicker-users.googlegroups.com/web/window-licker-swt-spike.patch"&gt;SWT patch&lt;/a&gt;). Have a play and see if you agree with the approach I took above.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 22px; height: 22px;" alt="" id="BLOGGER_PHOTO_ID_5283328307719135378" border="0" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-5325055086578443443?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/5325055086578443443/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=5325055086578443443' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/5325055086578443443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/5325055086578443443'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2008/12/be-explicit-about-ui-thread-in-swt.html' title='Be Explicit with the UI Thread'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_-uMxV_fCbC4/SVjhnGg2niI/AAAAAAAAC2g/D-Oxt3L5Y_Q/s72-c/swt-1.PNG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-8743513124842450285</id><published>2008-12-29T14:05:00.006Z</published><updated>2008-12-29T15:39:20.485Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='swt'/><title type='text'>SWT Support for Window Licker</title><content type='html'>&lt;a href="http://code.google.com/p/windowlicker/"&gt;Window &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Licker&lt;/span&gt;&lt;/a&gt; is a framework designed to help you define your own fluent &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;API&lt;/span&gt; for GUI testing. It provides a driver style &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;API&lt;/span&gt; that your Swing or Ajax applications plug into before you go about writing GUI tests in a &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_3"&gt;language&lt;/span&gt; natural to your application.&lt;br /&gt;&lt;br /&gt;We've been doing some driver based GUI testing for our web apps using &lt;a href="http://htmlunit.sourceforge.net/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;HtmlUnit&lt;/span&gt;&lt;/a&gt; so I was naturally interested in Window &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Licker&lt;/span&gt; with regard to rich client based testing. I've been trying to test my &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;SWT&lt;/span&gt; based apps at the unit level as much as possible, but it's not always straight forward &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_7"&gt;separating&lt;/span&gt; the behaviour of GUI classes from GUI elements. How do you test that all the validation behaviour is plumbed in correctly and fires at the right time in a text box? So, Window &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;Licker&lt;/span&gt; seemed like a great candidate to getting some real user style testing. Great!&lt;br /&gt;&lt;br /&gt;The bad news is that Window &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;Licker&lt;/span&gt; doesn't yet support &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;SWT&lt;/span&gt;. Boo! The good news is it gave me a great chance to have a go at implementing basic &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;SWT&lt;/span&gt; support in Window &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;Licker&lt;/span&gt;. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;Yey&lt;/span&gt;!&lt;br /&gt;&lt;br /&gt;Check out the &lt;a href="http://windowlicker-users.googlegroups.com/web/window-licker-swt-spike.patch"&gt;patch&lt;/a&gt; I wrote, or the &lt;a href="http://groups.google.com/group/windowlicker-users/browse_thread/thread/6fb792261a9cd1e7"&gt;thread&lt;/a&gt; where we discuss it.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 22px; height: 22px;" alt="" id="BLOGGER_PHOTO_ID_5283328307719135378" border="0" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-8743513124842450285?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/8743513124842450285/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=8743513124842450285' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/8743513124842450285'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/8743513124842450285'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2008/12/swt-support-for-window-licker.html' title='SWT Support for Window Licker'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-2773042527516655705</id><published>2008-12-29T12:03:00.004Z</published><updated>2008-12-29T13:46:10.364Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='swt'/><title type='text'>SWT Applications on Mac OS X</title><content type='html'>I've had a couple of problems running SWT applications on Mac, in particular, getting balloon tool tips to appear and incorrect invalid thread access errors. It seems that the Mac specific VM option     &lt;tt&gt;-XstartOnFirstThread&lt;/tt&gt; is the cure to what ails ya! It even addresses the bug I reported &lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=247218"&gt;here&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;It seems that by default, Java will not start on the main thread. Cocoa/Carbon/[insert mac vodoo here] starts it all and as a consequence, the SWT UI thread might get associated with it and not your main application thread. Therefore, whenever the application tries to access it (even though it looks like it owns it in your code), it may not and invalid thread access hilarity will ensue.&lt;br /&gt;&lt;br /&gt;The flip side to this is that AWT/Swing apps and plugins might have problems.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 22px; height: 22px;" alt="" id="BLOGGER_PHOTO_ID_5283328307719135378" border="0" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-2773042527516655705?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.eclipse.org/swt/macosx/' title='SWT Applications on Mac OS X'/><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/2773042527516655705/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=2773042527516655705' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/2773042527516655705'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/2773042527516655705'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2008/12/swt-applications-on-mac-os-x.html' title='SWT Applications on Mac OS X'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-8562099776868392159</id><published>2008-12-24T11:36:00.008Z</published><updated>2008-12-24T14:52:55.371Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='mocking'/><category scheme='http://www.blogger.com/atom/ns#' term='swt'/><title type='text'>Interfaces vs Class Imposterisers</title><content type='html'>I've been mocking with JMock2 for a while now and fully buy into using mocks and driving out behaviour using interfaces. However, I'm not sure I get the resistance when people want to use class imposterisers.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I've been doing a lot with SWT lately and always want to unit test the GUI elements. One way I've managed to do this is to mock parts of the GUI framework using imposterisers. Unless I want a full on GUI brought up, there just isn't another way. The GUI API doesn't offer me any convienent interfaces and I can't even create sub-classed mocks myself as the framework prevents you sub-classing with run time checks.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I understand that by slowly teasing out behaviour during the mocking / TDD process you can clearly express the collaborations a class may have but I feel that you can still be clear about a classes behaviour when imposterising. It's just code right? I'm not sure I care that collaborations are documented as interfaces or not, my tests express the relationships and I've gone through the same thought process to understand clearly how the classes under test interact.  So why is an imposter a bad guy?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In the case of legacy code or third part code, you're kind of stuck with imposterisers right? I mean you could build an application layer between your code and the third party stuff but I'd want better motivation for doing this than to avoid using imposterisers. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In the traditional description of an interface, we're taught to use interfaces when we want to share behaviour across multiple implementations. When driven to creating interfaces for mocking purposes we often only ever have one implementation in production which would seem at odds with this traditional definition. We do usually end up with a well designed applications which are nicely componentised and plugable, but we rarely plug anything different in. This in itself often leads us to testing the production configuration in larger end-to-end style tests.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So I feel that if you're clear about what's driving you to expose a public method on a class, your test exercises the collaboration clearly with mocks and your class under test is small and discrete then imposterising isn't really the devils work. You've considered what you're doing and why and at the end of the day, you've created a unit test that does what its supposed to.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If working naturally defining interfaces, then like me, mock away but at least consider not creating an interface if the only reason you're doing this is for mocking. If you do end up creating an interface just for mocking, don't do it &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;just &lt;/span&gt;for mocking but take it further and be explicit in why you're formalising the collaboration. Think about the behaviour and let it drive your design.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;img src="http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s320/gibble_22x22.png" style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 22px; height: 22px;" alt="" id="BLOGGER_PHOTO_ID_5283328307719135378" border="0" /&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-8562099776868392159?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/8562099776868392159/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=8562099776868392159' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/8562099776868392159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/8562099776868392159'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2008/12/interfaces-vs-class-imposterisers.html' title='Interfaces vs Class Imposterisers'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-5329960031028190216</id><published>2008-12-17T18:52:00.011Z</published><updated>2009-12-10T22:55:52.796Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='tempus-fugit'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrency'/><title type='text'>JUnit and Threaded Tests</title><content type='html'>I recently noticed a bit of a problem when playing with threads within &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;JUnit&lt;/span&gt;. Take the following snippet as an example;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_-uMxV_fCbC4/SUlOlaoBGJI/AAAAAAAAC0E/I1NXP9vyXHw/s1600-h/thread.PNG"&gt;&lt;img style="cursor: pointer; width: 400px; height: 234px;" src="http://2.bp.blogspot.com/_-uMxV_fCbC4/SUlOlaoBGJI/AAAAAAAAC0E/I1NXP9vyXHw/s400/thread.PNG" alt="" id="BLOGGER_PHOTO_ID_5280838442777909394" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here, the string "&lt;span style="font-family:courier new;"&gt;bye&lt;/span&gt;" is never shown, it would seem that when the test method finishes it somehow messes with the threads...&lt;br /&gt;&lt;br /&gt;Looking into things, it seems in my case that naughty Eclipse is muddying the water! The &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;RemoteTestRunner&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; class which Eclipse uses to run the tests ends up calling &lt;span style=";font-family:courier new;font-size:85%;"  &gt;System.exit(0)&lt;/span&gt; after it's run all the tests to kill the parent Java process. Even if we changed the daemon status of the thread, you'd get the same behaviour, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;ie&lt;/span&gt;, no "bye" being shown. Bad robot.&lt;br /&gt;&lt;br /&gt;So, in some situations it is possible to &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_3"&gt;interrupt&lt;/span&gt; a thread in a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;JUnit&lt;/span&gt; test bypassing the &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_5"&gt;interrupt&lt;/span&gt; mechanism when running a test from Eclipse. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;IntelliJ&lt;/span&gt; actually seems to have the same behaviour but I can't review to source to confirm.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://lh6.ggpht.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/gibble_22x22.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 22px; height: 22px;" src="http://lh6.ggpht.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/gibble_22x22.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-5329960031028190216?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/5329960031028190216/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=5329960031028190216' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/5329960031028190216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/5329960031028190216'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2008/12/junit-and-threaded-tests-i-recently.html' title='JUnit and Threaded Tests'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_-uMxV_fCbC4/SUlOlaoBGJI/AAAAAAAAC0E/I1NXP9vyXHw/s72-c/thread.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-560793931631214223</id><published>2008-12-11T18:55:00.006Z</published><updated>2008-12-24T14:37:53.870Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>XPDay 2008</title><content type='html'>Bit disappointing really. Things didn't get started properly will around 12:00 on day 1. I got to attend two really interesting talks of ~30 minutes each but then got trapped in a couple of nightmarish 'Open Spaces' which ended up being a rather self-indulgent discussions about nothing in particular.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://lh6.ggpht.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/gibble_22x22.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 22px; height: 22px;" src="http://lh6.ggpht.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/gibble_22x22.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-560793931631214223?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/560793931631214223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=560793931631214223' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/560793931631214223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/560793931631214223'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2008/12/xpday-2008-bit-disappointing-this-year.html' title='XPDay 2008'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_-uMxV_fCbC4/SVInGoVdYJI/AAAAAAAAC08/I4RV1KzCyPo/s72-c/gibble_22x22.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20485368.post-114232802583295457</id><published>2006-03-14T09:19:00.002Z</published><updated>2008-12-17T19:39:44.648Z</updated><title type='text'>New Blog</title><content type='html'>Moved to a new blog today at blogspot.com. How exciting does life get?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20485368-114232802583295457?l=pequenoperro.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pequenoperro.blogspot.com/feeds/114232802583295457/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20485368&amp;postID=114232802583295457' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/114232802583295457'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20485368/posts/default/114232802583295457'/><link rel='alternate' type='text/html' href='http://pequenoperro.blogspot.com/2006/03/new-blog-moved-to-new-blog-today-at.html' title='New Blog'/><author><name>bad.robot</name><uri>http://www.blogger.com/profile/04194536551624560525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://1.bp.blogspot.com/_-uMxV_fCbC4/SczyS5z_i6I/AAAAAAAADck/O8HLrvMRmBM/S220/A-Monkey-King.jpg'/></author><thr:total>0</thr:total></entry></feed>
