<?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-5099452783517680285</id><updated>2011-12-19T15:54:43.111+01:00</updated><category term='agile clear case hudson continuous integration plugin howto'/><category term='declarative concurrency mozart deterministic threading'/><category term='developer conference learning unconference inspiration learning mejsla'/><category term='mobilt bredband hardy heron tre 3 huawei kubuntu linux networking wireless e220 trådlöst nätverk mobile broadband'/><category term='java ant linux configuring'/><category term='developer conference learning unconference inspiration learning senior mejsla adaptiv agical clojure'/><category term='management programming repository agile'/><category term='KDE Linux usability sound'/><category term='linux adept dpgk apt-get update problems'/><category term='java examples rhetoric'/><category term='food recommended stockholm Chinese restaurants'/><category term='games pc rpg'/><category term='java openjdk opensource howto'/><category term='blogs'/><category term='hardware wlan linux drivers'/><category term='java webapp jar url log4j properties inside servlet'/><category term='java design scala type inference language'/><category term='linux wine mount umount cd drive'/><category term='interview questions programming work satisfaction stress'/><title type='text'>LarsW@Blogspot</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://larswestergren.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://larswestergren.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Lars Westergren</name><uri>http://www.blogger.com/profile/02654687571384000146</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_18LJx0IKqk0/SNjXSniCg3I/AAAAAAAAAAM/xENi61UQNj8/s1600-R/larswestergren.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>25</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5099452783517680285.post-4987961952124896695</id><published>2011-04-15T14:41:00.007+02:00</published><updated>2011-04-15T15:10:52.677+02:00</updated><title type='text'>Simple SOAP client</title><content type='html'>I needed a quick and simple SOAP client to verify some odd return values from a web service. I also wanted the client to be able to send and receive badly formatted  XML  for testing purposes, and preferably pretty print the xml. Didn't feel very appealing to try to do this in Java, so I decided to do it with JRuby.&lt;br /&gt;&lt;br /&gt;Ruby already has the soap4r library, which given a wsdl url gives you convenient objects for performing requests. Unfortunately soap4r tries to retrieve the wsdl with a http GET, and the service is configured to only respond to POST (yes, even for wsdl request). So I decided to go directly to the HTTPClient. Here it is, including pretty printing the  output, if someone else finds it useful.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;require 'rubygems'&lt;br /&gt;require 'httpclient'&lt;br /&gt;&lt;br /&gt;soapbody = &amp;lt;&amp;lt;-eos&lt;br /&gt;&amp;lt;soap:Envelope&amp;gt;&lt;br /&gt;  ** your soapy stuff goes here **&lt;br /&gt;&amp;lt;/soap:Envelope&amp;gt;&lt;br /&gt;eos&lt;br /&gt;&lt;br /&gt;header = {'Content-Type' =&amp;gt; 'application/soap+xml'}&lt;br /&gt;endpoint = &amp;quot;http://localhost:8080/testService&amp;quot;&lt;br /&gt;&lt;br /&gt;client = HTTPClient.new&lt;br /&gt;#Uncomment next line if you want to see requests and responses as sent.&lt;br /&gt;#client.debug_dev=STDOUT&lt;br /&gt;result = client.post(endpoint, soapbody, header)&lt;br /&gt;&lt;br /&gt;puts '== Content'&lt;br /&gt;print result.body&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;There are some more sample usages of HTTPClient &lt;a href="https://github.com/nahi/httpclient/tree/master/sample"&gt;here&lt;/a&gt;, the class documentation is &lt;a href="http://rubydoc.info/gems/httpclient/2.2.0/frames"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If you have a valid xml reply and want to pretty print it, add:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;require &amp;quot;jrexml&amp;quot;&lt;br /&gt;require &amp;quot;rexml/document&amp;quot;&lt;br /&gt;doc = REXML::Document.new result.body&lt;br /&gt;doc.write( STDOUT, 3 )&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5099452783517680285-4987961952124896695?l=larswestergren.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://larswestergren.blogspot.com/feeds/4987961952124896695/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5099452783517680285&amp;postID=4987961952124896695' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/4987961952124896695'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/4987961952124896695'/><link rel='alternate' type='text/html' href='http://larswestergren.blogspot.com/2011/04/simple-soap-client.html' title='Simple SOAP client'/><author><name>Lars Westergren</name><uri>http://www.blogger.com/profile/02654687571384000146</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_18LJx0IKqk0/SNjXSniCg3I/AAAAAAAAAAM/xENi61UQNj8/s1600-R/larswestergren.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5099452783517680285.post-6254465024813882256</id><published>2010-10-17T08:57:00.021+02:00</published><updated>2010-10-18T16:29:03.079+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='developer conference learning unconference inspiration learning mejsla'/><title type='text'>Unconference at Mejsla</title><content type='html'>We've had another &lt;a href="http://larswestergren.blogspot.com/2010/06/unconference.html"&gt;unconference&lt;/a&gt; day, this time at &lt;a href="http://www.mejsla.se/"&gt;Mejsla&lt;/a&gt; and arranged by yours truly. Participants were &lt;a href="http://www.mejsla.se/lars.westergren"&gt;me&lt;/a&gt;, &lt;a href="http://twitter.com/svjson"&gt;Sven Johansson&lt;/a&gt;, &lt;a href="http://www.mejsla.se/thomas.podal"&gt;Thomas Podal&lt;/a&gt;, &lt;a href="http://www.highlevelbits.com/"&gt;Fredrik Rubensson&lt;/a&gt;, &lt;a href="http://marten.gustafson.pp.se/"&gt;Mårten Gustafson&lt;/a&gt; and &lt;a href="http://r-c-r.tumblr.com/"&gt;Henrik Engström&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Topics&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Topics explored during the day included:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;the Erlang based key-value store &lt;a href="https://wiki.basho.com/display/RIAK/Riak"&gt;Riak&lt;/a&gt;&lt;/li&gt;&lt;li&gt;the cross-browser WebSocket &lt;a href="http://socket.io/"&gt;Socket.IO&lt;/a&gt;&lt;/li&gt;&lt;li&gt;the Scala based web framework &lt;a href="http://liftweb.net/"&gt;Lift&lt;/a&gt;,&lt;/li&gt;&lt;li&gt;JavaScript as a backend language, and especially its asynchronous &lt;a href="http://nodejs.org/"&gt;node.js&lt;/a&gt; framework&lt;/li&gt;&lt;li&gt;the graph database &lt;a href="http://neo4j.org/"&gt;Neo4J&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Google's &lt;a href="http://code.google.com/p/guava-libraries/"&gt;Guava libraries&lt;/a&gt;&lt;/li&gt;&lt;li&gt;the JVM based Lisp-like &lt;a href="http://clojure.org/"&gt;Clojure&lt;/a&gt;&lt;/li&gt;&lt;li&gt;getting started with &lt;a href="http://www.ruby-lang.org/en/"&gt;Ruby&lt;/a&gt; + &lt;a href="http://rubyonrails.org/"&gt;Rails&lt;/a&gt; + &lt;a href="http://heroku.com/"&gt;Heroku&lt;/a&gt;&lt;/li&gt;&lt;li&gt;the experimental &lt;a href="http://www.mirah.org/"&gt;Mirah&lt;/a&gt; language&lt;/li&gt;&lt;li&gt;&lt;a href="http://jquery.com/"&gt;JQuery&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Blocks&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A slow wireless network and the time it took to get to a "Hello World" state usually meant that we only had time to do a quick spike for each topic. The day was still very interesting, and we learned enough to see what might be worth to pursue further, but for the next unconference I think we will create a Wiki or similar so we can collect topic suggestions in advance. Then we can see which topics have the most interest in, and people who are sure they are going to spend time on a topic can download tools and libraries in advance. That way they can make sure they have passed the 1st compile and "hello world" steps, and maybe even have prepared a few questions or demos if they feel like it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Lift&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Two topics I participated in but which were examples of these "high overhead" tasks, were node.js and Lift. For Lift, I started downloading and installing the Scala language, but then discovered that the easiest way to get started was instead to download the &lt;a href="http://code.google.com/p/simple-build-tool/"&gt;sbt - the Simple Build Tool&lt;/a&gt; jar from Google, create a shell script on path to execute the jar, and then run&lt;br /&gt;&lt;pre&gt;&lt;code&gt;sbt update ~jetty-run&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;on an empty Lift project. This will download Scala, Lift, and all the dependent jars from the nearest Maven repository, then start the small Jetty server. Lift detected file changes live, which enabled a quick cycle of modifications and then reloading pages to instantly see the changes. Unfortunately Lift crashed with an OutOfMemoryError:PermGen exception after just a few changes to a html page in the "static" directory. &lt;a href="http://blog.headius.com/2008/09/first-taste-of-invokedynamic.html"&gt;PermGen problems&lt;/a&gt; is an annoyance for most alternative languages on the JVM, but this didn't give a very stable impression. After a restart things were much more stable and we couldn't reproduce the error, so it may have been an effect of the large number of initial downloads to get the system started the first time.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;node.js&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A lot of the time was spent on building node.js itself with "make", so we didn't get very far. But at least we got the "asynchronous web server in 10 lines" up and running. Again I was impressed with &lt;a href="http://www.jetbrains.com/idea/"&gt;IntelliJ&lt;/a&gt; though, which had nice support for JavaScript editing. If I'm going to continue using fully featured IDEs, I feel I really should learn to use IntelliJ, and purchase it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Mirah&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;Mirah is a very interesting language. We got it up and running very quickly (though if we hadn't had a working JRuby and Git set up it might have been a different story). Syntactically the language resembles Ruby very much, but it turns out it is actually statically typed and compiled. The types are generally inferred (like in Scala) for uncluttered code and a minimal amount of typing. We only created a few Java classes which can be imported and used in Java projects, but apparently you should be able to plug in different compiler backends so that you can emit... anything you may like. Source for other languages, Dalvik bytecode, or whatever. The mappings to Java bytecode seemed to work fine, we only had trouble with creating a "void" method. I'm going to experiment a lot more with this language, expect blog posts and hopefully a lightning speech together with Peter Lind at JFokus 2011.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Guava&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;This was a revelation for me. I had heard it mentioned in passing before, on a presentation by &lt;a href="http://twitter.com/ennru"&gt;&lt;span style="text-decoration: underline;"&gt;Enno Runne&lt;/span&gt;&lt;/a&gt; for instance, but it was one in an ever growing list of "things I ought to spend some time on". It turned out that these libraries are something that will help me enormously in my day-to-day Java programming:&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;A @VisibleForTesting annotation is helpful for documentation, as I very often relax visibilities on helper methods to enable unit testing on them, this will eliminate a lot of boilerplate javadocs. &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Classes that add functional style methods for manipulating collections (given the syntactical and semantical restrictions of the Java language and platform of course).&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Helper methods for primitives and arrays, which will be extremely helpful for me to clean up a library which is written in C style and does nothing but manipulate bytes and byte arrays.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Additions to the java.util.concurrent package, including a ListenableFuture that you can chain together for asynchronous workflows.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:100%;"&gt;These libraries every Java developer should be aware of. Big thanks to Henrik who had prepared some demos on this in advance. This was not expected of the participants, but it was very helpful.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Ruby, Rails and Heroku&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;A quick introduction to the Ruby language to those who were unfamiliar with it. We then generated a Rails project and I explained the structure of it, what could be done with the scripts, and so on. We then went on to what we thought would be the meat of the session, Heroku. Only, it took less than 5 minutes to integrate Git and Heroku. Pushing changes to Git made Heroku update, autodetect that it was a Rails project, download dependencies and start up an instance of our application in their cloud. Jaw-droppingly simple, as is often the case with Ruby. We then went back and did some more Ruby and Rails programming. Sven, whom I've had a hard time convincing about the excellence of Ruby, seemed to be on the way to becoming a convert.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;The future, and books about it&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;Towards the end of the day we were mentally exhausted and instead of doing another programming session we sat together and talked about good books, fictional and not. The only titles I remember were Kent Beck's Implementation Patterns, The Human Body 2.0, Charles Stross' Accelerando, and Vernor Vinge's Rainbow's End.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;What we didn't have time for&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;Topics that remained on the board, but which we hopefully will be able to do on another day:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Testing Java with Ruby's excellent testing tools through &lt;a href="http://jtestr.codehaus.org/"&gt;JTestR&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt; Ruby web framework &lt;a href="http://www.sinatrarb.com/"&gt;Sinatra&lt;/a&gt; + &lt;a href="http://haml-lang.com/"&gt;HAML&lt;/a&gt; markup.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Getting started with &lt;a href="http://python.org/"&gt;Python &lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Doing the &lt;a href="http://katas.softwarecraftsmanship.org/"&gt;Software Craftsmanship Ruby refactoring excercises&lt;/a&gt; from SC 2010&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Amazon's &lt;a href="http://aws.amazon.com/ec2/"&gt;EC2&lt;/a&gt; cloud&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Massive scaling with MOM, especially &lt;a href="http://activemq.apache.org/"&gt;ActiveMQ&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Getting started with event-driven design and Actors with &lt;a href="http://akkasource.org/"&gt;Akka&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;&lt;a href="http://en.wikipedia.org/wiki/HTML5"&gt;HTML 5&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;&lt;a href="http://www.jedi.be/blog/2010/02/12/what-is-this-devops-thing-anyway/"&gt;Devops&lt;/a&gt; and &lt;a href="http://wiki.opscode.com/display/chef/Home"&gt;OpsCode Chef&lt;/a&gt; &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Java 2.0 discussion. (Presumably means - next Java version).&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;&lt;a href="http://cukes.info/"&gt;Cucumber&lt;/a&gt; and &lt;a href="http://github.com/aslakhellesoy/cuke4duke/wiki"&gt;Cuke4Duke&lt;/a&gt; &lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Summary&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;Big thanks to all the participants for making this an excellent day, it was a privilege to learn from and with you.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5099452783517680285-6254465024813882256?l=larswestergren.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://larswestergren.blogspot.com/feeds/6254465024813882256/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5099452783517680285&amp;postID=6254465024813882256' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/6254465024813882256'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/6254465024813882256'/><link rel='alternate' type='text/html' href='http://larswestergren.blogspot.com/2010/10/unconference-at-mejsla.html' title='Unconference at Mejsla'/><author><name>Lars Westergren</name><uri>http://www.blogger.com/profile/02654687571384000146</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_18LJx0IKqk0/SNjXSniCg3I/AAAAAAAAAAM/xENi61UQNj8/s1600-R/larswestergren.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5099452783517680285.post-390832001964220392</id><published>2010-06-20T16:34:00.011+02:00</published><updated>2010-06-21T12:20:55.134+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='developer conference learning unconference inspiration learning senior mejsla adaptiv agical clojure'/><title type='text'>Unconference</title><content type='html'>&lt;h1&gt;Unconference day&lt;/h1&gt;&lt;br /&gt;A few weeks ago I was at a learning event arranged by &lt;a href="http://manssandstrom.wordpress.com/"&gt;Måns Sandström&lt;/a&gt; from &lt;a href="http://www.adaptiv.se/"&gt;Adaptiv&lt;/a&gt; together with &lt;a href="http://ellnestam.wordpress.com/"&gt;Ola Ellnestam&lt;/a&gt; from &lt;a href="http://www.agical.se/sv/index.html"&gt;Agical&lt;/a&gt;. It was called "Learning the learned". The people who arranged it had noticed that senior developers have difficulty finding worthwhile learning events. Courses are often very expensive and is often on such a basic level that any of the participants could have been in charge of the course themselves if given a day to prepare. Conference presentations, while inspiring, are often too short to go into any greater depth, and have to take into consideration that many in the audience may be juniors.&lt;br /&gt;&lt;br /&gt;So the solution was to have the senior developers teach each others. The format was inspired by the "unconference" or "Open Spaces" concepts that you may have seen from conferences. In other words, instead of having one person in charge and many passive listeners, people are encouraged to self organize in groups around topics that interest them and then discuss, pair program, draw on whiteboards, or whatever they can come up with. Måns and Ola invited a number of people who they thought had valuable things to contribute to such a day. After a few unfortunate last minute cancellations we were 7 participants at the start of the day.&lt;br /&gt;&lt;br /&gt;At the beginning of the day, each participant wrote down a short sentence  on a sticky note for every topic he* found interesting and wanted to explore. We put the notes up on a whiteboard in turn and explained a little more in depth what each topic was about. We then wrote our names on every note that sounded interesting. Then we picked two notes with the highest number of votes and formed two groups. One group wanted to explore "Testing frameworks for functional languages", and my group wanted to discuss "Unit testing beyond 'assertEquals'". We discussed how it feels like there are often two sources of non-DRY code when writing tests in Java - test data setup, and secondly the assertion lines themselves (so yes, pretty much all of it, unfortunately). For test data setup we quickly discussed Object Mother and Data Builder patterns, and mock frameworks like Mockito. For the assertions parts, I learned for the first time about Matchers (&lt;a href="http://code.google.com/p/hamcrest/"&gt;hamcrest&lt;/a&gt;  to be specific) and the &lt;span style="font-style: italic;"&gt;assertThat&lt;/span&gt;  method. The combination of the two creates very readable error  messages and tests that can be quickly and cleanly written by combining  predicating matchers. At the end of the session we did a quick recap of what we had learned for the other group. As people came up with new topic ideas, new sticky notes went up on the board during the day.&lt;br /&gt;&lt;br /&gt;Second and third sessions I spent doing the first few exercises of the excellent &lt;a href="http://www.knowing.net/index.php/2006/06/16/15-exercises-to-know-a-programming-language-part-1/"&gt;15 exercises to know a programming language&lt;/a&gt; using &lt;a href="http://clojure.org/"&gt;Clojure&lt;/a&gt;, together with &lt;a href="http://ellnestam.wordpress.com/"&gt;Ola Ellnestam&lt;/a&gt; and &lt;a href="http://microserf.wordpress.com/"&gt;Peter Hultgren&lt;/a&gt; who has since founded the &lt;a href="http://groups.google.com/group/stockholm-clojure-user-group?pli=1"&gt;Stockholm Clojure User Group&lt;/a&gt;. At the final session of the day people were pretty mentally exhausted, and instead of programming we all did a session together where we discussed "Books every developer should read" - programming related and not.&lt;br /&gt;&lt;br /&gt;In between sessions Ola was in charge of short exercises that were either medition and focusing exercises, or little games designed to make the participants get to know each other better. These were great fun, and helped greately to keep concentration up.&lt;br /&gt;&lt;br /&gt;For me this was a fantastic day. I learned much more than I have at the conferences I usually attend, plus I got to know new interesting people. Before going I was a bit nervous - the topics I had come up with felt "too easy" - stuff a senior programmer should already know. But considering how expansive our field is (and growing every day), no one can be an expert at everything, so this was really something I needn't have worried about (and neither should you, if you decide to go to something similar).&lt;br /&gt;&lt;br /&gt;I think that if I could go to something like this once a month, it would accelerate my learning and my career enormously. Hopefully this will become a regular event, the participants all agreed we should try to do it at least once every couple of months. And there is nothing stopping you from arranging a similar event, the concept is not trademarked or anything (though the people who arranged this day say mentioning them as a source of inspiration is appreciated).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;* Only guys present this time unfortunately. Sad that gender imbalance in our sector is actually growing! But that is a topic for another post...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5099452783517680285-390832001964220392?l=larswestergren.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://larswestergren.blogspot.com/feeds/390832001964220392/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5099452783517680285&amp;postID=390832001964220392' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/390832001964220392'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/390832001964220392'/><link rel='alternate' type='text/html' href='http://larswestergren.blogspot.com/2010/06/unconference.html' title='Unconference'/><author><name>Lars Westergren</name><uri>http://www.blogger.com/profile/02654687571384000146</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_18LJx0IKqk0/SNjXSniCg3I/AAAAAAAAAAM/xENi61UQNj8/s1600-R/larswestergren.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5099452783517680285.post-1809340514547832969</id><published>2010-03-23T10:57:00.006+01:00</published><updated>2010-03-23T11:16:12.463+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java webapp jar url log4j properties inside servlet'/><title type='text'>Load log4j.properties from jar file in webapp</title><content type='html'>Having environment specific log4j.properties inside a jar file is hardly an ideal solution, but if you find yourself in a similar situation:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;import java.net.URL;&lt;br /&gt;import org.apache.log4j.PropertyConfigurator;&lt;br /&gt;import javax.servlet.http.HttpServlet;&lt;br /&gt;&lt;br /&gt;public class Log4jConfLoad extends HttpServlet {&lt;br /&gt;&lt;br /&gt;  @Override&lt;br /&gt;  public void init() {&lt;br /&gt;    try {&lt;br /&gt;      String prefix = &amp;quot;jar:file:&amp;quot; + getServletContext().getRealPath(&amp;quot;/&amp;quot;);&lt;br /&gt;      String path = &amp;quot;WEB-INF/lib/the.jar!/&amp;quot; + System.getProperty(&amp;quot;env&amp;quot;) + &amp;quot;/log4j.properties&amp;quot;;&lt;br /&gt;      PropertyConfigurator.configure(new URL(prefix+path));&lt;br /&gt;    catch (Exception ex) {&lt;br /&gt;      //Because Servlet init can't be declared as throwing new exception.&lt;br /&gt;      //Any thrown Exception here should show up in catalina.out (if Tomcat used)&lt;br /&gt;      throw new RuntimeException(ex);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Also remember to add the servlet to web.xml with load-on-startup.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5099452783517680285-1809340514547832969?l=larswestergren.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://larswestergren.blogspot.com/feeds/1809340514547832969/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5099452783517680285&amp;postID=1809340514547832969' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/1809340514547832969'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/1809340514547832969'/><link rel='alternate' type='text/html' href='http://larswestergren.blogspot.com/2010/03/load-log4jproperties-from-jar-file-in.html' title='Load log4j.properties from jar file in webapp'/><author><name>Lars Westergren</name><uri>http://www.blogger.com/profile/02654687571384000146</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_18LJx0IKqk0/SNjXSniCg3I/AAAAAAAAAAM/xENi61UQNj8/s1600-R/larswestergren.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5099452783517680285.post-4643543493435695919</id><published>2009-12-23T09:36:00.005+01:00</published><updated>2009-12-24T10:46:09.773+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java examples rhetoric'/><title type='text'>"That" Java example and preaching to the converted</title><content type='html'>There is one example of Java code that keeps coming up. I have seen variants of it at conference presentations several times, in Venkat Subramaniam's &lt;a href="http://pragprog.com/titles/vslg/programming-groovy"&gt;Programming Groovy&lt;/a&gt; and most recently in an essay by Neal Ford in &lt;a href="http://pragprog.com/titles/twa/thoughtworks-anthology"&gt;The ThoughtWorks Anthology&lt;/a&gt;. This example compares Java with a scripting language, and goes usually something like this (here I combine all the worst practices from the books in one example):&lt;br /&gt;&lt;br /&gt;JAVA VERSION:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import java.io.*;&lt;br /&gt;&lt;br /&gt;public class ReadFile&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;public ReadFile(String path)&lt;br /&gt;{&lt;br /&gt;    BufferedReader reader = null;&lt;br /&gt;     try&lt;br /&gt;     {&lt;br /&gt;         reader = new BufferedReader(&lt;br /&gt;                                 new FileReader(path));&lt;br /&gt;         String line = null;&lt;br /&gt;         while((line = reader.readLine()) != null)&lt;br /&gt;         {&lt;br /&gt;               System.out.println(line);&lt;br /&gt;         }&lt;br /&gt;      }&lt;br /&gt;     catch(FileNotFoundException ex)&lt;br /&gt;     {&lt;br /&gt;          ex.printStackTrace();&lt;br /&gt;     }&lt;br /&gt;     catch(IOException ex)&lt;br /&gt;     {&lt;br /&gt;          ex.printStackTrace();&lt;br /&gt;     }&lt;br /&gt;     finally&lt;br /&gt;     {&lt;br /&gt;          try&lt;br /&gt;          {&lt;br /&gt;            if (reader!=null)&lt;br /&gt;            {&lt;br /&gt;                reader.close();&lt;br /&gt;            }&lt;br /&gt;          }&lt;br /&gt;          catch (IOException ex)&lt;br /&gt;          {&lt;br /&gt;           //Ignore&lt;br /&gt;          }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt; public static void main(String[] args)&lt;br /&gt; {&lt;br /&gt;  new ReadFile("thoreau.txt");&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;GROOVY VERSION:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;println new File('thoreau.txt').text&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Wow, 1 line instead of almost 50! Java must really suck! The problem with this is that the Groovy version is obviously just a one-off, there is no attempt to make a reusable module or do robust error handling. If there is an error, the program just terminates with en error message. We can do exactly the same with the Java version and cut down the number of lines significantly if we just throw the exception. We can reduce the number of lines even more if we use a "modern" (1.5) API and the Java coding conventions for where to place brackets, etc:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import java.io.File;&lt;br /&gt;import java.util.Scanner;&lt;br /&gt;&lt;br /&gt;public class ReadFile {&lt;br /&gt;&lt;br /&gt;    public static void main(String[] args) throws Exception {&lt;br /&gt;        File in = new File("thoreu.txt");&lt;br /&gt;        String contents = new Scanner(in).useDelimiter("\\Z").next();&lt;br /&gt;        System.out.println(contents);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It can be made a one or two lines shorter still, (at the price of a dependency on a big jar) if you are are willing to use an external library such as &lt;a href="http://commons.apache.org/io/"&gt;Apache Commons IO&lt;/a&gt;. Or I could have squeezed the three lines of logic into one, but I think this is a reasonable trade off between readability and verbosity. But this new and improved example is still much longer than the Ruby/Groovy/Scala/etc versions (especially if you count characters instead of lines); and arguably less clear (What's a scanner? What does "\\z" mean?).&lt;br /&gt;&lt;br /&gt;The problem with using the original Java example is that will mainly convince those who are firmly in the "Yeah, Java totally sucks" camp. Even a very junior Java developer, who is curious about learning about a new language will see that the original example is either&lt;br /&gt;a) Written by a rank amateur (unlikely considering the caliber of the authors) Or -&lt;br /&gt;b) Wildly exaggerated to make Java look as bad as possible.&lt;br /&gt;And that will make them less receptive to the text as a whole. With the number of active Java programmers probably (still) in the hundreds of thousands, alternative languages have a large number of possible recruits and allies. I would prefer to see a better example to convince them that it is worthwhile to look at other languages.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5099452783517680285-4643543493435695919?l=larswestergren.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://larswestergren.blogspot.com/feeds/4643543493435695919/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5099452783517680285&amp;postID=4643543493435695919' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/4643543493435695919'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/4643543493435695919'/><link rel='alternate' type='text/html' href='http://larswestergren.blogspot.com/2008/08/that-java-example-and-preaching-to.html' title='&quot;That&quot; Java example and preaching to the converted'/><author><name>Lars Westergren</name><uri>http://www.blogger.com/profile/02654687571384000146</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_18LJx0IKqk0/SNjXSniCg3I/AAAAAAAAAAM/xENi61UQNj8/s1600-R/larswestergren.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5099452783517680285.post-8756869340556202267</id><published>2009-08-10T09:04:00.002+02:00</published><updated>2009-08-10T09:10:42.040+02:00</updated><title type='text'>Pragmatic argumentation</title><content type='html'>I read Chad Fowler's The Passionate Programmer this weekend. All in all a pretty good book which I recommend. Remaining from the previous edition however is one of my least favorite paragraphs in the book.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;In his essay "Great Hackers", Paul Graham annoyed the industry with the assertion that Java programmers aren't as smart as Python programmers. He made a lot of stupid Java programmers mad (did I say that?), causing a lot of them to write counterarguments on their websites. The violent reaction indicates that he touched a nerve.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;So if, purely for the sake of argument mind, I claimed that "Chad Fowler is a racist" (he's not) and he got really upset about it, his reaction is an indication that I am on to something? No, only if you are on the level of a tabloid journalist. If you come with a hurtful accusation and people get really upset, that is an indication you are being a dick.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5099452783517680285-8756869340556202267?l=larswestergren.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://larswestergren.blogspot.com/feeds/8756869340556202267/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5099452783517680285&amp;postID=8756869340556202267' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/8756869340556202267'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/8756869340556202267'/><link rel='alternate' type='text/html' href='http://larswestergren.blogspot.com/2009/08/pragmatic-argumentation.html' title='Pragmatic argumentation'/><author><name>Lars Westergren</name><uri>http://www.blogger.com/profile/02654687571384000146</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_18LJx0IKqk0/SNjXSniCg3I/AAAAAAAAAAM/xENi61UQNj8/s1600-R/larswestergren.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5099452783517680285.post-7660433746951264732</id><published>2009-05-03T20:55:00.003+02:00</published><updated>2009-05-03T21:01:27.002+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='declarative concurrency mozart deterministic threading'/><title type='text'>Notes on dataflow concurrency</title><content type='html'>&lt;p style="margin-bottom: 0in;"&gt;At a conference, I heard someone say something to the effect of: "Declarative dataflow concurrency is awesome. You can't get deadlocks! It all just works, and it is so beautiful".&lt;/p&gt;  &lt;p style="margin-bottom: 0in;"&gt;If you are unfamiliar with dataflow concurrency, it is a technique used in some languages, where a program, if it reaches a statement that requires the use of a variable which hasn't been assigned a value yet, pauses until the variable has been assigned by another thread and then continues the computation as if nothing had happened.&lt;/p&gt;  &lt;p style="margin-bottom: 0in;"&gt;It is pretty neat, but I thought to myself - "Hang on, if we have two threads that each wait for the other to assign a variable, won't we get a circular dependency between them? Or if there is just one executing thread, won't that block forever? I don't understand, that doesn't sound like much different from what I'm used to...?"&lt;/p&gt;  &lt;p style="margin-bottom: 0in;"&gt;Now a month later, I am currently reading the book &lt;a href="http://www.info.ucl.ac.be/%7Epvr/book.html"&gt;"Concepts, Techniques and Models of Computer Programming"&lt;/a&gt; by Ray and Haridi. And indeed, on page 48 they state:&lt;/p&gt;  &lt;p style="margin-bottom: 0in;"&gt;&lt;/p&gt;&lt;blockquote&gt;The computation models of this book use [dataflow programming]. This is unreasonable in a sequential system, since the program will wait forever. It is reasonable in a concurrent system, where it could be part of normal operation that some other thread binds the varialbe. [Dataflow programming] introduces a new kind of program error, namely a suspension that waits forever. For example, if a variable name is misspelled then it will never be bound. A good debugger should detect when this occurs.&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;  &lt;p style="margin-bottom: 0in;"&gt;So even if they wait on an infinitely unbound variable instead of lock that is never released, the experience for the user would appear to be much the same - a program that "hangs" without producing the desired result. I wrote this little snipped in Mozart to demonstrate:&lt;/p&gt;  &lt;p style="margin-bottom: 0in;"&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p style="margin-bottom: 0in;"&gt;declare&lt;/p&gt; &lt;p style="margin-bottom: 0in;"&gt;Y&lt;/p&gt; &lt;p style="margin-bottom: 0in;"&gt;X&lt;/p&gt; &lt;p style="margin-bottom: 0in;"&gt;thread X=Y+1 end&lt;/p&gt; &lt;p style="margin-bottom: 0in;"&gt;Y=X+1 end&lt;/p&gt; &lt;p style="margin-bottom: 0in;"&gt;{Browse X}&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="margin-bottom: 0in;"&gt;&lt;/p&gt; &lt;p style="margin-bottom: 0in;"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style="margin-bottom: 0in;"&gt;And indeed the browse window never appears. The main thread blocks on line 5, the spawned thread on line 4, each waiting for an unbound variable.&lt;/p&gt;  &lt;p style="margin-bottom: 0in;"&gt;But even though it hasn't been stated outright in the book (at least not yet, I'm at page 350), I think there is an important difference compared to threaded programs as they are usually written in, for instance, Java. The Mozart program is deterministic (if written in a completely declarative style). It will *always* block, no matter how the threads are scheduled, which makes this programming error easier to detect and (hopefully) to locate and fix.&lt;/p&gt;  &lt;p style="margin-bottom: 0in;"&gt;So what the person at the conference perhaps meant, was that the programs written in dataflow concurrency style don't have *race conditions*.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5099452783517680285-7660433746951264732?l=larswestergren.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://larswestergren.blogspot.com/feeds/7660433746951264732/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5099452783517680285&amp;postID=7660433746951264732' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/7660433746951264732'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/7660433746951264732'/><link rel='alternate' type='text/html' href='http://larswestergren.blogspot.com/2009/05/notes-on-dataflow-concurrency.html' title='Notes on dataflow concurrency'/><author><name>Lars Westergren</name><uri>http://www.blogger.com/profile/02654687571384000146</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_18LJx0IKqk0/SNjXSniCg3I/AAAAAAAAAAM/xENi61UQNj8/s1600-R/larswestergren.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5099452783517680285.post-8062015615329836094</id><published>2009-01-30T12:58:00.004+01:00</published><updated>2009-01-30T13:23:30.648+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux adept dpgk apt-get update problems'/><title type='text'>Adept updater crash</title><content type='html'>I had been hoping to blog more about programming stuff, but here has been lots of &lt;a href="http://en.wiktionary.org/wiki/yak_shaving"&gt;"yak shaving"&lt;/a&gt; activities for me lately. Linux is still a hairy beast, even if things are slowly getting better. And here is another one!&lt;br /&gt;&lt;br /&gt;The "Adept updater tool" in KDE, which has a little icon in the systray informing you when important updates are unavailable, is light-years better than the default behavior of the Windows Update tool in Vista -&lt;br /&gt;&lt;br /&gt;("I have downloaded updates and will restart now, shutting down your programs". "I am configuring updates, you may not turn off your computer right now.", "Now I'm going to restart your computer again". "This is a blue screen of death" "Could not start Windows. Would you like to try to restore your computer to last known working configuration?" No joke, this happens to me with SP1 for Vista, can't install it on my Dell laptop)&lt;br /&gt;&lt;br /&gt;- but Adept is not completely bug- or annoyance-free either. Yesterday when downloading a new Linux kernel to my Kubuntu system, my update progress stopped suddenly. A command line style menu window had popped up asking if I wanted to keep my old locally changed grub conf file, or replace it with a new one. While Adept could show the menu to me if I went to the "details" tab, it could not process any input from me and transmit it to the install script, so I had to kill the Adept process.&lt;br /&gt;&lt;br /&gt;Next time I tried to restart Adept, it said the update database was locked because another program was using it. This is the solution to this problem (most of it curtesy of "harleqinguy" at &lt;a href="http://www.linuxquestions.org/questions/linux-newbie-8/database-locked-adept-updater-575761/"&gt;Linuxquestions.org&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;sudo rm /var/lib/dpkg/lock&lt;br /&gt;&lt;/span&gt;Removes lock file - only do if you are sure all programs which may access the update db are terminated, but the lock still remains.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;sudo dpkg --configure -a&lt;br /&gt;&lt;/span&gt;Reconfigures downloaded but not yet installed update packages, and backs up configuration files. Mainly to test if you can run update tools, and to try to fix any configuration mistakes you may have done&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Now you can restart Adept, but trying to update your system through it will only lead to the same issues again, to get by this problem and get your shiny new kernel installed, go to your trusty command line and run&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;sudo apt-get upgrade&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5099452783517680285-8062015615329836094?l=larswestergren.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://larswestergren.blogspot.com/feeds/8062015615329836094/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5099452783517680285&amp;postID=8062015615329836094' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/8062015615329836094'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/8062015615329836094'/><link rel='alternate' type='text/html' href='http://larswestergren.blogspot.com/2009/01/adept-updater-crash.html' title='Adept updater crash'/><author><name>Lars Westergren</name><uri>http://www.blogger.com/profile/02654687571384000146</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_18LJx0IKqk0/SNjXSniCg3I/AAAAAAAAAAM/xENi61UQNj8/s1600-R/larswestergren.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5099452783517680285.post-2467967118594055609</id><published>2009-01-29T14:24:00.005+01:00</published><updated>2009-01-29T14:31:17.171+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='KDE Linux usability sound'/><title type='text'>KDE login jingle</title><content type='html'>To turn off the annoying KDE login/logout jingles (which doesn't respect your sound settings and plays loudly when you are at the library, at a lecture, a conference, next to someone asleep, etc, unless you remembered to have headphones plugged in):&lt;br /&gt;&lt;br /&gt;Go to the KDE system settings program, click "Notifications" icon, "System notifications", "Applications" tab, select "KDE Systems notification" in dropdown menu, then select "login", then uncheck the "Play a sound" checkbox.&lt;br /&gt;&lt;br /&gt;Done. Whew. They hid that pretty well.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5099452783517680285-2467967118594055609?l=larswestergren.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://larswestergren.blogspot.com/feeds/2467967118594055609/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5099452783517680285&amp;postID=2467967118594055609' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/2467967118594055609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/2467967118594055609'/><link rel='alternate' type='text/html' href='http://larswestergren.blogspot.com/2009/01/kde-login-jingle.html' title='KDE login jingle'/><author><name>Lars Westergren</name><uri>http://www.blogger.com/profile/02654687571384000146</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_18LJx0IKqk0/SNjXSniCg3I/AAAAAAAAAAM/xENi61UQNj8/s1600-R/larswestergren.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5099452783517680285.post-1904583931464448923</id><published>2009-01-25T20:30:00.006+01:00</published><updated>2009-01-26T20:08:16.453+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux wine mount umount cd drive'/><title type='text'>Wine eject cd/dvd problem solved</title><content type='html'>A problem that has popped up for me several times and whose solution can be hard to find when Googling -&lt;br /&gt;&lt;br /&gt;If you are trying to install a Windows game or application on Linux with Wine, always start the command from "outside" the cd.&lt;br /&gt;I.e. - always DO write &lt;span style="font-weight: bold;"&gt;wine /media/cdrom/setup.exe&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;Do NOT write&lt;br /&gt;&lt;strike&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;cd /media/cdrom&lt;br /&gt;wine setup.exe&lt;br /&gt;&lt;/span&gt;&lt;/strike&gt;&lt;br /&gt;If you are promted to insert the next disc, but Linux won't let you do the unmount command because "device or resource is busy" - try&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;wine eject d:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;If all else fails, copy the whole disc to hard drive and run from there.&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5099452783517680285-1904583931464448923?l=larswestergren.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://larswestergren.blogspot.com/feeds/1904583931464448923/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5099452783517680285&amp;postID=1904583931464448923' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/1904583931464448923'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/1904583931464448923'/><link rel='alternate' type='text/html' href='http://larswestergren.blogspot.com/2009/01/wine-eject-cddvd-problem-solved.html' title='Wine eject cd/dvd problem solved'/><author><name>Lars Westergren</name><uri>http://www.blogger.com/profile/02654687571384000146</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_18LJx0IKqk0/SNjXSniCg3I/AAAAAAAAAAM/xENi61UQNj8/s1600-R/larswestergren.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5099452783517680285.post-5801389686458682379</id><published>2008-12-08T13:10:00.004+01:00</published><updated>2008-12-08T14:15:07.086+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='interview questions programming work satisfaction stress'/><title type='text'>Questions to ask employers</title><content type='html'>After thoroughly grilling the applicant for a job/project, many interviews often end with the question - "So, do you have any questions for us?" I've read in articles by career coaches that it is a good idea to have a few questions to ask here - it shows that you are interested. But the first times I had problems coming up with any sincere and interesting questions.&lt;br /&gt;&lt;br /&gt;After being at a number of different programming jobs now, big and small, I've come up with a list of questions. Some of these I intend to ask next time I'm in that situation. Not all of these questions require a "yes" answer from me, but at least that they know what these items are and can reason around them. If they answer "We don't know what these things are!", or "Yeah, yeah, I'm sure that's great stuff, but we don't have time for that sort of academic stuff, we have urgent deadlines to meet" that will be a strong warning signal to me to reconsider, or at least ask for decent pay to make up for the inevitable stress...&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Do you use a version control system for your code? Which?&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Do you use a continuous integration system? Which?&lt;/li&gt;&lt;li&gt;Development processes - none, Scrum, RUP, agile...? Would you say you follow them closely, or do you have you cherry-picked a subset of practices from them that you like/have found to work well for you?&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Do you have an internal Wiki? Does anyone use it for project documentation, or do you generally use Word/PowerPoint/Excel files instead?&lt;br /&gt;&lt;/li&gt;&lt;li&gt;How do you handle incidents? Do you use a standard process such as ITIL or have you made your own? Either way, how do you integrate incident handling in development? Separate teams, or...? Branch the source often, or...?&lt;br /&gt;&lt;/li&gt;&lt;li&gt;How do you get things deployment ready and how do you deploy, are there many manual steps involved?&lt;/li&gt;&lt;li&gt;How are your enviroments set up, do you have separate environments for development, dev testing, integration, prod-test, production? (Or do they have a variant of the dreaded &lt;a href="http://thedailywtf.com/Articles/The_Developmestuction_Environment.aspx"&gt;developmestuction&lt;/a&gt; environment?)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Very rough estimate, on a scale from say 1 to 5, how pleased are you with the unit test coverage of your codebase? Ever used any test coverage tools to check?&lt;/li&gt;&lt;li&gt;Has your team been required to do any all-nighters (or late-evenings) last year because of critical deadlines or major incidents? How many?&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Do you use any code-quality checking tools such as Findbugs?&lt;/li&gt;&lt;li&gt;Are employees allowed to use work time to improve their skills? How do you handle that - do you decide what they should study, or is that up to them? Ever arrange any lectures, study groups or anything like that internally in the company? Are employees encourged to head these, or do you hire external people to lecture?&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Feedback appreciated. What are your suggested questions?&lt;br /&gt;&lt;br /&gt;Update - two good suggestions from&lt;a href="http://www.drmaciver.com/"&gt; David R. MacIver&lt;/a&gt; via Twitter:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="entry-content"&gt;Can you give me a coding sample? :-)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="entry-content"&gt;I also like to give them slightly bizarre questions like "Tell me why I wouldn't want to work here".&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5099452783517680285-5801389686458682379?l=larswestergren.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://larswestergren.blogspot.com/feeds/5801389686458682379/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5099452783517680285&amp;postID=5801389686458682379' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/5801389686458682379'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/5801389686458682379'/><link rel='alternate' type='text/html' href='http://larswestergren.blogspot.com/2008/12/questions-to-ask-employers.html' title='Questions to ask employers'/><author><name>Lars Westergren</name><uri>http://www.blogger.com/profile/02654687571384000146</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_18LJx0IKqk0/SNjXSniCg3I/AAAAAAAAAAM/xENi61UQNj8/s1600-R/larswestergren.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5099452783517680285.post-7864725584422288148</id><published>2008-06-19T13:30:00.017+02:00</published><updated>2008-07-07T13:40:01.163+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='management programming repository agile'/><title type='text'>Delete the obsolete</title><content type='html'>A week ago I was in the unenviable situation of having to dig through a large number of legacy apps and libraries in Java, C and VB to find references to a database attribute that was going to be retired. Examining just one file took a long time, since a file containing a dangerous reference might have been imported as a helper lib in other projects - and to make things worse, I couldn't immediately see if these projects were obsolete or not.&lt;br /&gt;&lt;br /&gt;In my current project, my fellow employees have a very good overview of which systems are used where, and which versions are deployed, so when I am unsure I can always ask them. However, had they quit and taken that knowledge with them, I would have faced a combinatorial explosion of repository source versions, deployed versions, and production environments that would have made my task impossible; not just very hard and time-consuming as it was now.&lt;br /&gt;&lt;br /&gt;For clarity and maintainability, if a system is obsolete you should always at the &lt;span style="font-weight: bold;"&gt;very minimum&lt;/span&gt; comment database tables, tag repositories and check in README files to the repositories that clearly show that these things are no longer used. Even better would be to move the data to separate "graveyard" branches/databases. I think the best of all would be to delete the obsolete files, since you can always reconstruct them from the repositories and backups in the extremely unlikely case that you would need them again. I understand if some people are reluctant to do that, the human urge to hang on to things  "just in case" is strong.&lt;br /&gt;&lt;br /&gt;It is a project management anti-pattern to keep obsolete projects and modules in your source repositories, and obsolete database tables on your servers. You will soon accumulate a &lt;a href="http://www.martinfowler.com/bliki/TechnicalDebt.html"&gt;technical debt&lt;/a&gt; which, like the debts in your bank accounts, will keep growing over time. Keeping track of possible dependencies between systems and components becomes progressively harder, and it will becomes increasingly difficult for new developers to get an overview of the architecture. More and more valuable development time will be spent on "the debt" instead of useful tasks. Developers will not have the courage to refactor, and this will feed the negative habits of adding stuff but never removing - not very agile.&lt;br /&gt;&lt;br /&gt;Luckily the managers at my current company have been convinced to set aside developer time during the summer to clean up the source repository and move obsolete code to a separate view. At this particular company, I won't have the tedious task of searching through obsolete code again. For all our sakes, I urge you to do the same. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5099452783517680285-7864725584422288148?l=larswestergren.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://larswestergren.blogspot.com/feeds/7864725584422288148/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5099452783517680285&amp;postID=7864725584422288148' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/7864725584422288148'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/7864725584422288148'/><link rel='alternate' type='text/html' href='http://larswestergren.blogspot.com/2008/06/delete-obsolete.html' title='Delete the obsolete'/><author><name>Lars Westergren</name><uri>http://www.blogger.com/profile/02654687571384000146</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_18LJx0IKqk0/SNjXSniCg3I/AAAAAAAAAAM/xENi61UQNj8/s1600-R/larswestergren.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5099452783517680285.post-6420375636496286240</id><published>2008-06-16T11:50:00.004+02:00</published><updated>2008-06-16T12:44:36.221+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile clear case hudson continuous integration plugin howto'/><title type='text'>Hudson and ClearCase</title><content type='html'>If you want your company to be more agile and want to install a Continuous Integration system, but are stuck on Clear Case, here is a little howto. I am normally a Linux/Unix boy, but Windows was mandated.&lt;br /&gt;&lt;br /&gt;Download and install a servlet container such as &lt;a href="http://tomcat.apache.org/"&gt;Tomcat&lt;/a&gt;. Secondly, download the &lt;a href="https://hudson.dev.java.net/"&gt;Hudson&lt;/a&gt; war file. You can (should) define a HUDSON_HOME environment variable. Start Tomcat, deploy the Hudson war to the webapps dir, the "jobs" and "plugins" directories should be created in your HUDSON_HOME directory.&lt;br /&gt;&lt;br /&gt;Either use the builtin plugin manager page, or if like me you can't get it to work, download &lt;a href="https://hudson.dev.java.net/servlets/ProjectDocumentList?folderID=8040&amp;amp;expandFolder=8040&amp;amp;folderID=5818"&gt;the Clear Case plugin manually&lt;/a&gt; and put it in the HUDSON_HOME/plugin directory and restart Tomcat.&lt;br /&gt;&lt;br /&gt;Go to http://localhost:8080/hudson/ and choose "Manage Hudson" -&gt; "Configure System". Configure the Cleartool executable home (usually c:\program files\rational\clearcase\bin\cleartool), and other tools/services you might use for your projects (Ant, Maven, SMTP server etc)&lt;br /&gt;&lt;br /&gt;Select "New job" -&gt; "Build a free-style software project" and select a name, press "ok".&lt;br /&gt;&lt;br /&gt;How to configure stuff here depends on how your Clear Case administrator has set up your system, but this is what worked for me.&lt;br /&gt;Select the "UCM ClearCase" radio button and configure the following fields:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;View name&lt;/span&gt; - select a new unique view name, for instance "hudson_myproject". This is the view that Hudson will create for you.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Stream selector&lt;/span&gt; - this is very project dependent, this is how I figured out my stream name: If you have the ClearCase Explorer tool, select "Toolbox" tab -&gt; "UCM" dropdown -&gt; "Join project" link -&gt; select your project -&gt; "Properties" button. Now directly under the project name you see a string somewhat like the following:&lt;br /&gt;project:myproject_1.0@\servername&lt;br /&gt;Then the following should be your stream name:&lt;br /&gt;myproject_1.0@\servername&lt;br /&gt;If you have checked out a project view before with CC Explorer manually to the default drive (usually M:)  you can go to M: with Windows Explorer and rightclick on the directory there and select ClearCase tab, then properties. You should be able to get the Stream string from there too.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Load rules&lt;/span&gt; - Backslash + the path to a VOB (database file containing the project) just under the root of the project view. Again, if you have previously created a view using ClearCase explorer and mapped it to drive M:, go to M: and open the view directory there. Select one of the subdirs there as your "load rule". For example, I had&lt;br /&gt;M:\myproject\src&lt;br /&gt;so my "load rule" became&lt;br /&gt;\src&lt;br /&gt;&lt;br /&gt;Now press "advanced" button in Hudson config, and configure the following:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Additional mkview arguments&lt;/span&gt; - Here I had to use the -vws  parameter to the &lt;a href="http://www.ipnom.com/ClearCase-Commands/mkview.html"&gt;mkview&lt;/a&gt; command, plus a UNC name. Something like this:&lt;br /&gt;-vws \\companynetwork\clearcaseviewsserver\AD\myusername\&lt;br /&gt;This is where Hudson will create the view directory, but the source itself will be checked out to, and built from, your HUDSON_HOME/jobs/jobname/builds/ directories.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5099452783517680285-6420375636496286240?l=larswestergren.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://larswestergren.blogspot.com/feeds/6420375636496286240/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5099452783517680285&amp;postID=6420375636496286240' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/6420375636496286240'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/6420375636496286240'/><link rel='alternate' type='text/html' href='http://larswestergren.blogspot.com/2008/06/hudson-and-clearcase.html' title='Hudson and ClearCase'/><author><name>Lars Westergren</name><uri>http://www.blogger.com/profile/02654687571384000146</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_18LJx0IKqk0/SNjXSniCg3I/AAAAAAAAAAM/xENi61UQNj8/s1600-R/larswestergren.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5099452783517680285.post-7585981694711307085</id><published>2008-05-14T14:42:00.005+02:00</published><updated>2008-05-16T14:53:31.093+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java design scala type inference language'/><title type='text'>Type inference thoughts</title><content type='html'>I have been wondering about one thing and throw out this question just in case someone possibly reads my blog - does type inference bring any benefits apart from less typing?&lt;br /&gt;&lt;br /&gt;I know proponents of dynamic typing consider declaring variable types "noise" because it is the antithesis of their style of coding, and they say the compiler can usually infer the type for you anyway. Scala for instance is designed this way:&lt;br /&gt;&lt;br /&gt;var x = "Hello"&lt;br /&gt;&lt;br /&gt;The compiler will infer that x is of type String. You can reassign it (just like you can in Java) to a new String, but if you try to reassign an object which is not a String compile will fail.&lt;br /&gt;&lt;br /&gt;Map&amp;lt;Integer, Office&amp;gt; offMap = ....&lt;br /&gt;for instance, is more to type, that is true. In my opinion that can be an acceptable tradeoff. If I have the code in an IDE mouseover could tell me the return type of the right hand side method, true, but I often look at code through other interfaces than an IDE (online, books, a shell). Note that I'm not saying I think type inference is bad... sometimes it is a relief. But I don't think it is terrible that Java lacks it, either. For me it is just a matter of style.&lt;br /&gt;&lt;br /&gt;But just in case I have missed anything, my question is again: does type inference bring any other possible benefits? Compiler optimization...?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5099452783517680285-7585981694711307085?l=larswestergren.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://larswestergren.blogspot.com/feeds/7585981694711307085/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5099452783517680285&amp;postID=7585981694711307085' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/7585981694711307085'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/7585981694711307085'/><link rel='alternate' type='text/html' href='http://larswestergren.blogspot.com/2008/05/type-inference-thoughts.html' title='Type inference thoughts'/><author><name>Lars Westergren</name><uri>http://www.blogger.com/profile/02654687571384000146</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_18LJx0IKqk0/SNjXSniCg3I/AAAAAAAAAAM/xENi61UQNj8/s1600-R/larswestergren.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5099452783517680285.post-1726311267706464743</id><published>2008-04-22T16:12:00.011+02:00</published><updated>2008-04-28T14:27:48.095+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mobilt bredband hardy heron tre 3 huawei kubuntu linux networking wireless e220 trådlöst nätverk mobile broadband'/><title type='text'>Mobilt bredband med Kubuntu Linux, Tre och Huawei E220</title><content type='html'>Enklaste sättet att få mobilt bredband från 3 med Huawei E220 ("ovala pucken") att fungera under Kubuntu Linux:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Ladda ner och installera Vodafone Mobile Connect Card driver&lt;/li&gt;&lt;li&gt;Plugga in modemet med singelsladden (sladden med dubbla USB pluggar är för datorer med USB portar som inte ger tillräckligt med ström tydligen, men för mig fungerade det inte bra med den sladden) och vänta några sekunder. Om allt är ok ska du se följande rad i dmesg: "GSM modem (1-port) converter now attached to ttyUSB0". Du kan få en hel radda ttyUSB kopplingar, men det gör inget.&lt;/li&gt;&lt;li&gt;Starta Vodafone klienten, den bör detektera modemet, du får skriva in den PIN kod som kom med SIM kortet. Skriv i ett fejkat användarnamn och lösenord (typ "username" och "password"). Dessa MÅSTE vara med även fast de inte används, annars blir det fel när du kopplar upp dig.... Skriv i bredband.tre.se i fältet "APN".&lt;/li&gt;&lt;li&gt;Om du stavat fel någonstans i de tre fälten ovan måste du radera profilen och skapa en ny, eftersom en bugg (i alla fall i Beta 2 versionen som jag använder) gör att ändringar gjorda i "edit" mode inte sparas korrekt.&lt;/li&gt;&lt;li&gt;Klienten fungerar även bra efter uppgradering till Kubuntu 8.04, men du måste då lägga till "airprime" modulen i /etc/modprobe.d/blacklist filen, då dom drivrutinerna försöker ta över modemet men misslyckas. Du måste också antagligen radera din dolda katalog med inställningar (.vmc2) i hemkatalogen.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5099452783517680285-1726311267706464743?l=larswestergren.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://larswestergren.blogspot.com/feeds/1726311267706464743/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5099452783517680285&amp;postID=1726311267706464743' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/1726311267706464743'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/1726311267706464743'/><link rel='alternate' type='text/html' href='http://larswestergren.blogspot.com/2008/04/mobilt-bredband-med-kubuntu-linux-tre.html' title='Mobilt bredband med Kubuntu Linux, Tre och Huawei E220'/><author><name>Lars Westergren</name><uri>http://www.blogger.com/profile/02654687571384000146</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_18LJx0IKqk0/SNjXSniCg3I/AAAAAAAAAAM/xENi61UQNj8/s1600-R/larswestergren.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5099452783517680285.post-4682320156354471667</id><published>2008-01-15T10:18:00.000+01:00</published><updated>2008-01-15T10:21:24.593+01:00</updated><title type='text'>Facebook scepticism</title><content type='html'>&lt;a href="http://www.guardian.co.uk/technology/2008/jan/14/facebook"&gt;Interesting read&lt;/a&gt;....&lt;br /&gt;&lt;br /&gt;The only REALLY useful thing I personally get out of Facebook is an easy place to look up contact information of friends, and seeing what my friends are reading. But I agree with the article -  you can only add books that you can buy from large US companies such as Amazon. You can't add books from Swedish bookstores for instance, or classics that are out of print... nor can you add open source games, or games bought online.&lt;br /&gt;&lt;br /&gt;Facebook is not the product, YOU are the product, and you are being sold to the real customers - the advertisers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5099452783517680285-4682320156354471667?l=larswestergren.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://larswestergren.blogspot.com/feeds/4682320156354471667/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5099452783517680285&amp;postID=4682320156354471667' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/4682320156354471667'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/4682320156354471667'/><link rel='alternate' type='text/html' href='http://larswestergren.blogspot.com/2008/01/facebook-scepticism.html' title='Facebook scepticism'/><author><name>Lars Westergren</name><uri>http://www.blogger.com/profile/02654687571384000146</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_18LJx0IKqk0/SNjXSniCg3I/AAAAAAAAAAM/xENi61UQNj8/s1600-R/larswestergren.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5099452783517680285.post-1444810171925946378</id><published>2007-12-30T18:09:00.000+01:00</published><updated>2007-12-30T19:59:54.086+01:00</updated><title type='text'>Blogger.com online editing is awful</title><content type='html'>I have just spend some VERY frustrating days fighting with Blogspot/Bloggers online editing, as I was finishing my "Guide to OpenJDK" article. Avoid using the "a name" tag at all cost, it is normally used to create internal links to chapters in a webpage. When you switch to the preview or compose page, Blogger scripts automatically duplicate this tag EVERYWHERE throughout the text for some bloody reason. Before header tags, inside header tags, after header tags, before links, before images, before every paragraph, before lists, inside every list item.... You will have to spend hours removing them... and if you miss one, like I did, it will metatasize like a cancer all over your text if you switch editing mode again! Fun!!&lt;br /&gt;&lt;br /&gt;Also it doesn't save your original hand edited HTML. If you use the "lesser than"/"greater than" html elements to show, for instance, an email address, when you go to compose window everything looks ok, but when you switch back to editing html it will try to parse what is inside the "tag" characters, fail and delete your text.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5099452783517680285-1444810171925946378?l=larswestergren.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://larswestergren.blogspot.com/feeds/1444810171925946378/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5099452783517680285&amp;postID=1444810171925946378' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/1444810171925946378'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/1444810171925946378'/><link rel='alternate' type='text/html' href='http://larswestergren.blogspot.com/2007/12/bloggercom-online-editing-is-awful.html' title='Blogger.com online editing is awful'/><author><name>Lars Westergren</name><uri>http://www.blogger.com/profile/02654687571384000146</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_18LJx0IKqk0/SNjXSniCg3I/AAAAAAAAAAM/xENi61UQNj8/s1600-R/larswestergren.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5099452783517680285.post-8547235056056319496</id><published>2007-12-28T09:00:00.002+01:00</published><updated>2008-05-08T13:38:08.413+02:00</updated><title type='text'>The LG DBRH198</title><content type='html'>Our Samsung digital TV decoder broke down recently, and when looking for a replacement I found the LG DBRH198 - a combined DVD/CD/DivX/WM/jpg player, digital decoder, cd/dvd burner and 120GB media recorder. After spending a very frustrating day and a half trying to get it to work, I am now returning it.&lt;br /&gt;&lt;br /&gt;Pros:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Would have replaced four machines (VHS, DVD, CD, decoder) with one, if it had worked. Compact living, and saves energy!&lt;/li&gt;&lt;li&gt;Image was sharp, at least on our small LCD TV.&lt;/li&gt;&lt;/ul&gt;Cons:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Refused to read our Boxer smartcard connected through a CAD adapter, only the free channels worked.&lt;/li&gt;&lt;li&gt;Text TV fonts were ugly, an eyestrain to read.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;When going through menus it kept "locking up" randomly so we had to pull the plug repeatedly.&lt;/li&gt;&lt;li&gt;If we accidentally pushed the AV button on the remote we lost the decoder image. It got to AV4 and then refused to cycle back to the beginning no matter what buttons we pushed and we had to do a "reset to factory settings" to get it to read from AV1 (antenna) again. Perhaps there is a better way, but the manual didn't say. I don't know if this is a bug or just really poor user interface design&lt;/li&gt;&lt;li&gt;Poor interface design in general. We are two engineers in the household, and if we were having problems finding out how the menus work... not a good present for grandma.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Poorly translated menus. Unlike some machines I've owned, this time it wasn't so bad that it made understanding difficult, but it was still distracting. Manual was ok though.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Felt slow and sluggish - slow on startup, slow to change channels, slow to read the DVDs.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;We could not get sound to work through the decoder. It generally worked when playing DVDs (see below), and once we stumbled into playing back a recording from the hard drive and then it worked, but we never got it to work when watching TV directly through the decoder for some reason. Perhaps there was some setting hidden somewhere, or we should have used another audio cable, but this is something I think should just work out of the box and not something you have to fiddle around with for hours trying to get to work.&lt;/li&gt;&lt;li&gt;Once when playing a DVD the sound was suddenly just roaring white noise. The same DVD had worked fine 10 minutes before on the same machine...&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Previously I have been pleased with LG products. Certainly not high-end stuff, but cheap, fairly robust and lots of features. Seems this machine had too many features crammed into it and not enough quality. I think I'll try to replace it with one really good decoder with build in HD recording, and one really good DVD player. Probably not LG this time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5099452783517680285-8547235056056319496?l=larswestergren.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://larswestergren.blogspot.com/feeds/8547235056056319496/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5099452783517680285&amp;postID=8547235056056319496' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/8547235056056319496'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/8547235056056319496'/><link rel='alternate' type='text/html' href='http://larswestergren.blogspot.com/2007/12/lg-dbhr198.html' title='The LG DBRH198'/><author><name>Lars Westergren</name><uri>http://www.blogger.com/profile/02654687571384000146</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_18LJx0IKqk0/SNjXSniCg3I/AAAAAAAAAAM/xENi61UQNj8/s1600-R/larswestergren.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5099452783517680285.post-7774555895042201193</id><published>2007-12-12T13:01:00.001+01:00</published><updated>2008-02-17T21:39:38.917+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java openjdk opensource howto'/><title type='text'>Beginners guide to OpenJDK contributing</title><content type='html'>&lt;h3&gt;**DEPRECATED**&lt;/h3&gt;&lt;br /&gt;There is now an &lt;a href="http://openjdk.java.net/guide/"&gt;official OpenJDK Developer guide&lt;/a&gt; which incidentally appeared two days after this article was noticed on the java.net frontpage.&lt;br /&gt;:)&lt;br /&gt;&lt;br /&gt;You should go there for up to date information instead. Thanks to Brad Whetmore for useful feedback though, and getting this article noticed by mentioning it on his blog.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;**DEPRECATED**&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This is an expanded version of a presentation I held at &lt;a href="http://www.javaforum.se/"&gt;Javaforum&lt;/a&gt; Stockholm in December 2007. It is intended as a quick "getting started" guide for those who wish to participate in the OpenJDK project. All the information was already out there, but spread over many different sites and I thought it needed summing up in one place so beginners could see step by step what they need to do to get a patch accepted. A warning - as the OpenJDK project changes quickly the information here may be out of date. Comments, feedback or errata is much appreciated. The article is published under the &lt;a href="http://creativecommons.org/"&gt;Creative Commons&lt;/a&gt;.&lt;br /&gt;&lt;h3&gt;Contents&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;What is OpenJDK&lt;/li&gt;&lt;li&gt;Why contribute?&lt;/li&gt;&lt;li&gt;Who are in charge?&lt;/li&gt;&lt;li&gt;Organization - Groups and Projects&lt;/li&gt;&lt;li&gt;Getting the code&lt;/li&gt;&lt;li&gt;Preparing for the build&lt;br /&gt;&lt;/li&gt;&lt;li&gt;How to build&lt;/li&gt;&lt;li&gt;Short code overview&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Contributor agreement&lt;/li&gt;&lt;li&gt;Testing your changes&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Unit/regression tests&lt;/li&gt;&lt;li&gt;Committing patches&lt;/li&gt;&lt;li&gt;Making a good patch&lt;/li&gt;&lt;li&gt;What I would like to see&lt;/li&gt;&lt;li&gt;Links&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;What is OpenJDK&lt;/h3&gt;OpenJDK is the project to open source the development of the Java platform and virtual machine. Java has always been free to download and use, and the source has been available under the Java Research Licence. Now it is also available under a Free Software Foundation approved licence - GNU General Public Licence 2 with Classpath exception. This is not a separate project to Sun's "ordinary" Java. It is not a "ok kids, go play with this and don't bother us anymore" abandonware - the engineers at Sun will use the organization and tools described here exactly like external contributors do, and this source will be the base for the release of Java 7 and future releases as well as possible alternative distributions.&lt;br /&gt;&lt;br /&gt;Note that the OpenJDK project is only for collaboration around the &lt;span style="font-weight: bold;"&gt;implementation&lt;/span&gt; of the Java platform. The specification is still being decided by the &lt;a href="http://jcp.org/en/home/index"&gt;Java Community Process&lt;/a&gt;, which you really should join incidentally... free for individual members, you get to vote about once a year about who will be in the expert groups that decide the future of the platform.&lt;br /&gt;&lt;h3&gt;Why contribute&lt;/h3&gt;Why should you waste valuable time contributing to open source when you don't get paid for it? Here are the reasons I have to do that:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Increase your competence as a programmer. Perhaps you have a few hours a week at work dedicated to increasing your competence? Gaining a better understanding of the JVM and seeing how common algorithms are implemented is a pretty good way to do that.&lt;/li&gt;&lt;li&gt;You increase the value of your chosen platform. You make it more likely that there are good jobs for you in the future. Considering how much stuff have been written in Java the last 10 years I don't think there will be any lack of jobs for competent Java programmers for as long as I live, but perhaps you want some new development in the future, not just maintenance programming.&lt;/li&gt;&lt;li&gt;Make new contacts. When I was at JavaOne this year people at Sun who work in the management/JMX areas recognized my name when I came up and talked to them because I had submitted a couple of patches in that area.&lt;/li&gt;&lt;li&gt;It is an excellent merit. You have code that you are legally allowed to show to potential employers.  This is not just a little open source project that you and your closest friends use - if you submit patches to Java (or Linux), your code will be used in critical applications by  tens - make that HUNDREDS of millions of end users daily.&lt;/li&gt;&lt;li&gt;If you have a reoccuring bug that you have had to do an annoying workaround for - here is your chance to get rid of it permanently, not just for yourself but for all programmers around the world.&lt;/li&gt;&lt;li&gt;You will contribute to a more free and better society. Ok, I realize we are getting dangerously close to starry-eyed idealim territory here, but knowledge is power in today's world and computers are our primary knowledge-management tool. Therefore I think it is unwise to allow all control of our computers to fall to any singular entity, be it a state or a few large companies.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Who are in charge&lt;/h3&gt;Currently there is a "interim governance board" which I believe was selected by Sun, with help from the open source community. They will write a constitution and decide the final form the project will take. The members are:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.webmink.net/"&gt;Simon Phipps&lt;/a&gt; - Sun Chief Open Source Officer &lt;a href="http://linuxformat.co.uk/blog/wp-content/phipps.jpg"&gt;(Image) &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://wiki.java.net/bin/view/People/FabianeNardon"&gt;Fabiane Biznella Nardon &lt;/a&gt;– CTO of the company ZILICS. &lt;a href="http://www.tridedalo.com.br/fabiane/images/fabianenardon.jpg"&gt;(Image) &lt;/a&gt;. She is also the JavaTools community leader&lt;/li&gt;&lt;li&gt;&lt;a href="http://robilad.livejournal.com/"&gt;Dalibor Topič &lt;/a&gt; - Max Planck Institute. Well known for his work with Kaffe and Classpath.&lt;a href="http://blogs.sun.com/barton808/resource/J1panel1Sharp.JPG"&gt;(Image - center)&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href="http://g.oswego.edu/"&gt;Prof. Doug Lea &lt;/a&gt; - State University New York. &lt;a href="http://www.jcp.org/images/press/memberFocus/ec/doug_lea.jpg"&gt;(Image) &lt;/a&gt;Well known for his work on Java concurrency - author of several books, and the java.util.concurrent libraries introduced with Java 5, expanded and improved in Java 6 (and likely Java 7, with the forkJoin library).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.sun.com/mr/"&gt;Mark Reinhold &lt;/a&gt; - Sun JavaSE Chief Engineer &lt;a href="http://java.sun.com/developer/technicalArticles/Interviews/images/mreinhold.jpg"&gt;(Image)&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Organization - Groups and Projects&lt;/h3&gt;OpenJDK has two main concepts - Groups and Projects. I think this could be changed in the future by the governance board in theory, but I doubt that will happen. Groups and projects are described on the &lt;a href="http://openjdk.java.net/"&gt;official OpenJDK&lt;/a&gt; site, but here is a brief summary:&lt;h3&gt;Groups&lt;/h3&gt;A group is a collection of people with a common interest. There are three levels of participation: 1. Participant 2. Member 3. Moderator. A participant is anyone who has subscribed to the group mailing list. A Member is someone who "has demonstrated a history of significant contributions to a Group, has been granted Membership by that Group, and has signed the SCA" (more on the SCA later). A Moderator looks after the mailing list, counts votes etc.&lt;br /&gt;&lt;br /&gt;Groups usually have web pages describing them and mailing lists for discussions, but they DON'T have code repositories. A group can chose to sponsor a project. The initial groups were more or less the engineering teams at Sun - Java2D, Security, Hotspot, etc. Any group Member can suggest new groups. An examples of this is Dalibor Topič's &lt;a href="http://thread.gmane.org/gmane.comp.java.openjdk.general/630"&gt;Porters group suggestion&lt;/a&gt; which was approved just a few weeks ago.&lt;h3&gt;Projects&lt;/h3&gt;Projects exist to create some form of "artifact" (code, documentation). Projects, unlike groups, do not have member lists, they are open to all who want to contribute. Projects often have code repositories, and are often limited in time. A new project is formed if a group decides it wants to sponsor it. An example of this is the &lt;a href="http://article.gmane.org/gmane.comp.java.openjdk.general/705"&gt;JDK7 project&lt;/a&gt; proposed by Mark Reinhold.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Getting the code&lt;/h3&gt;&lt;p&gt;The Java source code was previously available as a read-only Subversion repository, but the project has now moved to&lt;a href="http://www.selenic.com/mercurial/wiki/"&gt;Mercurial (hg)&lt;/a&gt;. Mercurial is a distributed version control system. If you can read the repository, you can create a local clone - indeed, that is what you must do to work with it. Doing experimental forks of the code is therefore trivial, and it is hoped that increased local influence creates happier participants and a decreased risk of permanent "political" forks. If you haven't worked with Mercurial before, the greatest difference to svn/cvs is that you always have a local clone of the repository to work against, and that downloading patches and applying patches are two separate steps (unlike svn/cvs "update" command).&lt;/p&gt;Once you have downloaded it, "hg help" is your first command. There is a plugin in Netbeans (and in Eclipse too I'm sure) but the original program is run from the command line so I recommend you try it out that way first, to get a feel for all that is possible. A short list of useful commands -&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;hg clone ${localpath_or_url} - create a local copy of a repository&lt;/li&gt;&lt;li&gt;hg status - how do your work files diff against your local repository?&lt;/li&gt;&lt;li&gt;hg commit - save work file changes to local repository&lt;/li&gt;&lt;li&gt;hg incoming - what has changed in parent repository (the one you cloned from)&lt;/li&gt;&lt;li&gt;hg pull - download remote patches. Again, this step does not apply them.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;hg update - apply downloaded patches&lt;/li&gt;&lt;li&gt;hg push - send your changes to the parent repository (if you have write permission there)&lt;/li&gt;&lt;li&gt;hg merge - merge changes, best done with a tool (kdiff3, meld, Netbeans, Eclipse)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;All of these commands take lots of different parameters of course, but rather than me repeating it, there is a really good free book available on Mercurial &lt;a href="http://hgbook.red-bean.com/"&gt;at red-bean.com&lt;/a&gt;.&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;h3&gt;Mercurial extensions&lt;/h3&gt;One of the advantages of Mercurial is that it is easy to script extensions using Python. Sun has chosen to use the "forest" extension for OpenJDK, presumably so that subteams can administer themselves more easily. If you have already installed Mercurial, you can download the extension with it, using the following command:&lt;br /&gt;&lt;br /&gt;hg clone http://hg.akoha.org/hgforest/ hgforest&lt;br /&gt;&lt;br /&gt;Next you should edit your Mercurial configuration file. In your home directory, create a file called .hgrc and add the following lines to it:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;#Mercurial configuration&lt;br /&gt;[ui]&lt;br /&gt;username = your_name_and/or_mail_here&lt;br /&gt;[extensions]&lt;br /&gt;forest=/home/your_uid/hgforest/forest.py&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;The username defined there will identify you as the author in the commit metadata. At the public web repository of the code your mail address will be obfuscated, but your username string is not automatically obfuscated in the patches you submit. If you are sensitive about spam/privacy issues you may want to get a separate mail account. It is not improbable that some spamming scumbag clones the repository one day and combs through it for addresses.&lt;br /&gt;&lt;br /&gt;Once the extension is installed and configured, some commands will be replaced with their forest equivalent (fclone, fpush), so to finally download the code you do:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;hg fclone http://hg.openjdk.java.net/jdk7/jdk7&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;h3&gt;Preparing for the build&lt;/h3&gt;&lt;p&gt;You should read the &lt;span style="font-weight: bold;"&gt;README-builds.html&lt;/span&gt; page included in the source to begin with, these days it is very informative and helpful. You have to install the usual development libs. What differs OpenJDK from many other projects is that you have to download a bootstrap JDK - I think it is JDK6 now - and also the "binary plugs" which contain proprietary code that Sun doesn't own and did not get permission to release as open source. You do not need the binary plugs if you chose to download the &lt;a href="http://icedtea.classpath.org/wiki/Main_Page"&gt;Iced Tea&lt;/a&gt; version of the OpenJDK code. The Iced Tea project was created by RedHat and aims to replace all non-open source code so that you can build a completely free JDK from scratch. RedHat has signed the OpenJDK participation agreement I mentioned before, so their fixes will hopefully make it back into the core repository. When that has happened you won't need the binary plugs or a separate download from IcedTea anymore.&lt;/p&gt;&lt;p&gt;I have only built OpenJDK under Linux, but if you are planning to build under Windows there are a few things to consider. First, the compile process is oriented towards a Unix like environment so Windows style file paths, environment variables etc do not work. Therefore you must download and install Cygwin. According to the README-builds file you MUST use Visual Studio .NET 2003 Professional, the 2005 or later versions do not work, at least not out of the box. Luckily, Tim Bell and others are &lt;a href="http://blogs.sun.com/TimBell/entry/building_jdk7_on_windows_xp"&gt;looking at&lt;/a&gt; getting the "free-as-in-beer" Visual Studio Express for C++ to work (and in the future hopefully also "free-as-in-freedom" tools).&lt;br /&gt;&lt;/p&gt;&lt;p&gt;In theory only tested and perfectly functioning code is in the repository, but in reality people have mistakenly checked in non-compiling/non-working code often enough that it might be an idea to do as Elliotte Rusty Harold  &lt;a href="http://today.java.net/pub/a/today/2007/11/29/building-the-jdk.html"&gt;suggests&lt;/a&gt; - download a source snapshot first and try to get that to build, and then go on and try the latest repository code.&lt;/p&gt;&lt;h3&gt;Building&lt;/h3&gt;There is a file in the project source code you checked out -&lt;br /&gt;&lt;br /&gt;jdk/make/jdk_generic_profile.sh&lt;br /&gt;&lt;br /&gt;which sets all environment variables needed for the build. Look through it and edit it if needed, and when everything looks ok try running the following commands:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;bash&lt;br /&gt;. jdk/make/jdk_generic_profile.sh&lt;br /&gt;make dev-sanity&lt;br /&gt;make dev&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The "dev" version of the build is a bit smaller, if you really really want to build everything, including an installer, replace the last two lines with:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;make sanity&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;make&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Once you have built the whole project, you can build just the subprojects you are working on by guild into the corresponding "make" subdirectory and run the "make" command from there, this will save you time. Doing builds of subprojects depends on tools created by the global make, so the first time you must unfortunately build everything.&lt;br /&gt;&lt;h3&gt;Code overview&lt;/h3&gt;For easier maintenance the source has been split up into separate projects - &lt;span style="font-weight: bold;"&gt;langtools, jaxp, jaxws&lt;/span&gt; projects mainly consist of java code, &lt;span style="font-weight: bold;"&gt;hotspot &lt;/span&gt;is native code, &lt;span style="font-weight: bold;"&gt;corba&lt;/span&gt; is mixed.&lt;br /&gt;&lt;br /&gt;The sources for the core Java classes you use daily are usually in&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;jdk/src/share/classes/java(x)&lt;/span&gt;&lt;br /&gt;Some of these classes are just interfaces or abstract classes. The implementations are usually in&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;jdk/src/share/classes/sun&lt;/span&gt;&lt;br /&gt;(These classes in the sun package are sometimes used by applications, but it is strongly adviced that you never do that. It ties your users to Sun's JVM versions, and these classes are not a public API and therefore can change without any warning between JVM releases.)&lt;br /&gt;Operating system/platform specific Java code can be found in&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;jdk/src/{platform}/classes&lt;/span&gt;&lt;br /&gt;JNI created files usually end up in&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;jdk/src/share/native/&lt;/span&gt;&lt;br /&gt;but these are usually just header files. All the fun stuff tend to happen in&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;hotspot/src/share/vm&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;TODO - expand this part of the article.&lt;br /&gt;&lt;h3&gt;Requesting to participate&lt;/h3&gt;A lot of the following information is taken from &lt;a href="http://openjdk.java.net/contribute/"&gt;OpenJDK contribution page&lt;/a&gt;. First of all print out the &lt;a href="http://sun.com/software/opensource/sca.pdf"&gt;Sun Participation Agreement&lt;/a&gt; and read it through carefully. Basically you agree to "dual ownership" of the code, both parties can do whatever they want with it without asking the other part first. More details at the &lt;a href="http://www.sun.com/software/opensource/contributor_agreement.jsp"&gt;FAQ&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If you decide these terms are acceptable, sign it and mail it back to the provided address, or scan it and fax it to them. If you have signed this for any earlier Sun open source projects (Glassfish, Netbeans, OpenSolaris...) you are already covered and don't have to do it again.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Getting started with a bug&lt;/h3&gt;First of all find a suitable bug or Request For Enhancement (RFE) in the &lt;a href="http://bugs.sun.com/"&gt;bug database&lt;/a&gt;. If you know of a bug but can't find it in the database, please start by submitting the bug! Note that even though a bug has been accepted into the database, the submitter's synopsis can be misleading or completely incorrect. If there is an evaluation there you are on firmer ground, but I have known these to be out of date or incorrect also, so don't trust everything you read, you must check the code and the specs and think carefully about how things really work, and how they are intended to work. Sometimes bugs are even fixed but not closed in the database. When you have a good bug, search through the mailing lists and see if you can find any discussion about it - perhaps work on it has already started. If there is no discussion, announce your intention to start. Send a mail to the appropriate mailinglist with the subject "{Bugid: Synopsis}". For instance:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;162111: Incorrect Descriptor handling in ModelMBean classes&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Body of the mail is usually just something like "My name is... and I'd like to get started on this bug". Wait a few days for comments. Perhaps Sun engineers have already started working on this bug, perhaps they will re-evaluate it now and close it for some reason. In general, changing any public APIs (adding new methods for instance) is VERY DIFFICULT. You have to provide a convincing argument why this is needed, if the bug synopsis doesn't make a convincing case you could try to add some arguments to the body of your "starting intention" mail. Also, changing incorrect behaviour that applications already depend on is pretty much impossible - backwards compatibility has been holy so far. Still, just because Sun won't merge your patch into the core OpenJDK repository doesn't mean that others won't find it useful...&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Testing changes locally&lt;/h3&gt;Before submitting a patch you probably want to try out your changes. If you have compiled with the default build target and everything worked, you will have a newly compiled JDK located at &lt;span style="font-weight: bold;"&gt;build/{platform}/&lt;/span&gt;. One way is to just set the $PATH and $JAVA_HOME variables there and then try running all your favourite Java applications. On the other hand, perhaps you want to try to isolate your changes so you can test just those classes you changed together with an already installed JDK that you know works fine. You do this with the Xbootclasspath parameter. For instance -&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;java -Xbootclasspath/p:jarname.jar&lt;/span&gt;&lt;br /&gt;The "/p" part of the command is important, it prepends classes. This means that if the JVM finds any of the core java classes in the jar files or directories you specified (jarname.jar in my example above), these class versions will be used instead of the internal ones in your installed JDK. You can specify several jar files or directories as parameters.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Automated tests - Unit/regression testing&lt;/h3&gt;If you want your patch accepted you must also provide test classes. Most of you are probably familiar with JUnit/TestNG or similar test frameworks. Sun for a long time used an internal testing framework called &lt;a href="http://openjdk.dev.java.net/jtreg"&gt;JavaTest with the "jtreg" extension&lt;/a&gt; to run many of the JDK tests. This framework has now been open sourced. You can define test suits in java files, shellscript files or html files. The tests executed by jtreg can test not only ordinary Java files, but also applets and shellscripts. The Java classes you test do not need to implement any special interface, you can define the test to just run the main method of the class. If the process started by the test returns normally (the main method or shellscript finished) the test passed. If the JVM terminates with an uncaught exception, or the JVM or shellscript returns an errorcode (-1 usually) as it terminates, then the test failed. You can run tests with&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;jtreg -jdk:${jdk_path} ${testdir_or_testfile_path}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I'd like to write more about this works, but documentation is a bit sparse and when I last submitted my patch it was still JUnit that was asked of external submitters. Hopefully this situation will improve.&lt;br /&gt;&lt;br /&gt;It is difficult to give any rules for how much testing you should do... if you are just changing how GUI are drawn or documentation you can't do any tests of course. As a rule of thumb, perhaps you should consider spending at least as much time writing tests as you did fixing the code.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Submitting your patch&lt;/h3&gt;Now we are finally getting to the fun part! You submit your patch by sending a mail to the appropriate mailing list, with a subject of the following pattern:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[PATCH] 162111: Incorrect Descriptor handling in MBean classes&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The mail should contain the following:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;A discussion of the change: A rationale (if the bug synopsis didn't have one good enough). Briefly what you have changed and why. If you had any alternative solutions that you rejected, you may want to write a little about why.&lt;/li&gt;&lt;li&gt;A diff in the "unified" format (-u). Remember to write which version of the source you created the diff against!&lt;/li&gt;&lt;li&gt;Your tests classes.&lt;/li&gt;&lt;/ol&gt;Within a couple of weeks a Sun engineer (or someone with the same responsibility in a project) should reply and say if the patch will be accepted, or if it needs further work.&lt;br /&gt;&lt;h3&gt;Making a good patch&lt;/h3&gt;Here are a few rules of thumb to maximize your chances of getting your patch accepted:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Follow &lt;a href="http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html"&gt;The Java Code Conventions&lt;/a&gt;. Your code comments should describe WHY you do something if that needs explaining, not HOW you do it. Writing how you do it in comments is unnecessary duplication, that should be immediately obvious when looking at the code or something is wrong with it. Clear and descriptive variable names, yadda yadda. You know the rest...&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Idiomatic Java code that is readable even to junior programmers is preferable. Of course you shouldn't avoid writing smart and concise code, but don't show off for the sake of showing off, abuse "clever" tricks to fit the code into a single cryptic unmaintainable line, and so on.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Write lots of good tests.&lt;/li&gt;&lt;li&gt;Most important rule last - &lt;span style="font-weight: bold;"&gt;only change what is necessary, nothing else!&lt;/span&gt; This is a mistake I did when working on my first patch... Your patch will be carefully evaluated by core engineering teams, the smaller the diff is, the easier it is for them. Never run "fix imports", "autoindent all code" or similar in your IDE, start cleaning up cryptic variable names elsewhere in the class, etc,  even if you think the original code looks like complete crap. The patch will probably be rejected immediately if you do. Stick to fixing your original bug. Do code cleanup as a separate patch later that doesn't change any functionality, if you think this cleanup is absolutely necessary for maintainability.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;If the patch was not accepted into OpenJDK trunk by Sun, don't be discouraged. You probably learned a lot while doing it. Other projects or repositories may still be interested in your patch.&lt;br /&gt;&lt;br /&gt;Another rule of thumb I like is - try to be nice, if you need to criticise try to make it constructive criticism. In my experience Sun engineers are almost always been polite and helpful, but as the community grows some highly opinionated (and also very skilled) open source contributors may not hesitate to let you know if they think your code is poor in no uncertain terms. If that should happen, see it as an exercise in maturity. Thank them (silently if you prefer) for the what you may have learned from the exchange, and disregard any possible personal attacks. Consider that current/future employers may read the exchange one day. The Internet has a very long memory, and your online reputation matters.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;What I would like to see&lt;/h3&gt;For the OpenJDK to succced, Sun must continue their work to lower the barriers to entry. But a living and vibrant community is not something that Sun can create top-down with a wave of a magic wand, it is something that all of us who are interested in seeing OpenJDK succeed must try to help create. I'd like to see the following:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;More participants! We want YOU for OpenJDK! There must be hundreds of thousands of active Java programmers on the planet. If only a few percent contributed a couple of good patches each....&lt;/li&gt;&lt;li&gt;More information from Sun employees what they are working with. Previously I have seen new contributors who have had their first patch rejected because a internal rewrite/planned rewrite fixes the bug, and they were disappointed. Luckily this situation has already improved now that Sun's engineers use Mercurial, and the same mailing lists for discussions as everyone else.&lt;/li&gt;&lt;li&gt;Cleaning up of old and inaccurate information online. The &lt;a href="http://download.java.net/jdk/JDK-Starter.html"&gt;Starter bug list&lt;/a&gt; page for instance should be updated, I think half of the bugs on it are closed by now. I would also like it to be expanded so it covers not just individual bugs but whole areas with a low barrier to entry where beginner contributions would be welcome - something like the Linux &lt;a href="http://kernelnewbies.org/"&gt;Kernel Newbies&lt;/a&gt; community. Perhaps an OpenJDK Newbies Group could be created?&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h3&gt;Links&lt;/h3&gt;&lt;br /&gt;&lt;a href="http://today.java.net/pub/ct/10"&gt;On the Open Road&lt;/a&gt; - series of articles about OpenJDK. Rustys article beat me to the punch by a week or so and made this article somewhat redundant, but it was good to see that I was on the right track.&lt;br /&gt;Kelly O'Hair has loads of information on his &lt;a href="http://weblogs.java.net/blog/kellyohair/"&gt;two&lt;/a&gt; &lt;a href="http://blogs.sun.com/kto/"&gt;blogs&lt;/a&gt; about Mercurial, and building the JDK.&lt;br /&gt;Ted Neward blogs about&lt;a href="http://blogs.tedneward.com/2007/12/15/Let+The+JDK+Hacking+Begin.aspx"&gt; building the OpenJDK on Windows.&lt;/a&gt;&lt;br /&gt;Volker Simonis has two very in-depth articles about &lt;a href="http://weblogs.java.net/blog/simonis/archive/2008/01/hotspot_develop.html"&gt;HotSpot development on Linux with Netbeans.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5099452783517680285-7774555895042201193?l=larswestergren.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://larswestergren.blogspot.com/feeds/7774555895042201193/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5099452783517680285&amp;postID=7774555895042201193' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/7774555895042201193'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/7774555895042201193'/><link rel='alternate' type='text/html' href='http://larswestergren.blogspot.com/2007/12/beginners-guide-to-openjdk-contributing.html' title='Beginners guide to OpenJDK contributing'/><author><name>Lars Westergren</name><uri>http://www.blogger.com/profile/02654687571384000146</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_18LJx0IKqk0/SNjXSniCg3I/AAAAAAAAAAM/xENi61UQNj8/s1600-R/larswestergren.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5099452783517680285.post-7690393826732016340</id><published>2007-11-02T10:04:00.000+01:00</published><updated>2007-11-02T10:32:27.097+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='games pc rpg'/><title type='text'>Math test finally over</title><content type='html'>So, I finally have some spare time again, now that I have written my math test. Upcoming blogs will hopefully be about contributing to &lt;a href="http://openjdk.java.net/"&gt;OpenJDK&lt;/a&gt;, and my attempts to install &lt;a href="http://www.gnusolaris.org/gswiki"&gt;Nexenta/GnuOpenSolaris&lt;/a&gt; in order to use &lt;a href="http://www.sun.com/bigadmin/content/dtrace/"&gt;DTrace&lt;/a&gt; to help improve &lt;a href="http://jruby.codehaus.org/"&gt;JRuby&lt;/a&gt;, &lt;a href="http://www.netbeans.org/"&gt;Netbeans&lt;/a&gt; and other worthy open source projects.&lt;br /&gt;&lt;br /&gt;In the meantime, a short post about games. People have been talking about PC gaming on the decline, but I'm not seeing it. The sales numbers are for US retail stores only, and PC stales are much bigger in Europe, and online sales through sites like &lt;a href="http://www.steampowered.com/"&gt;Steam&lt;/a&gt;. These numbers conveniently also tend to ignore monthly MMORPG sales... if you include all those, I wouldn't be surprised if the PC is actually #1 in sales. I already know it is #1 in quality...&lt;br /&gt;&lt;br /&gt;In fact, there are more good games to play than I have spare time. Real role playing games (as I define them.... not action games like Diablo or cliched linear JRPGs, but games where you actually play a role and have an impact on the world through your choices) are having a mini-revival it seems like. &lt;a href="http://www.blogger.com/www.atari.com/nwn2/"&gt;Neverwinter Nights 2&lt;/a&gt; was pretty fun, a definite improvement on NWN1 and the closest I've gotten in a long time to recapuring the old Baldur's Gate magic, but I felt it didn't quite live up to its potential. Now that NWN2: Mask of the Betrayer is here, I think it has. There are other modules on the way for that game, both commercial and free (&lt;a href="http://theblackhound.googlepages.com/"&gt;Black Hound&lt;/a&gt; and &lt;a href="http://www.planescapetrilogy.com/"&gt;Planescape Trilogy&lt;/a&gt; look really promising). Also The Witcher looks good, though I haven't played it yet. Dragon Age should be released soon (I hope). Many shooters are growing up, becoming smarter, and finally becoming more inspired by Warren Specter and less by Carmack. Plot and mood are important. &lt;a href="http://www.2kgames.com/bioshock/"&gt;Bioshock&lt;/a&gt;, Portal are two good examples. Hey, even adventure games are back! &lt;a href="http://www.telltalegames.com/store/samandmax-season1"&gt;Sam &amp;amp; Max season One&lt;/a&gt; was fantastic.&lt;br /&gt;&lt;br /&gt;And then there are all the casual games! &lt;a href="http://www.popcap.com/games/bookwormadventures"&gt;Bookworm Adventures&lt;/a&gt; and &lt;a href="http://www.puzzlepirates.com/"&gt;Puzzle Pirates&lt;/a&gt; are two excellent ones. The last one is even free!&lt;br /&gt;&lt;br /&gt;Also thanks to Steam you can get previously hard to find classics like Vampire: Bloodlines and Psychonauts cheaply.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5099452783517680285-7690393826732016340?l=larswestergren.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://larswestergren.blogspot.com/feeds/7690393826732016340/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5099452783517680285&amp;postID=7690393826732016340' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/7690393826732016340'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/7690393826732016340'/><link rel='alternate' type='text/html' href='http://larswestergren.blogspot.com/2007/11/math-test-finally-over.html' title='Math test finally over'/><author><name>Lars Westergren</name><uri>http://www.blogger.com/profile/02654687571384000146</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_18LJx0IKqk0/SNjXSniCg3I/AAAAAAAAAAM/xENi61UQNj8/s1600-R/larswestergren.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5099452783517680285.post-7182044164433627929</id><published>2007-07-31T21:11:00.000+02:00</published><updated>2007-08-01T14:15:44.231+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hardware wlan linux drivers'/><title type='text'>Wireless, the eternal headache</title><content type='html'>New computer means re-installing operating systems, joy. Wireless hardware has always been a constant headache, no exception this time.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Netgear WG121 USB in Windows XP&lt;/b&gt;, I had to go through the following steps:&lt;br /&gt;1) Plug it in.&lt;br /&gt;2) When Windows recognizes it and wants to install drivers, you must "cancel".&lt;br /&gt;3) Pop in the CD and use setup.exe to install drivers yourself.&lt;br /&gt;4) Reboot.&lt;br /&gt;5) When windows wants to install drivers again after startup, "allow". Let it search the HD for drivers automatically, it will find and reinstall drivers - from what I can see, it copies from and to the same location.&lt;br /&gt;6) Reboot&lt;br /&gt;7) The Netgear connection wizard pops up and wants to disable Windows' own management of wireless connections - "allow".&lt;br /&gt;8) Wait a couple of minutes while seemingly nothing happens, until the wizard window hangs and stops responding, kill it with Windows process manager.&lt;br /&gt;9) Reboot. Now you can start the wizard from the start menu and you can finally configure settings and start using connection.&lt;br /&gt;10) Discover that the connection hangs while downloading large files - for instance the new Kubuntu 7.04 installation CD ISO.&lt;br /&gt;11) Swear a lot, reboot, download the 2.0 drivers and firmware zip from Netgear's site.&lt;br /&gt;12) Go into control panel, uninstall the original drivers and tools completely.&lt;br /&gt;13) Reboot and repeat steps 3-9, this time with the 2.0 drivers.&lt;br /&gt;&lt;br /&gt;Any deviation from these steps will make the driver installation fail and the hardware unusable, you will have to uninstall and restart from step 1.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Netgear WG121 USB in Kubuntu 7.04 Feisty Fawn&lt;/b&gt;: This is what I had to go through&lt;br /&gt;1) Read that some people claim it works out of the box. Plug it in, notice that nothing at all happens, plug in long network cable borrowed from work instead.&lt;br /&gt;2) Find the &lt;a href="https://help.ubuntu.com/community/WifiDocs/Device/WG121"&gt;following page&lt;/a&gt;.&lt;br /&gt;3) Do NOT download the packaged version of ndiswrapper through Synaptic/Adept package managers, use wget to download the latest version from Sourceforge.&lt;br /&gt;4) Remember to unplug the hardware if you have plugged it in, having it in will cause installation to fail.&lt;br /&gt;5) Compile and "make install".&lt;br /&gt;6) After following instructions on page from point 2 above and nothing works (only one light on device is on, /var/log/messages says probe failed with error code -22) after hours of trying to recompile and modprobe different versions, Google. Try to find relevant information without clicking on links from &lt;a href="http://www.google.com/search?q=wg121+ubuntu+7.04+incorrect+firmware+version&amp;ie=utf-8&amp;amp;amp;amp;oe=utf-8&amp;aq=t&amp;amp;rls=org.mozilla:sv-SE:official&amp;amp;client=firefox-a"&gt;Google keyword bombing spam scumbags&lt;/a&gt;. Eventually I found that Feisty has a regression bug - wrong Prism firmware is included in /lib/firmware for that kernel version. So, download the &lt;a href="http://jbnote.free.fr/prism54usb/"&gt;latest firmware&lt;/a&gt; compiled by the maintainer and overwrite one of the files in /lib/firmware/ with a completely different name.... I'd post a link to the detailed instructions of course, if I could find it again! I believe I read it at the Ubuntu bug forums.&lt;br /&gt;7) Reboot, now it works... for around 30 seconds, when it locks up until next reboot. Google some more, find that &lt;a href="http://ubuntuforums.org/showthread.php?t=417229"&gt;other people have the same problem&lt;/a&gt; but no one has found a reliable solution.&lt;br /&gt;&lt;br /&gt;Give up and install the PCI card I bought last time for this. I think it is a D-link card. The drivers for Windows are even more horrible than the Netgear WG121. I haven't been able to get it to work at all with Windows actually, but it works fine with Linux and ndiswrapper. So I have to have two devices, one for Windows and one for Linux.... Bleh.&lt;br /&gt;&lt;br /&gt;Perhaps newer generations of hardware are better? Can anyone recommend something that works with a minimum of hassle with both Windows and Linux?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5099452783517680285-7182044164433627929?l=larswestergren.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://larswestergren.blogspot.com/feeds/7182044164433627929/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5099452783517680285&amp;postID=7182044164433627929' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/7182044164433627929'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/7182044164433627929'/><link rel='alternate' type='text/html' href='http://larswestergren.blogspot.com/2007/07/wireless-eternal-headache.html' title='Wireless, the eternal headache'/><author><name>Lars Westergren</name><uri>http://www.blogger.com/profile/02654687571384000146</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_18LJx0IKqk0/SNjXSniCg3I/AAAAAAAAAAM/xENi61UQNj8/s1600-R/larswestergren.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5099452783517680285.post-3347445026822828354</id><published>2007-07-17T11:52:00.000+02:00</published><updated>2007-07-17T14:53:15.660+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='food recommended stockholm Chinese restaurants'/><title type='text'>Good Chinese food in Stockholm</title><content type='html'>Unfortunately it is difficult to find good Chinese food in Sweden. I have read that there is actually a reclusive Swedish-Chinese millionaire who lends money to families who want to start restaurants, providing they follow his guidelines. In other words, many restaurants are parts of a franchise just like McDonalds, which may explain why so many of them look the same, have the same muzak, the same price range, and the food at them is so similar and tastes so bland.... To me they fill the price and quality niche between fast food joints and "real" restaurants.&lt;br /&gt;&lt;br /&gt;The "Asian restaurant" syndrome is another pet peeve of mine by the way.... Instead of interesting fusions of kitchens with new crossover dishes being invented like in Australia for instance, in Sweden we get generic "Asian" restaurants where sushi restaurants have started to include a few standard Thai dishes on the menu, Chinese restaurants always have some bad sushi, and so on. You get a lot to choose from but very little that has been cooked with any passion or finesse.&lt;br /&gt;&lt;br /&gt;Enough negativity. Here are few tips for some better Chinese restaurants in Stockholm:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.laowai.se/index.html"&gt;Lao Wai&lt;/a&gt; is a small vegetarian restaurant and definitely number one on my list. They always use authentic and fresh ingredients, for instance Chinese rice wine instead of sherry, never canned products or powders. They import Oolong tea from their own plantation and so on. They cook and serve orders to the table one at a time to be eaten immediately, so you will get the best experience if you share dishes with your friends the traditional way. They have tofu that tastes just like smoked sausages or chicken, so even meat eaters who normally don't like vegetarian food should enjoy it.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Formosa is the best one in &lt;a href="http://www.old-town-stockholm.com/restaurants-old-town-stockholm.php"&gt;Gamla Stan (Old Town) &lt;/a&gt; that I know of. Very crowded with Chinese tourists who come by the busload. Noodle soup with meat, shrimp and pak soi is my favourite.&lt;/li&gt;&lt;li&gt;Ming, just next door to the &lt;a href="http://www.hotels.se/hotell-sverige/hotell-stockholm/crystal-plaza-hotel/"&gt;Crystal Plaza hotel&lt;/a&gt; used be really good, but I haven't eaten there in a while and I read in the papers that their star chef from China didn't get a renewed visa despite protests from the management of the restaurant and the hotel, so I'm not sure if it is still as good as it used to be.&lt;/li&gt;&lt;li&gt;Dragon House at Hornstull. This is a restaurant that gets very varied online reviews, from full marks to none, so either a competitor is trying to discredit them with a smear campaign or they have different chef teams with wildly varying skills. I have never been disappointed, but I always order from the special "traditional Chinese" menu and stay away from the buffet, the Thai food and the sushi. I recommend the small spicy chickens (beware of sharp bones though as they don't fillet the chickens, they just chop them up traditional style bones and all with a big meat cleaver) and the seafood pots with Chinese mushrooms (Seven Thunder Seafood I believe one is called). For the brave, they also have dishes like pigs stomach or crispy fried tripe with szechuan peppers (I don't know why so many are queasy about it though, the same people happily eat sausages after all).  This is another restaurant where you should go as a big group and share the dishes with one another.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5099452783517680285-3347445026822828354?l=larswestergren.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://larswestergren.blogspot.com/feeds/3347445026822828354/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5099452783517680285&amp;postID=3347445026822828354' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/3347445026822828354'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/3347445026822828354'/><link rel='alternate' type='text/html' href='http://larswestergren.blogspot.com/2007/07/good-chinese-food-in-stockholm.html' title='Good Chinese food in Stockholm'/><author><name>Lars Westergren</name><uri>http://www.blogger.com/profile/02654687571384000146</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_18LJx0IKqk0/SNjXSniCg3I/AAAAAAAAAAM/xENi61UQNj8/s1600-R/larswestergren.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5099452783517680285.post-5575733126178621178</id><published>2007-07-04T12:15:00.000+02:00</published><updated>2007-07-06T16:09:46.568+02:00</updated><title type='text'>Opinions about Ruby</title><content type='html'>I have been reluctantly been forced to admit that some of the stuff you can do with Ruby is pretty damn cool. Now that I have had to try to debug a non-trivial (to me at least) application, I feel I can have an opinion on Ruby, and do this based on experience rather than prejudice.&lt;br /&gt;&lt;br /&gt;First of all, documentation is poor for many libs. This is something that was raised at one of the general sessions at RailsConf 2007 in Portland, and got a very loud applause. I'm not just talking about tutorials or examples, many of them lack even minimal rubydocs. Many of them also do very little logging.&lt;br /&gt;&lt;br /&gt;Secondly, I like checked exceptions. There, I've said it. This particular application failed silently somewhere, and from the few things I could get from the logs it seemed like a problem with SSL. After messing around for days trying to get this to work, I noticed something odd. At one place in the code, I had this:&lt;br /&gt;@@services[wsdl_class].wiredump_dev = Logger.new("#{RAILS_ROOT}/log/#{RAILS_ENV}.log")&lt;br /&gt;@@services[wsdl_class].options['protocol.http.ssl_config.verify_mode'] = OPENSSL::SSL::VERIFY_NONE&lt;br /&gt;&lt;br /&gt;Now, if you switch around those lines, you get something funny, the wiredump logs aren't written. In fact, you could change it to&lt;br /&gt;@@services[wsdl_class].options['protocol.http.ssl_config.verify_mode'] = blahblahblah&lt;br /&gt;for the same effect. This is what finally clued me in to what was going on. In a completely different place in the codebase, the "model" code that fetches the SOAP object does a begin/rescue, assuming that any exceptions that occur are network related. I think that this was a valid assumption when the code was written, but later on some code had been refactored and some meta-programming magic goes on in a sub-lib to generate convenient helper classes and methods, and if you have a bug there, the generated exception is also silently swallowed and discarded. And this was application code by a very experienced programmer. Once other less experienced Ruby programmers (like me!) starts to mess up the code it quickly gets very difficult to understand what is going on.&lt;br /&gt;&lt;br /&gt;True, you can sprinkle your code with&lt;br /&gt;try {&lt;br /&gt;} catch (Exception x}&lt;br /&gt;{//Ignore}&lt;br /&gt;in Java as well, but I believe this is rarer or mainly done by beginner programmers. Some very good frameworks to it too, but generally wrap the exception in their own layer appropriate exception and passes it on. Knowing that introducing a new checked exception breaks client code does make Java code less malleable, but on the other hand it might make the lib developers more careful about how they structure the code, and reminds them when they have to handle exceptions that sub-libraries might throw themselves, and when they can wrap the the exception in another (layer appropriate) exception and pass it on. I might be wrong though, we'll see if my opinion changes as I learn more of Ruby and other languages.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5099452783517680285-5575733126178621178?l=larswestergren.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://larswestergren.blogspot.com/feeds/5575733126178621178/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5099452783517680285&amp;postID=5575733126178621178' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/5575733126178621178'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/5575733126178621178'/><link rel='alternate' type='text/html' href='http://larswestergren.blogspot.com/2007/07/opinions-about-ruby.html' title='Opinions about Ruby'/><author><name>Lars Westergren</name><uri>http://www.blogger.com/profile/02654687571384000146</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_18LJx0IKqk0/SNjXSniCg3I/AAAAAAAAAAM/xENi61UQNj8/s1600-R/larswestergren.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5099452783517680285.post-6675365626930556684</id><published>2007-06-19T14:29:00.000+02:00</published><updated>2007-06-19T14:40:57.359+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java ant linux configuring'/><title type='text'>Configuring Ant in Linux</title><content type='html'>I solved this problem a couple of years ago, but now it popped up again and I had forgotten how to solve it and wasted some time. So for my own sake, and in case people are Googling for it:&lt;br /&gt;&lt;br /&gt;If you get&lt;br /&gt;Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/tools/ant/launch/Launcher&lt;br /&gt;when running &lt;span style="font-style: italic;"&gt;ant&lt;/span&gt; first of all run "which ant" and "which java" to see which programs are being executed. You might discover (like I did) that the server is running an old gcj and there is an old systemwide ant. Export ANT_HOME, JAVA_HOME to correct the dirs. Also&lt;br /&gt;export PATH=$JAVA_HOME/bin:$ANT_HOME/bin:$PATH&lt;br /&gt;&lt;br /&gt;If you STILL get NoClassDefFoundError, you might find that there is a&lt;br /&gt;/etc/ant.conf&lt;br /&gt;file which trips you up, you might have to set ANT_HOME and JAVA_HOME properties there too! Or like &lt;a href="http://forum.java.sun.com/thread.jspa?threadID=549080&amp;messageID=4375629"&gt;Michael-N&lt;/a&gt; suggests, run &lt;span style="font-style: italic;"&gt;ant --noconfig -version&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The best solution though, tends to be to uninstall gcj, as well as all old system wide java tools that came with your distro. Instead of using RPM or similar, download the latest source directly from Sun. Things might improve now that Java is open source though.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5099452783517680285-6675365626930556684?l=larswestergren.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://larswestergren.blogspot.com/feeds/6675365626930556684/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5099452783517680285&amp;postID=6675365626930556684' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/6675365626930556684'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/6675365626930556684'/><link rel='alternate' type='text/html' href='http://larswestergren.blogspot.com/2007/06/configuring-ant-in-linux.html' title='Configuring Ant in Linux'/><author><name>Lars Westergren</name><uri>http://www.blogger.com/profile/02654687571384000146</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_18LJx0IKqk0/SNjXSniCg3I/AAAAAAAAAAM/xENi61UQNj8/s1600-R/larswestergren.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5099452783517680285.post-5200655864562336500</id><published>2007-06-09T11:49:00.000+02:00</published><updated>2007-06-09T12:15:15.331+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blogs'/><title type='text'>So...</title><content type='html'>So I finally gave in and got a real blog, where I previously only had a few random &lt;a href="http://slashdot.org/%7ELarsWestergren/journal"&gt;Slashdot journal entries&lt;/a&gt;. Blame &lt;a href="http://ola-bini.blogspot.com/"&gt;this guy&lt;/a&gt;! On a serious note, what convinced me was his argument that already today many in the computer industry find good blogs a more useful indication of a persons skill and history than does a CV or a long list of certifications. I like my current job, but I suppose I will switch some day, so I might as well get started.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5099452783517680285-5200655864562336500?l=larswestergren.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://larswestergren.blogspot.com/feeds/5200655864562336500/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5099452783517680285&amp;postID=5200655864562336500' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/5200655864562336500'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5099452783517680285/posts/default/5200655864562336500'/><link rel='alternate' type='text/html' href='http://larswestergren.blogspot.com/2007/06/so.html' title='So...'/><author><name>Lars Westergren</name><uri>http://www.blogger.com/profile/02654687571384000146</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_18LJx0IKqk0/SNjXSniCg3I/AAAAAAAAAAM/xENi61UQNj8/s1600-R/larswestergren.jpg'/></author><thr:total>0</thr:total></entry></feed>
