<?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-4477671938416917536</id><updated>2012-02-16T08:18:08.206-05:00</updated><category term='parseInt'/><category term='scala'/><category term='timer'/><category term='java'/><category term='cache'/><category term='tips'/><category term='google collections'/><category term='wait leak'/><category term='functional programming'/><category term='jboss'/><category term='wait'/><category term='sorting'/><category term='jboss cache'/><category term='tail recursion'/><category term='executor'/><category term='collections'/><category term='comparable'/><category term='integer'/><category term='concurrency'/><category term='mvcc'/><category term='comparator'/><title type='text'>Code Violation</title><subtitle type='html'>Musings on Java Software Development</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://code-violation.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4477671938416917536/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://code-violation.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Dan Hodge</name><uri>http://www.blogger.com/profile/06658831341947837396</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>6</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4477671938416917536.post-46429673813808639</id><published>2008-11-20T22:16:00.000-05:00</published><updated>2008-11-20T22:16:34.881-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='executor'/><category scheme='http://www.blogger.com/atom/ns#' term='timer'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrency'/><title type='text'>Time's Up</title><content type='html'>I'm certainly not the &lt;a href="http://tech.puredanger.com/2008/09/22/timer-rules/"&gt;first&lt;/a&gt; person to say this, but it bears repeating, using &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/Timer.html"&gt;&lt;code&gt;Timer&lt;/code&gt;&lt;/a&gt; in the post Java 5 world is not a good idea. I got bitten by &lt;code&gt;Timer's&lt;/code&gt; lack of exception handling again recently. If you must use a &lt;code&gt;Timer&lt;/code&gt; and are relying on it to be long-lived, make sure the &lt;code&gt;run()&lt;/code&gt; methods on your tasks can't throw any unchecked exceptions, because if any exceptions manage to leak out of the &lt;code&gt;run()&lt;/code&gt; method, the timer thread will terminate and no more tasks will run. I used to use &lt;code&gt;Timer&lt;/code&gt; in situations where I wanted to be able to cancel tasks, since &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/TimerTask.html"&gt;&lt;code&gt;TimerTask&lt;/code&gt;&lt;/a&gt; exposes a &lt;code&gt;cancel()&lt;/code&gt; method. What I failed to realize was that you can do the exact same thing using &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/concurrent/ScheduledExecutorService.html"&gt;&lt;code&gt;ScheduledExecutorService&lt;/code&gt;&lt;/a&gt; using the &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/concurrent/ScheduledFuture.html"&gt;&lt;code&gt;ScheduledFuture&lt;/code&gt;&lt;/a&gt; object that is returned when one of the schedule methods is invoked. It's a bit more cumbersome to cancel tasks this way since you may have to keep references to both the task object and the future object, but it wouldn't be too difficult to create a custom class to manage this.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4477671938416917536-46429673813808639?l=code-violation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-violation.blogspot.com/feeds/46429673813808639/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4477671938416917536&amp;postID=46429673813808639' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4477671938416917536/posts/default/46429673813808639'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4477671938416917536/posts/default/46429673813808639'/><link rel='alternate' type='text/html' href='http://code-violation.blogspot.com/2008/11/times-up.html' title='Time&apos;s Up'/><author><name>Dan Hodge</name><uri>http://www.blogger.com/profile/06658831341947837396</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4477671938416917536.post-4022216947601189945</id><published>2008-11-10T23:11:00.000-05:00</published><updated>2008-11-10T23:11:43.090-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss cache'/><category scheme='http://www.blogger.com/atom/ns#' term='cache'/><category scheme='http://www.blogger.com/atom/ns#' term='mvcc'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>Who's the Boss?</title><content type='html'>&lt;a href="http://www.jboss.org/jbosscache/"&gt;JBoss Cache&lt;/a&gt; 3.0.0 is &lt;a href="http://jbosscache.blogspot.com/2008/11/yet-another-cr.html"&gt;almost&lt;/a&gt; ready, and its big &lt;a href="http://java.dzone.com/articles/a-look-inside-jboss-cache"&gt;feature&lt;/a&gt;, multi-version concurrency control (&lt;a href="http://www.jboss.org/community/docs/DOC-10272"&gt;MVCC&lt;/a&gt;), is a big improvement. I assume that anyone who has tried to do anything interesting with JBoss Cache has run into &lt;a href="https://jira.jboss.org/jira/browse/JBCACHE-97"&gt;this&lt;/a&gt; limitation: any time you try and upgrade a read lock to a write lock while another thread is holding a read lock on the same node, you get an UpgradeException. Preventing this situation from arising in an application is very complicated. You can use Java synchronization to prevent concurrent access to the same data, but then you're throwing away JBoss Cache's fine-grained locking system. The solution that I settled on was a fine-grained (but not hierarchical) &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/concurrent/locks/Lock.html"&gt;&lt;code&gt;java.util.concurrent.locks.Lock&lt;/code&gt;&lt;/a&gt;-based layer that prevented concurrent access to the same cache nodes. JBoss Cache 3.0.0 makes all of this code unnecessary. In a pinch me, I'm dreaming moment, I wrote &lt;a href="http://sites.google.com/site/datajanitordev/Home/UpgradeTest.java?attredirects=0"&gt;this&lt;/a&gt; test (adapted from the &lt;a href="http://kickjava.com/src/org/jboss/test/cache/test/local/TxDeadlockUnitTestCase.java.htm"&gt;&lt;code&gt;TxDeadlockUnitTestCase)&lt;/code&gt;&lt;/a&gt; that causes the JBCACHE-97 bug and ran it against a 3.0.0 CR3 and 2.1.1 GA just to make sure the problem is really gone.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4477671938416917536-4022216947601189945?l=code-violation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-violation.blogspot.com/feeds/4022216947601189945/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4477671938416917536&amp;postID=4022216947601189945' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4477671938416917536/posts/default/4022216947601189945'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4477671938416917536/posts/default/4022216947601189945'/><link rel='alternate' type='text/html' href='http://code-violation.blogspot.com/2008/11/whos-boss.html' title='Who&apos;s the Boss?'/><author><name>Dan Hodge</name><uri>http://www.blogger.com/profile/06658831341947837396</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4477671938416917536.post-5658726305144571243</id><published>2008-09-27T13:46:00.000-04:00</published><updated>2008-09-27T13:46:01.134-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='wait leak'/><category scheme='http://www.blogger.com/atom/ns#' term='wait'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrency'/><title type='text'>Can't Hardly Wait</title><content type='html'>I ran into a wait leak issue recently and it made me wonder if there was anything I could to do prevent this issue from happening again. I found this &lt;a href="http://www.ibm.com/developerworks/java/library/j-perf01215/index.html"&gt;article&lt;/a&gt; from a few years back written by Java performance gurus &lt;a href="http://www.javaperformancetuning.com/"&gt;Jack Shirazi&lt;/a&gt; and &lt;a href="http://kirk.blog-city.com/"&gt;Kirk Pepperdine&lt;/a&gt;. The article mainly discusses tactics for detecting wait leaks. When it comes to preventing them from happening in the first place, there's no silver bullet. Something that I thought of that wasn't mention in the article is preferring the timed &lt;a href="http://java.sun.com/javase/6/docs/api/java/lang/Object.html#wait(long)"&gt;wait()&lt;/a&gt; method instead of the no-arg version in order to prevent wait leaks. Obviously, it's not always possible to specify a wait timeout, but in situations where it is possible, it can help an application recover gracefully from a wait leak.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4477671938416917536-5658726305144571243?l=code-violation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-violation.blogspot.com/feeds/5658726305144571243/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4477671938416917536&amp;postID=5658726305144571243' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4477671938416917536/posts/default/5658726305144571243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4477671938416917536/posts/default/5658726305144571243'/><link rel='alternate' type='text/html' href='http://code-violation.blogspot.com/2008/09/cant-hardly-wait.html' title='Can&apos;t Hardly Wait'/><author><name>Dan Hodge</name><uri>http://www.blogger.com/profile/06658831341947837396</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4477671938416917536.post-112597717847857255</id><published>2008-09-23T22:51:00.001-04:00</published><updated>2008-09-23T22:51:24.875-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='functional programming'/><category scheme='http://www.blogger.com/atom/ns#' term='tail recursion'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Heads and Tails</title><content type='html'>For whatever reason, tail recursion is a concept I could never quite wrap my head around. It was either something that I learned and then forgot, or heard about and never completely understood. I was reading this &lt;a href="http://www.kungfuice.com/index.php/2008/09/18/tail-recursive-algorithms-in-scala/"&gt;posting&lt;/a&gt; about tail recursion, &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt;, and the JVM and something in my brain just clicked and it makes total sense to me now. It should come in handy when I finally get around to learning Scala.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4477671938416917536-112597717847857255?l=code-violation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-violation.blogspot.com/feeds/112597717847857255/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4477671938416917536&amp;postID=112597717847857255' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4477671938416917536/posts/default/112597717847857255'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4477671938416917536/posts/default/112597717847857255'/><link rel='alternate' type='text/html' href='http://code-violation.blogspot.com/2008/09/heads-and-tails.html' title='Heads and Tails'/><author><name>Dan Hodge</name><uri>http://www.blogger.com/profile/06658831341947837396</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4477671938416917536.post-5707127937846178135</id><published>2008-09-18T22:04:00.000-04:00</published><updated>2008-09-18T22:04:31.185-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='comparator'/><category scheme='http://www.blogger.com/atom/ns#' term='comparable'/><category scheme='http://www.blogger.com/atom/ns#' term='collections'/><category scheme='http://www.blogger.com/atom/ns#' term='sorting'/><category scheme='http://www.blogger.com/atom/ns#' term='google collections'/><title type='text'>Compared To What?</title><content type='html'>I recently ran into an issue with the venerable &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/Collections.html#sort(java.util.List)"&gt;Collections#sort(List)&lt;/a&gt; method. The List that I was sorting had an unexpected null element, which resulted in a NullPointerException during the sort. My first inclination was to change the compareTo() method to handle nulls. This didn't work, however, because of line 1157 of the &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/Arrays.html"&gt;Arrays&lt;/a&gt;#mergeSort(Object[], Object[], int, int, int) method.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;1153           // Insertion sort on smallest arrays&lt;br /&gt;1154           if (length &lt; INSERTIONSORT_THRESHOLD) {&lt;br /&gt;1155               for (int i=low; i&lt;high; i++)&lt;br /&gt;1156                   for (int j=i; j&gt;low &amp;&amp;&lt;br /&gt;1157                            ((Comparable) dest[j-1]).compareTo(dest[j])&gt;0; j--)&lt;br /&gt;1158                       swap(dest, j, j-1);&lt;br /&gt;1159               return;&lt;br /&gt;1160           }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The method doesn't do any null checking, so if the object on the left side of the comparison is null, a NullPointerException will ensue. Punting on this concern was probably a good idea, since the whole idea of allowing null objects in a List is controversial, nevermind figuring out where to put them in the sort order. It would have been nice if there was more information about this in the API documentation. &lt;a href="http://www.amazon.com/Effective-Java-Programming-Language-Guide/dp/0201310058/ref=pd_bbs_sr_3?ie=UTF8&amp;s=books&amp;qid=1221789266&amp;sr=8-3"&gt;Effective Java&lt;/a&gt; mentions that the compareTo() method of a &lt;a href="http://java.sun.com/javase/6/docs/api/java/lang/Comparable.html"&gt;Comparable&lt;/a&gt; type should throw a NullPointerException if it receives a null object in Item 11, but the API docs for Arrays and Comparable don't say anything about how nulls are handled.&lt;br /&gt;&lt;br /&gt;I looked further into the Arrays class and noticed that the &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/Comparator.html"&gt;Comparator&lt;/a&gt; and Comparator-less sort methods are essentially line-by-line copies of each other, except the Comparator version uses the Comparator object to perform the comparison. I would have expected them to use the same underlying code, perhaps by creating an anonymous Comparator instance that delegates to the compareTo() method, but I digress...&lt;br /&gt;&lt;br /&gt;I finally solved the problem by creating a Comparator that can properly handle null objects. If you ever face this problem and you're using the &lt;a href="http://code.google.com/p/google-collections/"&gt;Google Collections&lt;/a&gt; library, you can use the &lt;a href="http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Comparators.html#nullLeastOrder()"&gt;Comparators#nullLeastOrder()&lt;/a&gt; or &lt;a href="http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Comparators.html#nullGreatestOrder()"&gt;Comparators#nullGreatestOrder()&lt;/a&gt; methods to obtain a Comparator that can handle null objects gracefully.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4477671938416917536-5707127937846178135?l=code-violation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-violation.blogspot.com/feeds/5707127937846178135/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4477671938416917536&amp;postID=5707127937846178135' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4477671938416917536/posts/default/5707127937846178135'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4477671938416917536/posts/default/5707127937846178135'/><link rel='alternate' type='text/html' href='http://code-violation.blogspot.com/2008/09/compared-to-what.html' title='Compared To What?'/><author><name>Dan Hodge</name><uri>http://www.blogger.com/profile/06658831341947837396</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4477671938416917536.post-553666021013008498</id><published>2008-09-04T22:50:00.000-04:00</published><updated>2008-09-04T22:52:26.650-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='tips'/><category scheme='http://www.blogger.com/atom/ns#' term='integer'/><category scheme='http://www.blogger.com/atom/ns#' term='parseInt'/><title type='text'>The Joy of Hex</title><content type='html'>The Java platform is so large that even experienced developers discover new classes and methods nearly every day. My discovery &lt;i&gt;du jour&lt;/i&gt; is the 2-arg form of &lt;a href="http://java.sun.com/javase/6/docs/api/java/lang/Integer.html"&gt;java.lang.Integer&lt;/a&gt;'s &lt;a href="http://java.sun.com/javase/6/docs/api/java/lang/Integer.html#parseInt%28java.lang.String,%20int%29"&gt;parseInt()&lt;/a&gt; method. It's a pretty slick way to parse a hex dump, among other things.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4477671938416917536-553666021013008498?l=code-violation.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://code-violation.blogspot.com/feeds/553666021013008498/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4477671938416917536&amp;postID=553666021013008498' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4477671938416917536/posts/default/553666021013008498'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4477671938416917536/posts/default/553666021013008498'/><link rel='alternate' type='text/html' href='http://code-violation.blogspot.com/2008/09/joy-of-hex.html' title='The Joy of Hex'/><author><name>Dan Hodge</name><uri>http://www.blogger.com/profile/06658831341947837396</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
