<?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-8405165711854469088</id><updated>2011-11-27T15:31:20.886-08:00</updated><title type='text'>Lasse Westh's Idle Thoughts</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://lassewesth.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://lassewesth.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>LasseWesth</name><uri>http://www.blogger.com/profile/14183130837834650426</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>20</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8405165711854469088.post-3839497651926282825</id><published>2011-08-11T05:54:00.001-07:00</published><updated>2011-08-11T05:55:31.657-07:00</updated><title type='text'>Awesome Gmail</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-f7_8oTUIclg/TkPRHit4MSI/AAAAAAAAAdw/S8_hn76bolc/s1600/gmailwarning.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 362px; height: 169px;" src="http://4.bp.blogspot.com/-f7_8oTUIclg/TkPRHit4MSI/AAAAAAAAAdw/S8_hn76bolc/s400/gmailwarning.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5639581085906514210" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8405165711854469088-3839497651926282825?l=lassewesth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lassewesth.blogspot.com/feeds/3839497651926282825/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8405165711854469088&amp;postID=3839497651926282825' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/3839497651926282825'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/3839497651926282825'/><link rel='alternate' type='text/html' href='http://lassewesth.blogspot.com/2011/08/awesome-gmail.html' title='Awesome Gmail'/><author><name>LasseWesth</name><uri>http://www.blogger.com/profile/14183130837834650426</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><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-f7_8oTUIclg/TkPRHit4MSI/AAAAAAAAAdw/S8_hn76bolc/s72-c/gmailwarning.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8405165711854469088.post-2248810014578384907</id><published>2011-01-20T04:00:00.000-08:00</published><updated>2011-01-20T04:07:58.574-08:00</updated><title type='text'>HTTP tidbits</title><content type='html'>Reading up on RFC 2616, section 6, some interesting details that I want to keep:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-style:italic;"&gt;reason phrases [...] MAY be replaced by local equivalents without affecting the protocol&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;Could come in handy for debugging?&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-style:italic;"&gt;HTTP applications are not required to understand the meaning of all registered status codes, [...]. However, applications MUST understand the class of any status code, as indicated by the first digit, and treat any unrecognized response as being equivalent to the x00 status code of that class&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;Interesting edge case. And HTTP status codes are arithmetic types, not enums.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8405165711854469088-2248810014578384907?l=lassewesth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lassewesth.blogspot.com/feeds/2248810014578384907/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8405165711854469088&amp;postID=2248810014578384907' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/2248810014578384907'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/2248810014578384907'/><link rel='alternate' type='text/html' href='http://lassewesth.blogspot.com/2011/01/http-tid-bits.html' title='HTTP tidbits'/><author><name>LasseWesth</name><uri>http://www.blogger.com/profile/14183130837834650426</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-8405165711854469088.post-1706733041655471677</id><published>2010-12-08T03:09:00.000-08:00</published><updated>2010-12-08T03:22:52.673-08:00</updated><title type='text'>Ninite</title><content type='html'>Note to self: http://ninite.com/ works really well.&lt;br /&gt;&lt;br /&gt;Thanks Carlos!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8405165711854469088-1706733041655471677?l=lassewesth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lassewesth.blogspot.com/feeds/1706733041655471677/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8405165711854469088&amp;postID=1706733041655471677' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/1706733041655471677'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/1706733041655471677'/><link rel='alternate' type='text/html' href='http://lassewesth.blogspot.com/2010/12/ninite.html' title='Ninite'/><author><name>LasseWesth</name><uri>http://www.blogger.com/profile/14183130837834650426</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-8405165711854469088.post-2398738839668255994</id><published>2009-10-06T15:09:00.000-07:00</published><updated>2009-10-06T15:32:07.306-07:00</updated><title type='text'>Brief is not simple</title><content type='html'>I am always keen to reduce the world into simple metaphors and proverbs. Big fan of &lt;a href="http://en.wikipedia.org/wiki/The_Emperor's_New_Clothes"&gt;"the emperor has no clothes"&lt;/a&gt; for example (and not only because &lt;a href="http://en.wikipedia.org/wiki/Hans_Christian_Andersen"&gt;H. C. Andersen&lt;/a&gt; was danish!), as it can be applied to so many things. Particularly, while we battle for the hearts and minds of the IT industry, advocating simplicity and denouncing ceremony, it seems to come in handy time and again.&lt;br /&gt;&lt;br /&gt;Anyway, I was reading about &lt;a href="http://code.google.com/p/guava-libraries/"&gt;Guava&lt;/a&gt; (thanks for the link Simon!), and stumbled upon one that was missing from my library: &lt;a href="http://en.wikipedia.org/wiki/Polonius#Famous_lines"&gt;"brevity is the soul of wit"&lt;/a&gt;. In the context of source code, you can imagine a snooty Perl hacker uttering this phrase after writing a particularly pleasing regular expression that no-one will ever be able to decode. However, I cannot think of anything less appealing in source code that brevity or wit. As a way of communicating, code is really best expressed simply, not briefly or cleverly.&lt;br /&gt;&lt;br /&gt;Of course, outside the world of code I am a huge fan of folks who can be concise, thus.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8405165711854469088-2398738839668255994?l=lassewesth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lassewesth.blogspot.com/feeds/2398738839668255994/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8405165711854469088&amp;postID=2398738839668255994' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/2398738839668255994'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/2398738839668255994'/><link rel='alternate' type='text/html' href='http://lassewesth.blogspot.com/2009/10/brief-is-not-simple.html' title='Brief is not simple'/><author><name>LasseWesth</name><uri>http://www.blogger.com/profile/14183130837834650426</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-8405165711854469088.post-8010221058662634973</id><published>2009-07-14T03:44:00.000-07:00</published><updated>2009-07-14T04:07:04.651-07:00</updated><title type='text'>Watch your dependencies</title><content type='html'>Dependencies are a headache. They &lt;a href="http://parlezuml.com/blog/?postid=466"&gt;cause all sorts of problems&lt;/a&gt;. So you should keep aware of them.&lt;br /&gt;&lt;br /&gt;Tools are a-plenty, for many languages, but here is a good starter for your favourite open platform: &lt;a href="http://byecycle.sourceforge.net/"&gt;Byecycle&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.ndepend.com/"&gt;Other&lt;/a&gt; &lt;a href="http://andrei.gmxhome.de/jdepend4eclipse/"&gt;tools&lt;/a&gt; do more, but are also more complicated and &lt;a href="http://www.clarkware.com/software/images/figure1b.jpg"&gt;hard to interpret&lt;/a&gt;. If you want a gentle introduction, start with this little visual tool.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;It can help you find dependency cycles&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_844tMBy37IE/SlxjuGcTF-I/AAAAAAAAAI4/xtC1AD_kCUw/s1600-h/yinyang.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 231px;" src="http://2.bp.blogspot.com/_844tMBy37IE/SlxjuGcTF-I/AAAAAAAAAI4/xtC1AD_kCUw/s400/yinyang.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5358267300318484450" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;It can help you spot classes that do too much&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_844tMBy37IE/Slxj9ibYrVI/AAAAAAAAAJA/aUr7vX8dCTg/s1600-h/swissarmyknife.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 293px;" src="http://1.bp.blogspot.com/_844tMBy37IE/Slxj9ibYrVI/AAAAAAAAAJA/aUr7vX8dCTg/s400/swissarmyknife.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5358267565528886610" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It simply gives you a 30.000ft view of how your code looks, something which is difficult to get from text files on even a medium sized code base.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8405165711854469088-8010221058662634973?l=lassewesth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lassewesth.blogspot.com/feeds/8010221058662634973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8405165711854469088&amp;postID=8010221058662634973' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/8010221058662634973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/8010221058662634973'/><link rel='alternate' type='text/html' href='http://lassewesth.blogspot.com/2009/07/watch-your-dependencies.html' title='Watch your dependencies'/><author><name>LasseWesth</name><uri>http://www.blogger.com/profile/14183130837834650426</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><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_844tMBy37IE/SlxjuGcTF-I/AAAAAAAAAI4/xtC1AD_kCUw/s72-c/yinyang.JPG' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8405165711854469088.post-7503206271106201799</id><published>2009-05-11T01:49:00.000-07:00</published><updated>2009-05-11T02:34:04.968-07:00</updated><title type='text'>I like Apache HTTP Client over java.net.HttpURLConnection</title><content type='html'>My last project involved &lt;a href="http://www.jasig.org/cas"&gt;CAS&lt;/a&gt; and a lot of integration points, so we ended up with lots of HTTP traffic as part of our integration tests.&lt;br /&gt;&lt;br /&gt;We started having problems with our build, spurious exceptions would break it, but we couldn't reproduce the problem. It was not until we did some rudimentary load testing that the problem surfaced: &lt;a href="http://java.sun.com/j2se/1.5.0/docs/guide/net/http-keepalive.html"&gt;Persistent HTTP connections&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Problem was, we had written our tests using &lt;a href="http://java.sun.com/javase/6/docs/api/java/net/HttpURLConnection.html"&gt;java.net.HttpURLConnection&lt;/a&gt; like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;try {&lt;br /&gt;  HttpURLConnection connection = (HttpURLConnection) new URL("http://localhost:8080").openConnection();&lt;br /&gt;  connection.connect();&lt;br /&gt;  assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode());&lt;br /&gt;} catch (...){&lt;br /&gt;  ...&lt;br /&gt;}&lt;br /&gt;finally {&lt;br /&gt;  connection.disconnect();&lt;br /&gt;  connection.close();&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Turns out, because we didn't care about the response body and thus never bothered reading it, and that would tie up TCP connections. The more tests we ran, the more likely it became that we would see an exception like this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;Exception in thread "main" java.net.BindException: Address already in use: connect&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;So while we thought we were being diligent by writing a finally block to disconnect and close the connection, it turns out that is completely superfluous. What we would have to write was this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;try {&lt;br /&gt;  HttpURLConnection connection = (HttpURLConnection) new URL("http://localhost:8080").openConnection();&lt;br /&gt;  connection.connect();&lt;br /&gt;  assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode());&lt;br /&gt;} catch (...){&lt;br /&gt;  ...&lt;br /&gt;}&lt;br /&gt;finally {&lt;br /&gt;  while (connection.getInputStream().read() != -1) ;&lt;br /&gt;&lt;br /&gt;  connection.disconnect();&lt;br /&gt;  connection.close();&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;(Actually, that just works for happy HTTP responses, as this library will throw an exception on 4xx and 5xx's!? But lets not digress...)&lt;br /&gt;&lt;br /&gt;Now that's a lot of code for something so simple - look at &lt;a href="http://hc.apache.org/httpclient-3.x/"&gt;Apache HTTP Client&lt;/a&gt; for the same task:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;HttpClient httpClient = new HttpClient();&lt;br /&gt;GetMethod method = new GetMethod("http://localhost:8080");&lt;br /&gt;assertEquals(HttpStatus.SC_OK, httpClient.executeMethod(method));&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Notice, no cleanup code! And even better, comparing peak use of TCP connections as a function of number of connections opened (measured with &lt;code&gt;netstat -a&lt;/code&gt; on my Windows box):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_844tMBy37IE/Sgfs_7pnKHI/AAAAAAAAAIM/vUW5N57PNmk/s1600-h/tcp_keepalive1.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 219px;" src="http://4.bp.blogspot.com/_844tMBy37IE/Sgfs_7pnKHI/AAAAAAAAAIM/vUW5N57PNmk/s400/tcp_keepalive1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5334492866731780210" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And look at the number of exceptions we get on a sample run - HTTP Client cleans up the input buffer automatically up and gives zero exceptions:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_844tMBy37IE/SgfuEvekFaI/AAAAAAAAAIU/PTWWpXTfPVM/s1600-h/tcp_keepalive2.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 217px;" src="http://4.bp.blogspot.com/_844tMBy37IE/SgfuEvekFaI/AAAAAAAAAIU/PTWWpXTfPVM/s400/tcp_keepalive2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5334494048875189666" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;So while the API library can be made to work, I don't think I will be using it in future. On top being verbose, the way it handles "unhappy" response codes and the fact that &lt;a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6369510"&gt;it will insert a Content-Type behind your back&lt;/a&gt; makes it a poor choice.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8405165711854469088-7503206271106201799?l=lassewesth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lassewesth.blogspot.com/feeds/7503206271106201799/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8405165711854469088&amp;postID=7503206271106201799' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/7503206271106201799'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/7503206271106201799'/><link rel='alternate' type='text/html' href='http://lassewesth.blogspot.com/2009/05/i-like-apache-http-client-over.html' title='I like Apache HTTP Client over java.net.HttpURLConnection'/><author><name>LasseWesth</name><uri>http://www.blogger.com/profile/14183130837834650426</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><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_844tMBy37IE/Sgfs_7pnKHI/AAAAAAAAAIM/vUW5N57PNmk/s72-c/tcp_keepalive1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8405165711854469088.post-5654749791102654477</id><published>2009-05-05T04:12:00.000-07:00</published><updated>2009-05-06T17:06:49.945-07:00</updated><title type='text'>Waldo: Excellent!</title><content type='html'>Being currently beached and briefly free of family life, I had some time to catch up on my reading. This one really filled a gap in my knowledge of distributed computing and its history.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I was in a conversation once that only now makes proper sense. The phrase "Waldo taught is that" was used in a discussion about REST, which puzzled me - I hadn't heard of Waldo except for the &lt;a href="http://www.facebook.com/pages/Wheres-Wally/29848278059"&gt;fellow in the striped sweater&lt;/a&gt;. Later I was reading some &lt;a href="http://qconlondon.com/london-2009/file?path=/qcon-london-2009/slides/SteveVinoski_RPCAndItsOffspringConvenientYetFundamentallyFlawed.pdf"&gt;notes from QCon&lt;/a&gt; via &lt;a href="http://steve.vinoski.net/blog/"&gt;Steve Vinoski's blog&lt;/a&gt;, and again the mysterious Wally was mentioned. And finally a quick googling turns up a reference from Uncle Bob and his friends on &lt;a href="http://blog.objectmentor.com/articles/2009/02/26/10-papers-every-programmer-should-read-at-least-twice"&gt;their list of reading recommendations&lt;/a&gt;. Now I can't ignore Wally any longer.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Waldo et al. described the impedance mismatch of language abstractions and distributed computing in &lt;a href="http://research.sun.com/techrep/1994/abstract-29.html"&gt;this 1994 thesis&lt;/a&gt;. And I am regretting it took 15 years before I read it, as it makes some very straight forward arguments - things I wish I had been more aware of in past. In fact, thinking back, in 2002 I took a course which featured CORBA, and I was very impressed with it at the time.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Qouting from the abstract: "&lt;span class="Apple-style-span" style="font-style: italic;"&gt;We argue that objects that interact in a distributed system need to be dealt with in ways that are intrinsically different from objects that interact in a single address space. These differences are required because distributed systems require that the programmer be aware of latency, have a different model of memory access, and take into account issues of concurrency and partial failure&lt;/span&gt;".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So if you are doing any web/ SOA/ remoting at all, you really should go find Wally and get some extra context.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8405165711854469088-5654749791102654477?l=lassewesth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lassewesth.blogspot.com/feeds/5654749791102654477/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8405165711854469088&amp;postID=5654749791102654477' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/5654749791102654477'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/5654749791102654477'/><link rel='alternate' type='text/html' href='http://lassewesth.blogspot.com/2009/05/waldo-excellent.html' title='Waldo: Excellent!'/><author><name>LasseWesth</name><uri>http://www.blogger.com/profile/14183130837834650426</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>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8405165711854469088.post-5113112632320584223</id><published>2009-02-19T03:05:00.000-08:00</published><updated>2009-02-19T03:10:59.890-08:00</updated><title type='text'>Manual Deployment Antipattern</title><content type='html'>It always felt wrong and now I found that it is actually a named antipattern! Yay! Now I can take that and use it to knock people on the head. Intellectual bullying - I'm lovin' it!&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Alright, the article is about deployment automation, and &lt;a href="http://www.ibm.com/developerworks/java/library/j-ap01139/index.html?S_TACT=105AGX02&amp;amp;S_CMP=EDU#N101D1"&gt;this one in particular&lt;/a&gt; brings back memories. Hours and hours spent, manually deploying and redeploying a system, trying to ensure all dependencies were met.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Oh and of course, the reason I am loving this is the &lt;a href="http://www.antipatterns.com/"&gt;Antipatterns book&lt;/a&gt;, which I thought was brilliant. The whole concept of common pitfalls is just great - read it and you already know things you should be avoiding, you don't have to learn the hard way.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8405165711854469088-5113112632320584223?l=lassewesth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lassewesth.blogspot.com/feeds/5113112632320584223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8405165711854469088&amp;postID=5113112632320584223' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/5113112632320584223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/5113112632320584223'/><link rel='alternate' type='text/html' href='http://lassewesth.blogspot.com/2009/02/manual-deployment-antipattern.html' title='Manual Deployment Antipattern'/><author><name>LasseWesth</name><uri>http://www.blogger.com/profile/14183130837834650426</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-8405165711854469088.post-2072841997230796762</id><published>2009-02-16T14:58:00.000-08:00</published><updated>2009-02-16T14:59:59.770-08:00</updated><title type='text'>Digital signatures in Java</title><content type='html'>We needed this for work, so while learning I wrote this very small program.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;pre&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;package digisign;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;import java.security.InvalidKeyException;&lt;/div&gt;&lt;div&gt;import java.security.KeyFactory;&lt;/div&gt;&lt;div&gt;import java.security.KeyPair;&lt;/div&gt;&lt;div&gt;import java.security.KeyPairGenerator;&lt;/div&gt;&lt;div&gt;import java.security.NoSuchAlgorithmException;&lt;/div&gt;&lt;div&gt;import java.security.PrivateKey;&lt;/div&gt;&lt;div&gt;import java.security.PublicKey;&lt;/div&gt;&lt;div&gt;import java.security.Signature;&lt;/div&gt;&lt;div&gt;import java.security.SignatureException;&lt;/div&gt;&lt;div&gt;import java.security.spec.InvalidKeySpecException;&lt;/div&gt;&lt;div&gt;import java.security.spec.X509EncodedKeySpec;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;/*&lt;/div&gt;&lt;div&gt; * http://java.sun.com/docs/books/tutorial/security/apisign/index.html&lt;/div&gt;&lt;div&gt; */&lt;/div&gt;&lt;div&gt;public class Main {&lt;/div&gt;&lt;div&gt;    public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, InvalidKeySpecException {&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;// create some keys&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;keyPairGenerator.initialize(1024);&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;KeyPair keyPair = keyPairGenerator.generateKeyPair();&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;PrivateKey privateKey = keyPair.getPrivate();&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;PublicKey publicKey = keyPair.getPublic();&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;// sign some data&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;byte[] data = "Hello, world!\n".getBytes();&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Signature signature = Signature.getInstance("SHA1withRSA");&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;signature.initSign(privateKey);&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;signature.update(data);&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;byte[] sign = signature.sign();&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;// serialize public key and hand it over&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;byte[] pubKey = publicKey.getEncoded();&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;// store to disk, read in etc...&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;X509EncodedKeySpec encodedKeySpec = new X509EncodedKeySpec(pubKey);&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;KeyFactory keyFactory = KeyFactory.getInstance("RSA");&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;publicKey = keyFactory.generatePublic(encodedKeySpec);&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;// verify signature&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;signature = Signature.getInstance("SHA1withRSA");&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;signature.initVerify(publicKey);&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;signature.update(data);&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;boolean b = signature.verify(sign);&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;System.out.println("signature " + (b ? "ok." : "invalid!"));&lt;/div&gt;&lt;div&gt;    }&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8405165711854469088-2072841997230796762?l=lassewesth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lassewesth.blogspot.com/feeds/2072841997230796762/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8405165711854469088&amp;postID=2072841997230796762' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/2072841997230796762'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/2072841997230796762'/><link rel='alternate' type='text/html' href='http://lassewesth.blogspot.com/2009/02/digital-signatures-in-java.html' title='Digital signatures in Java'/><author><name>LasseWesth</name><uri>http://www.blogger.com/profile/14183130837834650426</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-8405165711854469088.post-6994725967686922749</id><published>2009-01-05T13:54:00.000-08:00</published><updated>2009-01-05T15:06:23.208-08:00</updated><title type='text'>Software Sloth</title><content type='html'>I know I should be babysitting, but I saw &lt;a href="http://iancartwright.com/blog/2009/01/five-kinds-of-technical-debt.html"&gt;Ian's nuanced post&lt;/a&gt; about &lt;a href="http://www.martinfowler.com/bliki/TechnicalDebt.html"&gt;technical debt&lt;/a&gt; and thought he left one out, and it is a &lt;a href="http://en.wikipedia.org/wiki/Sloth_(deadly_sin)"&gt;cardinal one&lt;/a&gt;.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The fundamental problem is you either do not care enough and/ or you are too proud to change your was. The blogosphere is full of good advice, there are loads of great textbooks available, and peer learning is catching on - so help is available. So why do some still not "get it" and start producing good software?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Technical debt can be excused if it is backed up my conscious, well thought through decisions. There can be justification for skimping on quality. However, I contend that most technical debt is accrued through sloth. You either do not know what quality is, because you do not care enough to go and find out. You do not know the price of short sightedness. You cannot be bothered to read good books, or participate in collaborative peer efforts to better yourself. Or you are sinister, arrogant and not interested in improving your ways, not receptive to better ideas - even when you see mounting technical debt all around you.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I am a firm believer in evolution, and if we frame the problem thus, it is clear what the real problem is: because there isn't enough talent to go around, to fill enough posts and attain critical mass, sloth is allowed to thrive. Evolutionary pressures only work when resources are scarce, and sloth is apparently a smaller problem than getting bums on seats and poor code out the door.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Or maybe I am mistaken, and quantity is the real measure of success?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8405165711854469088-6994725967686922749?l=lassewesth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lassewesth.blogspot.com/feeds/6994725967686922749/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8405165711854469088&amp;postID=6994725967686922749' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/6994725967686922749'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/6994725967686922749'/><link rel='alternate' type='text/html' href='http://lassewesth.blogspot.com/2009/01/software-sloth.html' title='Software Sloth'/><author><name>LasseWesth</name><uri>http://www.blogger.com/profile/14183130837834650426</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-8405165711854469088.post-2684523670327944698</id><published>2008-11-04T02:53:00.000-08:00</published><updated>2008-11-04T03:51:31.545-08:00</updated><title type='text'>Hello, Nagios\n</title><content type='html'>Nagios is a generic monitoring tool, and I want to use it to monitor my own application. It has a lot of built-in and offical plugins. However, it is always good to try a Hello, World-type example.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Firstly, my very interesting application. It follows the Nagios Plugin guidelines: return a value in {0, 1, 2, 3} and a status message of less than 4k to standard out. And it gives you some random sysadmin-action:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(&lt;span class="Apple-style-span" style="font-style: italic;"&gt;np.c&lt;/span&gt;, compiles into an executable &lt;span class="Apple-style-span" style="font-style: italic;"&gt;np&lt;/span&gt;)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;#include &amp;lt;time.h&amp;gt;&lt;br /&gt;&lt;br /&gt;int main(int argc, char* argv[]) {&lt;br /&gt; srand(time(NULL));&lt;br /&gt;&lt;br /&gt; int r = rand() % 10;&lt;br /&gt;&lt;br /&gt; int status = -1;&lt;br /&gt; char* message = NULL;&lt;br /&gt;&lt;br /&gt; switch(r){&lt;br /&gt;  case 0:&lt;br /&gt;  case 1:&lt;br /&gt;  case 2:&lt;br /&gt;  case 3:&lt;br /&gt;   status = 0;&lt;br /&gt;   message = "Everything is alright :-)";&lt;br /&gt;   break;&lt;br /&gt;  case 4:&lt;br /&gt;  case 5:&lt;br /&gt;  case 6:&lt;br /&gt;   status = 1;&lt;br /&gt;   message = "You have been warned.";&lt;br /&gt;   break;&lt;br /&gt;  case 7:&lt;br /&gt;  case 8:&lt;br /&gt;   status = 2;&lt;br /&gt;   message = "She is gonna blow!";&lt;br /&gt;   break;&lt;br /&gt;  case 9:&lt;br /&gt;   status = 3;&lt;br /&gt;   message = "Oh shit...";&lt;br /&gt;   break;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; printf("%s\n", message);&lt;br /&gt;&lt;br /&gt; return status;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Nagios is easy to install with &lt;a href="http://nagios.sourceforge.net/docs/3_0/quickstart-ubuntu.html"&gt;this quickstart guide&lt;/a&gt;. You just need to configure it:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;1) In &lt;span class="Apple-style-span" style="font-style: italic;"&gt;$NAGIOS_HOME/etc/nagios.cfg&lt;/span&gt;, add a line &lt;span class="Apple-style-span" style="font-style: italic;"&gt;cfg_file=$NAGIOS_HOME/etc/objects/np.cfg&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;2) In &lt;span class="Apple-style-span" style="font-style: italic;"&gt;$NAGIOS_HOME/etc/nagios.cfg&lt;/span&gt;, set &lt;span class="Apple-style-span" style="font-style: italic;"&gt;interval_length&lt;/span&gt; to a suitably low number, e.g. 5 seconds, so you can see changes quickly&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;3) In &lt;span class="Apple-style-span" style="font-style: italic;"&gt;$NAGIOS_HOME/etc/objects/np.cfg&lt;/span&gt;, make it look something like this:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre&gt;define hostgroup {&lt;br /&gt;  hostgroup_name        app_hosts&lt;br /&gt;  alias                 Application Hosts&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;define host {&lt;br /&gt;  use                   generic-host&lt;br /&gt;  host_name             app_host&lt;br /&gt;  alias                 Application Host&lt;br /&gt;  address               localhost&lt;br /&gt;  hostgroups            app_hosts&lt;br /&gt;  max_check_attempts    10&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;define service {&lt;br /&gt;  use                   local-service&lt;br /&gt;  host_name             app_host&lt;br /&gt;  service_description   My Application&lt;br /&gt;  check_command         monitor_np&lt;br /&gt;  normal_check_interval 1&lt;br /&gt;  retry_check_interval  1&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;define command {&lt;br /&gt;  command_name          monitor_np&lt;br /&gt;  command_line          $APPLICATION_HOME/bin/np&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The configuration is quite fidgety. Lots of required attributes, no sensible defaults. Luckily you can reuse example configuration that comes with Nagios. And there is a handy pre-flight-check feature, you just run &lt;span class="Apple-style-span" style="font-style: italic;"&gt;/usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg&lt;/span&gt; and it will give you errors and warnings against your configuration files, with line numbers.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Anyway, by now Bob is your uncle and you can restart nagios to pick up changes. Then point your browser to &lt;span class="Apple-style-span" style="font-style: italic;"&gt;http://localhost/nagios&lt;/span&gt; and watch the action!&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/8405165711854469088-2684523670327944698?l=lassewesth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lassewesth.blogspot.com/feeds/2684523670327944698/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8405165711854469088&amp;postID=2684523670327944698' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/2684523670327944698'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/2684523670327944698'/><link rel='alternate' type='text/html' href='http://lassewesth.blogspot.com/2008/11/hello-nagiosn.html' title='Hello, Nagios\n'/><author><name>LasseWesth</name><uri>http://www.blogger.com/profile/14183130837834650426</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-8405165711854469088.post-1043282917055493468</id><published>2008-11-03T03:06:00.000-08:00</published><updated>2008-11-03T03:54:43.699-08:00</updated><title type='text'>Any Fool Can Sysadmin</title><content type='html'>I have Windows XP on my laptop, but I needed a Linux environment for client work. The last time I played around with dual booting was in 2000 when I had just bought my self-builder home computer. I installed Windows 2000 then RedHat 6, but the whole thing failed (I suspect my then very new motherboard didn't have drivers, or something) and I had to wipe everything (using my home sysadmin skills: if anything goes wrong, wipe and reinstall!).&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So, it is fair to say I am a non-sysadmin, and maybe that's why I am sometimes accused of being a girly drinker. But with VMware I am suddenly sucessful and confident - in fact I am so confident I might just &lt;a href="http://www.garyshood.com/root/"&gt;run as root&lt;/a&gt; - it is a vm after all, what could go wrong?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I found &lt;a href="http://www.lifehack.org/articles/technology/beginners-guide-run-linux-like-any-other-program-in-windows.html"&gt;this guide&lt;/a&gt; extremely helpful. &lt;a href="http://www.vmware.com/products/player/"&gt;VMware Player&lt;/a&gt; is free and easy, the guide helps to hook things up, &lt;a href="http://www.ubuntu.com/"&gt;Ubuntu&lt;/a&gt; is quite user friendly. Why was I so scared of sysadmining for so long?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Well, these are early days, and I might just revert to my old self if I get a problem with Linux - wipe and reinstall. But since it is a vm, that is actually a painless solution...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Actually I forget; I first tried installing Damn Small Linux using a VMware Appliance, since it was only a 50MB download. However, I didn't manage to get the network working. And my colleagues and I didn't have a clue how to fix it. So I ended up with Ubuntu. Morale of the story though, sysadmining is no fun if you can't easily wipe and reinstall.&lt;/div&gt;&lt;div&gt;&lt;br /&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/8405165711854469088-1043282917055493468?l=lassewesth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lassewesth.blogspot.com/feeds/1043282917055493468/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8405165711854469088&amp;postID=1043282917055493468' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/1043282917055493468'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/1043282917055493468'/><link rel='alternate' type='text/html' href='http://lassewesth.blogspot.com/2008/11/any-fool-can-sysadmin.html' title='Any Fool Can Sysadmin'/><author><name>LasseWesth</name><uri>http://www.blogger.com/profile/14183130837834650426</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-8405165711854469088.post-6498688389707018848</id><published>2008-10-03T05:32:00.000-07:00</published><updated>2008-10-03T07:17:57.197-07:00</updated><title type='text'>Software Apprentice</title><content type='html'>&lt;span class="Apple-style-span"   style="border-collapse: collapse;   white-space: pre-wrap; font-family:courier;font-size:12px;"&gt;&lt;a href="http://blog.livingroomarchitect.com/"&gt;Kerry&lt;/a&gt; is always talking about &lt;a href="http://bst.sagepub.com/cgi/content/abstract/24/3/188"&gt;Dreyfus and nursing competencies&lt;/a&gt;.&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="border-collapse: collapse;   white-space: pre-wrap;font-family:courier;font-size:12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="border-collapse: collapse;   white-space: pre-wrap; font-family:courier;font-size:12px;"&gt;That got me thinking: is there a book you can give to a software developer that he can follow and use to improve himself through the five levels?&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="border-collapse: collapse;   white-space: pre-wrap;font-family:courier;font-size:12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="border-collapse: collapse;   white-space: pre-wrap; font-family:courier;font-size:12px;"&gt;Well, I haven't read it yet but &lt;a href="http://www.thoughtworks.com/who-we-are/our-people/profiles/Keogh,+Elizabeth.html"&gt;Elizabeth Keogh&lt;/a&gt; recommended me &lt;span class="Apple-style-span"   style="border-collapse: separate;   white-space: normal; font-family:Georgia;font-size:16px;"&gt;&lt;span class="Apple-style-span"   style="border-collapse: collapse;   white-space: pre-wrap;font-family:courier;font-size:12px;"&gt;&lt;a href="http://softwarecraftsmanship.oreilly.com/wiki"&gt;Apprenticeship Patterns: Guidance For The Aspiring Software Craftsman&lt;/a&gt;&lt;/span&gt;&lt;span class="Apple-style-span"   style="border-collapse: collapse;   white-space: pre-wrap; font-family:courier;font-size:12px;"&gt;. I shall put it on my list right after finishing the DDD book and several volumes on how to raise babies.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; font-family: courier; font-size: 48px; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; font-family: courier; font-size: 48px; white-space: pre-wrap;"&gt;&lt;span class="Apple-style-span" style="border-collapse: separate; font-family: -webkit-monospace; font-size: 13px; "&gt;More on this topic: http://dannorth.net/2008/06/learning-to-lean - loved the Bruce Lee quote at the bottom.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="border-collapse: collapse;   white-space: pre-wrap;font-family:courier;font-size:12px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8405165711854469088-6498688389707018848?l=lassewesth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lassewesth.blogspot.com/feeds/6498688389707018848/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8405165711854469088&amp;postID=6498688389707018848' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/6498688389707018848'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/6498688389707018848'/><link rel='alternate' type='text/html' href='http://lassewesth.blogspot.com/2008/10/software-apprentice.html' title='Software Apprentice'/><author><name>LasseWesth</name><uri>http://www.blogger.com/profile/14183130837834650426</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-8405165711854469088.post-5441063401371855695</id><published>2008-10-01T03:22:00.000-07:00</published><updated>2008-11-04T04:39:30.656-08:00</updated><title type='text'>Annoying Eclipse Configuration</title><content type='html'>&lt;div style="text-align: justify;"&gt;I needed to get Eclipse to use a JDK instead of a JRE so I could play around with Maven.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Easy peasy? Well, no, not exactly...&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;"Just specify a -vm option in your eclipse.ini, and Bob is your uncle", they stated. Hah!&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li style="text-align: justify;"&gt;I put the option in with a blank line seperator. Doesn't work.&lt;br /&gt;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;I delete the blank line after reading &lt;a href="http://lofidewanto.blogspot.com/2007/05/eclipse.html"&gt;a blog entry&lt;/a&gt;. Doesn't work.&lt;br /&gt;&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Hmm, it keeps defaulting to my JRE, maybe I will uninstall that so I can "debug". Que slow Windows uninstallation...&lt;/li&gt;&lt;li style="text-align: justify;"&gt;Now I get error messages. Maybe it is the space in &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Program Files&lt;/span&gt;? I'll put a %20 in there. Doesn't work.&lt;/li&gt;&lt;li style="text-align: justify;"&gt;I discover option values go onto a new line (how obscure). Combinatorials ensue. Still doesn't work.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Turns out it won't work if you don't -vm option before the -vmargs option. Why??? Worse, it will just silently die/ ignore/ not warn you. Perhaps they should work on their &lt;a href="http://lassewesth.blogspot.com/2008/09/surprisingly-good-error-messages.html"&gt;error messages&lt;/a&gt;?&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;But i'm not ashamed to have wasted half an hour. Others have &lt;a href="http://dev.eclipse.org/newslists/news.eclipse.platform/msg53199.html"&gt;wasted time on this stuff&lt;/a&gt; too.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Isn't there a standard or convention for text-based config files, and couldn't someone get Eclipse to use it?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8405165711854469088-5441063401371855695?l=lassewesth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lassewesth.blogspot.com/feeds/5441063401371855695/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8405165711854469088&amp;postID=5441063401371855695' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/5441063401371855695'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/5441063401371855695'/><link rel='alternate' type='text/html' href='http://lassewesth.blogspot.com/2008/10/annoying-eclipse-configuration.html' title='Annoying Eclipse Configuration'/><author><name>LasseWesth</name><uri>http://www.blogger.com/profile/14183130837834650426</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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8405165711854469088.post-784039789538036603</id><published>2008-09-30T03:50:00.000-07:00</published><updated>2009-02-03T15:17:55.127-08:00</updated><title type='text'>Unit Testing With Threads</title><content type='html'>&lt;div&gt;I saw &lt;a href="http://goodliffe.blogspot.com/search/label/threads"&gt;this&lt;/a&gt; and started thinking back on a calculus course at university.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Wouldn't we expect a theorem like this to be true:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;"for all codebases C and features F, there exists a set of refactorings R and unit test U, such that U(F) is safe under R(C)"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In other words, can we not manipulate any piece of untestable thread code into a testable one, given enough refactorings and inversion of control levers (and effort!)? Seems reasonable to me.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In a situation with 2 threads and one interaction, it is easy to imagine the combinatorial complexity of test cases. It of course explodes when the numbers go up - but perhaps we could argue that for any number of threads and interactions, we can reduce the complexity of our tests by looking at each in isolation...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If my theorem holds, you can of course turn it around and use it to knock people over their heads when they screw up thread testing - hmm, how productive that would be :-)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Interesting thought, anyway.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8405165711854469088-784039789538036603?l=lassewesth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lassewesth.blogspot.com/feeds/784039789538036603/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8405165711854469088&amp;postID=784039789538036603' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/784039789538036603'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/784039789538036603'/><link rel='alternate' type='text/html' href='http://lassewesth.blogspot.com/2008/09/unit-testing-with-threads.html' title='Unit Testing With Threads'/><author><name>LasseWesth</name><uri>http://www.blogger.com/profile/14183130837834650426</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-8405165711854469088.post-6172635085931232693</id><published>2008-09-25T08:58:00.000-07:00</published><updated>2008-09-25T09:46:20.278-07:00</updated><title type='text'>Surprisingly Good Error Messages!</title><content type='html'>I was stunned recently by finding a piece of software that does something reasonably complicated, but still manages to give good error messages.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Just look at this beauty from &lt;a href="http://static.springframework.org/spring/docs/2.0.x/reference/beans.html"&gt;Spring IOC&lt;/a&gt;:&lt;/div&gt;&lt;br /&gt;&lt;code&gt;org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'magiceightball' defined in file [C:\...\random\magiceightball.test.xml]: Cannot resolve reference to bean 'randomsource' while setting constructor argument; nested exception is org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [foo.Foo] for bean with name 'randomsource' defined in file [C:\...\random\magiceightball.test.xml]; nested exception is java.lang.ClassNotFoundException: foo.Foo at [...]&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;That is actually perfectly readable! Alright, I am a nerd, and I have some experience with debugging Java code, but I bet a 9-year-old child could deduce that they forgot to implement a RandomSource called Foo.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I was stunned when I saw it, perhaps because it is so rare to get useful error messages from clever frameworks. As soon as reflection enters the picture, people just give up it seems. Look at this example as a contrast:&lt;/div&gt;&lt;br /&gt;&lt;code&gt;com.google.inject.CreationException: Guice configuration errors: 1) Error at foo.BarTestModule$TestBar.&lt;init&gt;(BarTest.java:18):&lt;/init&gt; Could not find a suitable constructor in foo.BarTestModule$TestBar. Classes must have either one (and only one) constructor annotated with @Inject or a zero-argument constructor. 1 error[s] at com.google.inject.BinderImpl.createInjector(BinderImpl.java:277)&lt;br /&gt;[blah blah]&lt;/code&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style=" ;font-family:-webkit-monospace;font-size:13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div&gt;Hmm, that's funny, I distinctly remember creating a zero-argument constructor in TestBar??? It turns out, &lt;a href="http://code.google.com/p/google-guice/wiki/Guice10Recipes#How_can_I_inject_an_inner_class?"&gt;Guice does not support injection of inner classes&lt;/a&gt;. And it only took me an hour to figure that out... So is this error message helpful, or rather harmful?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Hibernate is equally bad and will give you a lot of grief if you do not tread carefully. And these are popular, high-profile pieces of software, not random open-source amateur junk off of SourceForge. So how come Spring IOC got it right and these guys got it so wrong?&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/8405165711854469088-6172635085931232693?l=lassewesth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lassewesth.blogspot.com/feeds/6172635085931232693/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8405165711854469088&amp;postID=6172635085931232693' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/6172635085931232693'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/6172635085931232693'/><link rel='alternate' type='text/html' href='http://lassewesth.blogspot.com/2008/09/surprisingly-good-error-messages.html' title='Surprisingly Good Error Messages!'/><author><name>LasseWesth</name><uri>http://www.blogger.com/profile/14183130837834650426</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>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8405165711854469088.post-8488533445584761820</id><published>2008-09-22T04:38:00.000-07:00</published><updated>2008-09-22T05:01:45.945-07:00</updated><title type='text'>T-shirt Size Estimation</title><content type='html'>We have all been through painfil estimation sessions. What makes them painful is formality.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The Living Room Architect talks about a &lt;a href="http://blog.livingroomarchitect.com/2008/08/story-card-matrix.html"&gt;Story Matrix&lt;/a&gt;, as a way of facilitating a smoother flow for estimating a bunch of stories. Good idea.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One problem still persists though, is the formality of it, with the whole points debate: do we use Fibonacci, linear, exponential, what? What do the numbers mean? And the apprehention on the part of us developers to be specific with stories they have only just begun to think about.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Someone today introduced me to T-shirt Sized Estimation - you basically cluster your stories into S, M and L. Sizes cover plain "lines of code", complexity and risk. But it has an implied light touch which seems to solve some problems I think, it seemed to go quickly and easily, and we did get a result out of it.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;No numbers, so nothing to get too hung up about&lt;/li&gt;&lt;li&gt;Only 3 categories, so we don't have to discuss things for very long - it is implied that this isn't the final clustering&lt;/li&gt;&lt;li&gt;We still got to communicate about the stories, so Agile Tick Mark&lt;span class="Apple-style-span"   style="border-collapse: collapse;   font-family:verdana;font-size:13px;"&gt;™&lt;/span&gt; right there&lt;/li&gt;&lt;li&gt;And we got a rough set of estimates&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Now, that isn't of course the final word in the estimation process, and we all know that, so no point in getting defensive. We will need numbers at some point. But it got us perhaps half way. We did talk about our understanding of the stories, and we did get a picture of how hard the project might be.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But most importantly, we didn't get hung up on details - instead we split the process into 2 (or more) phases. A bit like when you look at algorithms, you know that when you need to traverse a graph and do something complicated, you can either write the mother of all recursive functions, or you can split up into separate stages (search and modify stages for example). In the end, we all know that O(n) + O(n) = O(n) - i.e. the amount of effort will be the same, but it will be easier to manage the two things separately.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We will certainly need another card session, and we will need some numbers at some point, but for now we have fleshed out some things, in a very short time and noone has run off crying. And that has to be considered progress.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8405165711854469088-8488533445584761820?l=lassewesth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lassewesth.blogspot.com/feeds/8488533445584761820/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8405165711854469088&amp;postID=8488533445584761820' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/8488533445584761820'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/8488533445584761820'/><link rel='alternate' type='text/html' href='http://lassewesth.blogspot.com/2008/09/t-sirt-size-estimation.html' title='T-shirt Size Estimation'/><author><name>LasseWesth</name><uri>http://www.blogger.com/profile/14183130837834650426</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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8405165711854469088.post-5687095177846041018</id><published>2008-09-15T09:18:00.000-07:00</published><updated>2008-09-15T09:20:50.562-07:00</updated><title type='text'>Schema Spy</title><content type='html'>While reverse-engineering a customer's database, my pair-mate introduced me to Schema Spy. It looks quite good: lightweight cross-db reporting and visualization, runs from the command line and gives you an HTML folder structure.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://schemaspy.sourceforge.net/"&gt;http://schemaspy.sourceforge.net/&lt;/a&gt;&lt;br /&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/8405165711854469088-5687095177846041018?l=lassewesth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lassewesth.blogspot.com/feeds/5687095177846041018/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8405165711854469088&amp;postID=5687095177846041018' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/5687095177846041018'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/5687095177846041018'/><link rel='alternate' type='text/html' href='http://lassewesth.blogspot.com/2008/09/schema-spy.html' title='Schema Spy'/><author><name>LasseWesth</name><uri>http://www.blogger.com/profile/14183130837834650426</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-8405165711854469088.post-7599898726829953555</id><published>2008-09-11T15:28:00.000-07:00</published><updated>2008-09-11T16:02:22.957-07:00</updated><title type='text'>Top 10 Books On Software</title><content type='html'>A &lt;a href="http://www.blogger.com/profile/02339143544719044213"&gt;friend of mine&lt;/a&gt; &lt;a href="http://blog.livingroomarchitect.com/2008/09/top-10-software-engineering-books.html"&gt;blogged about books&lt;/a&gt;. His question was: "&lt;span class="Apple-style-span" style="color: rgb(51, 51, 51); font-family: Verdana; font-size: 13px; font-style: italic; font-weight: bold; line-height: 16px; "&gt;What are, in your opinion, the top 10 books that every software engineer/developer should read?&lt;/span&gt;". Well, here are a few to get you started:&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://books.google.co.uk/books?id=aQ1RAAAAMAAJ&amp;amp;q=design+patterns&amp;amp;dq=design+patterns"&gt;Gamma et al.: "Design Patterns"&lt;/a&gt;. An absolute classic. After reading it I immediately went into pattern fever (as everyone does?). Interestingly, the patterns themselves aren't that useful for the stuff I do day to day, but the idea is powerful. And of course, this book started the whole Patterns Movement...&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://books.google.co.uk/books?id=jYDEkHFXniEC&amp;amp;printsec=frontcover&amp;amp;dq=schwartzbach&amp;amp;sig=ACfU3U38f2p3SPCweDdrifpd7e6BxAgbeQ"&gt;Møller &amp;amp; Schwartzbach: "&lt;/a&gt;&lt;span id="btAsinTitle"&gt;&lt;a href="http://books.google.co.uk/books?id=jYDEkHFXniEC&amp;amp;printsec=frontcover&amp;amp;dq=schwartzbach&amp;amp;sig=ACfU3U38f2p3SPCweDdrifpd7e6BxAgbeQ"&gt;An Introduction to XML and Web Technologies&lt;/a&gt;&lt;/span&gt;&lt;a href="http://books.google.co.uk/books?id=jYDEkHFXniEC&amp;amp;printsec=frontcover&amp;amp;dq=schwartzbach&amp;amp;sig=ACfU3U38f2p3SPCweDdrifpd7e6BxAgbeQ"&gt;"&lt;/a&gt;. I am slightly biased, having taken an XML course from the authors. But, this book really puts things in perspective, it is thorough and clear, and offers opinion. The web is full of simple examples, re-hashes, cheaply written stuff without depth. So this was a great and welcome read.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://books.google.co.uk/books?id=xRlRAAAAMAAJ&amp;amp;q=larman&amp;amp;dq=larman"&gt;Larman: "Applying UML and Patterns"&lt;/a&gt;. This one really hit the spot. I was idling somewhat, lacking direction, and this one gave me a spark of inspiration. The way it formulates those simple, old-fashioned OO values, it takes you back to first principles and reminds you why it is we do what we do. It is easy to get lost in new technology, tools, methodology and process - but what we really need is to remember those few, simple things: model your domain, separate concerns, an Bob is your uncle!&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8405165711854469088-7599898726829953555?l=lassewesth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lassewesth.blogspot.com/feeds/7599898726829953555/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8405165711854469088&amp;postID=7599898726829953555' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/7599898726829953555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/7599898726829953555'/><link rel='alternate' type='text/html' href='http://lassewesth.blogspot.com/2008/09/top-10-books-on-software.html' title='Top 10 Books On Software'/><author><name>LasseWesth</name><uri>http://www.blogger.com/profile/14183130837834650426</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-8405165711854469088.post-2827596794028916753</id><published>2008-09-11T15:18:00.000-07:00</published><updated>2008-09-11T15:25:31.203-07:00</updated><title type='text'>All The Cool Kids Have A Blog</title><content type='html'>All the cool kids have a blog, so I think I should have one too. That is about as much reasoning as I can muster right now.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I am always impressed with blogger's boldness, the way they reveal their hand to the world and take sides. I wonder if I will be as brave? I like to ask questions. Do questions belong in a blog? Or does it only work if you have that blogger-swagger?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Anyway, we shall see what comes of it!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8405165711854469088-2827596794028916753?l=lassewesth.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lassewesth.blogspot.com/feeds/2827596794028916753/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8405165711854469088&amp;postID=2827596794028916753' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/2827596794028916753'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8405165711854469088/posts/default/2827596794028916753'/><link rel='alternate' type='text/html' href='http://lassewesth.blogspot.com/2008/09/all-cool-kids-have-blog.html' title='All The Cool Kids Have A Blog'/><author><name>LasseWesth</name><uri>http://www.blogger.com/profile/14183130837834650426</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></feed>
