<?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-5605173550883974775</id><updated>2012-01-31T11:05:34.774Z</updated><category term='Social Media'/><category term='Python'/><category term='education'/><category term='EasyMock'/><category term='tools'/><category term='Space'/><category term='vcard'/><category term='Canoo'/><category term='Regular Expressions'/><category term='Hibernate'/><category term='Ramaze'/><category term='maven'/><category term='privacy'/><category term='Water'/><category term='Windows'/><category term='London'/><category term='Oracle'/><category term='Comedy'/><category term='SOA'/><category term='Probability Theory'/><category term='Mercurial'/><category term='Vodafone'/><category term='Motoring'/><category term='Politics'/><category term='london mayor'/><category term='Big Brother'/><category term='software practice'/><category term='eclipse rcp'/><category term='agile'/><category term='Credit Crunch'/><category term='craftsmanship'/><category term='Native'/><category term='Fit'/><category term='Software Configuration Management'/><category term='Spring'/><category term='test-driven development'/><category term='c++'/><category term='BT'/><category term='Religion'/><category term='Heritage'/><category term='arduino'/><category term='Text Centre'/><category term='embedded'/><category term='lean'/><category term='SMS'/><category term='soft skills'/><category term='WebTest'/><category term='VMWare'/><category term='MySQL'/><category term='Subversion'/><category term='PDF'/><category term='authentication'/><category term='security'/><category term='Music'/><category term='eclipse pde'/><category term='no2id'/><category term='XML'/><category term='Perl'/><category term='droplifting'/><category term='Java'/><category term='Web 2.0'/><category term='teams'/><category term='Open Source'/><category term='publishing'/><category term='Haskell'/><category term='PHP'/><category term='ITIL'/><category term='national identity register'/><category term='Regex'/><category term='android'/><category term='jMock'/><category term='Joomla'/><category term='eCommerce'/><category term='XPath'/><category term='homelessness'/><category term='Ruby'/><category term='Rack'/><category term='Linux'/><category term='sales technique'/><category term='BPTM'/><category term='Ubuntu'/><category term='Hacking'/><category term='Transport'/><category term='testing'/><category term='vcf'/><category term='virtualisation'/><category term='ID cards'/><category term='management'/><category term='Erlang'/><title type='text'>A  Software Practitioner Still Practising</title><subtitle type='html'>Practice makes perfect? Maybe, but I need lots of it...</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>85</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-8514834001058579900</id><published>2012-01-31T11:04:00.000Z</published><updated>2012-01-31T11:05:34.784Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Ubuntu Linux desktop 11.10 proxy settings solved</title><content type='html'>Watch out for system proxy settings in &lt;a href="http://www.ubuntu.com/ubuntu/whats-new" target="_blank"&gt;Ubuntu Desktop 11.10&lt;/a&gt; (at least in its &lt;a href="http://www.vmware.com/appliances/directory/va/1263893" target="_blank"&gt;LXDE&lt;/a&gt; guise, which is what I am running in a VM). The control panel "Network" has disappeared and even if you install it using apt or Synaptic you'll find that it doesn't have any proxy options. gconf does, but seems to have no effect. Answer is to edit /usr/share/applications/chromium-browser.desktop and append&lt;br /&gt;&lt;br /&gt;--proxy-pac-url="&lt;a href="http://example.com/" target="_blank"&gt;http://example.com/&lt;/a&gt;"&lt;br /&gt;&lt;br /&gt;to the Exec line.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-8514834001058579900?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/8514834001058579900/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=8514834001058579900' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/8514834001058579900'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/8514834001058579900'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2012/01/ubuntu-linux-desktop-1110-proxy.html' title='Ubuntu Linux desktop 11.10 proxy settings solved'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-6222784592344673989</id><published>2011-09-24T10:17:00.000+01:00</published><updated>2011-09-24T10:22:54.997+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='arduino'/><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='test-driven development'/><category scheme='http://www.blogger.com/atom/ns#' term='embedded'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Fun with Robots, Arduino and Android</title><content type='html'>Together with Mike Hogg from my firm, Zühlke Engineering, I recently developed a demonstration project over a three-day training exercise.We purchased a &lt;a href="http://robotshop.com/eu/dfrobotshop-rover-tracked-robot-bluetooth-kit.html"&gt;simple robot&lt;/a&gt; and added a set of three infra-red sensors capable of detecting a black line marked out on the ground with electrician's tape. We had to develop a line-sensing algorithm and control logic to follow the line and stop at stations (a short length of tape at right angles to the line) until instructed to move on.&lt;br /&gt;&lt;br /&gt;We followed a &lt;a href="http://en.wikipedia.org/wiki/Test-driven_development"&gt;test-driven development&lt;/a&gt; (TDD) approach for C++ using &lt;a href="http://www.cpputest.org/"&gt;CppUTest&lt;/a&gt;, as described by &lt;a href="http://pragprog.com/book/jgade/test-driven-development-for-embedded-c"&gt;James Grenning&lt;/a&gt;, to create a &lt;a href="http://objectvalue.com/articles/CppFiniteStateMachine.html"&gt;state machine&lt;/a&gt; to turn sensor readings into motor control instructions (with hindsight, we might have saved time by resorting to the &lt;a href="http://ehiti.de/machine_objects/"&gt;Machine Objects library&lt;/a&gt;). To my surprise, once we loaded the finished firmware to the &lt;a href="http://www.arduino.cc/"&gt;Arduino&lt;/a&gt; board, it worked very well with only a bit of tweaking of the motor speed settings corresponding to "hard left", "slight left" etc.&lt;br /&gt;&lt;br /&gt;Then we linked this with an application we developed for an &lt;a href="http://developer.android.com/"&gt;Android&lt;/a&gt; tablet computer (Motorola Xoom) that could be used to instruct the robot to go to any selected station, pick up/drop a "payload" (only conceptually) and return to base. The two components communicated by &lt;a href="http://www.bluetooth.com/"&gt;Bluetooth&lt;/a&gt; radio link.&lt;br /&gt;&lt;br /&gt;Finally, the tablet app was linked via a &lt;a href="http://en.wikipedia.org/wiki/Representational_state_transfer"&gt;RESTful Web Service&lt;/a&gt; interface to an "enterprise" system developed by other colleagues on the training course, that controlled the whole delivery network and knew which consignments had to be delivered to what stations. The tablet would send a message to the enterprise server telling it where the robot had arrived, and receive back an instruction containing the name of the next station to move to. The robot would then move off automatically after 5 seconds.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-kspgnGt7-4k/Tn2Nz8VcLFI/AAAAAAAADU8/PebPiop8QwA/s1600/DSC01614.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://1.bp.blogspot.com/-kspgnGt7-4k/Tn2Nz8VcLFI/AAAAAAAADU8/PebPiop8QwA/s320/DSC01614.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The whole thing was enormous fun (as well as very instructive) and was demonstrated successfully to the entire group (see photo).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.codemanship.co.uk/"&gt;Jason Gorman&lt;/a&gt; and &lt;a href="http://research.microsoft.com/~simonpj"&gt;Simon Peyton Jones&lt;/a&gt;, among others, have recently been at pains to point out the shortcomings of &lt;a href="http://www.computingatschool.org.uk/"&gt;IT education in the UK&lt;/a&gt;. Thinking about the above exercise, it occurred to me that it is just the sort of project that could engender enthusiasm for the subject from a wide range of school students. It involves lots of varied tasks from assembling the hardware to designing the user interface, and of course the devising of suitable protocols between all the components.&lt;br /&gt;&lt;br /&gt;Simon Peyton Jones of Microsoft Research will be presenting an &lt;a href="http://bcs-spa.org/cgi-bin/view/SPA/ComputingAtSchool"&gt;interactive talk&lt;/a&gt; about Computing At School on 2nd November in London, and the following month (6 December) Mike and I plan to do a session on the Robot Shop exercise at the same location. Anyone interested will be most welcome.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-6222784592344673989?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/6222784592344673989/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=6222784592344673989' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/6222784592344673989'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/6222784592344673989'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2011/09/fun-with-robots-arduino-and-android.html' title='Fun with Robots, Arduino and Android'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-kspgnGt7-4k/Tn2Nz8VcLFI/AAAAAAAADU8/PebPiop8QwA/s72-c/DSC01614.JPG' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-2582820647921024927</id><published>2011-08-10T14:22:00.002+01:00</published><updated>2011-08-10T14:25:00.298+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><title type='text'>Generate test data for Java development easily</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;A colleague has just pointed out the release of &lt;a href='http://www.andygibson.net/blog/article/generate-test-data-with-datafactory/' target='_blank'&gt;Andy Gibson's DataFactory library&lt;/a&gt; as a Maven artifact. It generates arbitrarily long lists of random names and addresses, dates, date ranges (with arbitrary constraints), random selections from lists, numbers, strings, Internet addresses etc. etc.&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=79e9dab2-2060-834f-83ea-2fc0ae0b6c4d' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-2582820647921024927?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/2582820647921024927/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=2582820647921024927' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/2582820647921024927'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/2582820647921024927'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2011/08/generate-test-data-for-java-development.html' title='Generate test data for Java development easily'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-6865052649114266769</id><published>2011-06-19T15:19:00.006+01:00</published><updated>2011-06-19T15:34:57.451+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software practice'/><category scheme='http://www.blogger.com/atom/ns#' term='education'/><category scheme='http://www.blogger.com/atom/ns#' term='Politics'/><category scheme='http://www.blogger.com/atom/ns#' term='craftsmanship'/><title type='text'>Inspiring the next generation of developers</title><content type='html'>&lt;a href="http://http://codemanship.co.uk/parlezuml/blog/?postid=1039"&gt;Jason Gorman&lt;/a&gt; has published a thought-provoking opinion piece asking why schools are doing so little to promote IT as an enticing career option and to equip kids to take advantage of it. His analysis points to a lack of suitably qualified teachers (so what's new?) and a commensurate lack of ambition on the part of exam boards to make the syllabus industry-relevant.&lt;br /&gt;&lt;br /&gt;Do &lt;a href="http://www.codemanship.co.uk/parlezuml/contact.htm"&gt;get in touch&lt;/a&gt; with Jason to take part in a summit at &lt;a href="http://www.bletchleypark.org.uk/"&gt;Bletchley Park&lt;/a&gt; (where else?) on 25th August 2011 to identify practical measures that can be taken to improve this dire situation.&lt;br /&gt;&lt;br /&gt;I think this is an issue the &lt;a href="http://bcs.org/"&gt;BCS&lt;/a&gt; should be addressing with all dispatch instead of tying itself in knots over some elusive ideal of making all IT practitioners professionally qualified. Some of the most proficient software practitioners I know have no professional qualifications at all.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-6865052649114266769?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/6865052649114266769/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=6865052649114266769' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/6865052649114266769'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/6865052649114266769'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2011/06/inspiring-next-generation-of-developers.html' title='Inspiring the next generation of developers'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-3088750649073327193</id><published>2011-05-25T16:55:00.002+01:00</published><updated>2011-05-25T17:00:17.465+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='eclipse pde'/><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='Fit'/><category scheme='http://www.blogger.com/atom/ns#' term='test-driven development'/><title type='text'>Perils of using an elderly FitLibrary</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;I learned about a really useful tool today while trying to hunt down a bug in a set of Fit automated acceptance tests.&lt;br /&gt;&lt;br /&gt;Last September, my colleague Darren Bishop had set up the automated acceptance test infrastructure for a Maven/Java project I subsequently joined. He used &lt;a href="http://search.maven.org/#artifactdetails%7Corg.fitnesse%7Cfitlibrary%7C20080812%7Cjar" target="_blank"&gt;version 20080812&lt;/a&gt; of the Maven dependency (org.fitnesse.fitlibrary), probably because it was the latest available in the Maven Central repository. Thus the stage was set for my troubles last night and this morning!&lt;br /&gt;&lt;br /&gt;While working on a small enhancement with a developer in the customer's product support unit, I noticed that one of the Fit tests was producing a blank report and not being counted in the summary totals. A comparison with other spreadsheets that did run properly revealed no significant differences.&lt;br /&gt;&lt;br /&gt;Back at base, it quickly became apparent that I had to single-step through the program to find out where it was going wrong. But I could find no source jar for this version of fitlibrary - the latest dependency version available with source was from &lt;a href="http://mirror3.mirrors.tds.net/pub/maven/org/fitnesse/fitnesse/20060719/" target="_blank"&gt;2006&lt;/a&gt;. What to do?&lt;br /&gt;&lt;br /&gt;After a futile attempt to desk-walkthrough the code of FolderRunner and SpreadsheetRunner, Keith Braithwaite suggested decompiling the class files. &lt;a href="http://java.decompiler.free.fr/?q=jdeclipse" target="_blank"&gt;JD-Eclipse&lt;/a&gt; to the rescue! I installed it in my Eclipse and found it so insanely useful that I will never want to be without it again. Basically it creates beautifully formatted source code for you on demand (obviously without the programmer's original comments and documentation). This means that you can set breakpoints and single-step through library code even if you have no source attachment for your library. Installation was really easy. After that, if you single-step into a library method, the "source" is opened automatically. You can also open a .class file directly in the package explorer by browsing the libraries on your project's build path.&lt;br /&gt;&lt;br /&gt;There's just one slight gotcha: the line numbers in the decompiled code rarely match the original, so if the class file contains line number annotations your instruction pointer and breakpoints may appear to be a few lines away from the location reported in the debugger's thread view. Ignore the cursor and read off the current line number from the comment at the start of each line. You can turn off the display of metadata and line numbers in the JD preferences, and I have done so - it needs a restart of Eclipse to take effect, but setting breakpoints is much easier afterwards.&lt;br /&gt;&lt;br /&gt;So, what was the solution to the mystery?&lt;br /&gt;&lt;br /&gt;In the FitLibrary class SpreadsheetRunner, the method collectTables() used an Iterator to return the rows of the test script one at a time and convert them into arrays of values that the runner could subsequently invoke to execute the test:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:monospace;"&gt;HSSFRow row = (HSSFRow)it.next();&lt;br /&gt;HSSFCell[] cells = getCells(row);&lt;br /&gt;String[] borderedCellValues = getBorderedCellValues(cells, workbook);&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Unfortunately, getCells() dimensioned an array of HSSFCell objects using the value returned by a row:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:monospace;"&gt;private HSSFCell[] getCells(HSSFRow row) {&lt;br /&gt;int maxCell = row.getLastCellNum();&lt;br /&gt;HSSFCell[] cells = new HSSFCell[maxCell];&lt;br /&gt;...&lt;br /&gt;return cells;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;When the row was "empty", getLastCellNum() returned -1, which caused the next line to throw a NegativeArraySizeException. This exception was caught by FolderRunner.runFile(), which attempted to report the problem to the standard output, but this didn't appear in the Maven test log.&lt;br /&gt;&lt;br /&gt;I have not found out what makes &lt;a href="http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.apache.poi%22%20AND%20a%3A%22poi%22" target="_blank"&gt;POI&lt;/a&gt; decide that a row is "empty". There was only a single spreadsheet row in the entire suite of tests that was interpreted in this way. I achieved a workaround by pasting a copy of another blank row of cells onto this row, but the danger is that anyone could inadvertently reintroduce the error.&lt;br /&gt;&lt;br /&gt;Lessons:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;You can still use the Java debugger if you don't have the source. JD-Eclipse worked very well for me, even though it is only at version 0.1.3. (I wonder if it will decompile classes written in other languages such as &lt;a href="http://www.jruby.org/" target="_blank"&gt;JRuby&lt;/a&gt;?)&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;It's time someone made a proper Maven dependency, with sources and javadoc, of the latest Fit, Fitnesse and FitLibrary versions - the &lt;a href="http://fitlibrary.git.sourceforge.net/git/gitweb.cgi?p=fitlibrary/fitlibrary;a=shortlog" target="_blank"&gt;current version&lt;/a&gt; of FitLibrary, dated April 5th, 2011 in fact solves the exact problem I encountered!&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="zemanta-pixie"&gt;&lt;img class="zemanta-pixie-img" alt="" src="http://img.zemanta.com/pixy.gif?x-id=5b3b98a6-59df-8d63-a24f-3485e8f52912" /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-3088750649073327193?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/3088750649073327193/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=3088750649073327193' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/3088750649073327193'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/3088750649073327193'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2011/05/perils-of-using-elderly-fitlibrary.html' title='Perils of using an elderly FitLibrary'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-7013603631141505604</id><published>2011-02-11T14:40:00.003Z</published><updated>2011-02-11T14:46:22.013Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Heritage'/><title type='text'>So long then, Ken Olsen</title><content type='html'>Ken Olsen, founder of DEC, passed away aged 84 on Sunday 7th February. &lt;a href="http://www.computerworld.com/s/article/9208601/Digital_Equipment_Corp._co_founder_Ken_Olsen_dies_at_age_84"&gt;Read a short obituary here&lt;/a&gt;. I used to consider DEC as the nimble young upstart snapping at IBM's heels and making computing affordable. My first real computing experience was on the undergraduate DEC-10 system (running TOPS10) at Leeds - and it shaped my subsequent career, though various PDP-8 and PDP-11 minis featured even before that. RIP Ken.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-7013603631141505604?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/7013603631141505604/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=7013603631141505604' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/7013603631141505604'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/7013603631141505604'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2011/02/so-long-then-ken-olsen.html' title='So long then, Ken Olsen'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-3692497708225454789</id><published>2011-01-29T16:01:00.001Z</published><updated>2011-01-29T16:01:02.873Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Probability Theory'/><title type='text'>The oddness of socks</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;style&gt;  &lt;/style&gt;  &lt;p class='MsoNormal'&gt;&lt;span lang='EN-GB' style='font-size: 10pt; font-family: Arial;'&gt;&lt;img src='http://lh3.ggpht.com/_eJ-aAjApSE0/TUQ4wVUN60I/AAAAAAAABpA/3n_xByPJDeI/%5BUNSET%5D.png?imgmax=800' style='max-width: 800px;'/&gt;&lt;br/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class='MsoNormal'&gt;&lt;span lang='EN-GB' style='font-size: 10pt; font-family: Arial;'&gt;In a moment of boredom, and prompted by a recent &lt;a href='http://www.itbusinessedge.com/slideshows/show.aspx?c=86398' target='_blank'&gt;survey of wacky interview questions&lt;/a&gt;, I plotted out the probability graph of finding a matching pair of socks at random, based on the number of black ones among 25 grey ones. It turns out that you need only 3 black socks to drop the probability of a matching pair from 100% to 80%; 9 in 25 gets you to 60%. Anything over that makes very little difference up to 25, where the probability drops to a minimum as you would expect. After that it starts rising again slowly, but never reaches 100%. YOU NEVER HAVE A LESS THAN 48.9795918% CHANCE OF GETTING A MATCHING PAIR. I find that oddly comforting.   &lt;/span&gt;&lt;/p&gt;  &lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=8429c580-2880-894e-9a35-0e69d56075e9' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-3692497708225454789?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/3692497708225454789/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=3692497708225454789' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/3692497708225454789'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/3692497708225454789'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2011/01/oddness-of-socks.html' title='The oddness of socks'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_eJ-aAjApSE0/TUQ4wVUN60I/AAAAAAAABpA/3n_xByPJDeI/s72-c/%5BUNSET%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-6602552325079003237</id><published>2011-01-14T18:38:00.002Z</published><updated>2011-01-14T18:41:15.609Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><title type='text'>Oracle 10g problem under Windows Server 2003</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;It cost me the best part of two days' detective work to fix a problem with the Oracle DB Control service. Symptoms include:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;"CONFIG: Waiting for service 'OracleDBConsoleorcl' to fully start" in cfgtoollogs\dbca\orcl\cloneDBCreation.log&lt;/li&gt;&lt;li&gt;"&lt;span class="ft"&gt;The &lt;em&gt;oracleDBconsoleorcl service&lt;/em&gt; could not be  started"&lt;/span&gt; &lt;/li&gt;&lt;li&gt;"[Orion Launcher] ERROR app.ContextInitializer contextInitialized.272 - Integration Class not found: oracle.sysman.ias.ias.IASIntegration" in emoms.log&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;This started to happen after a failed import using the data pump (&lt;a href="http://wiki.oracle.com/page/Data+Pump+Export+%28expdp%29+and+Data+Pump+Import%28impdp%29" target="_blank"&gt;impdp&lt;/a&gt;) trashed the database and I rashly thought that I might clear up the problem by uninstalling and reinstalling Oracle 10.2.0.4.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Background&lt;/b&gt;: For a client project, we needed a local copy of the client's schema and stored procedures. I found it remarkably straightforward to install the Oracle product and a default database instance named orcl. However, attempting to import the client's &lt;a href="http://www.oracle-dba-online.com/data_pump_utility.htm" target="_blank"&gt;exported schema and stored procs&lt;/a&gt; caused a rash of errors and then the SYSTEM user's password had been corrupted too. My suggestion: use the deprecated &lt;a href="http://wiki.oracle.com/page/Oracle+export+and+import" target="_blank"&gt;exp and imp&lt;/a&gt; tools instead. They're much more straightforward to use, AND the wonderful &lt;a href="http://www.ddlwizard.com/"&gt;DDL Wizard&lt;/a&gt; is able to convert the exported file to DDL and PL/SQL that you can run in SQLPlus instead of overwriting your database contents willy-nilly.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Solution&lt;/b&gt;: I wish there was one. The problem appears to occur in the final phase of the database configuration assistant - after creating and configuring the database it tries to start up the console service for it and fails, for as-yet unfathomable reasons. Could it be to do with the fact that we also run MS SQL Server on the same box? Yet this was fine before I tried to reinstall Oracle. (As I eventually learned, I need not have redone the entire installation, because the database configuration assistant is quite good at deleting the database instance and creating a new one - in fact, this is what the installer invokes anyway).&lt;br /&gt;&lt;br /&gt;Luckily the whole thing runs on a virtual machine, so I am going to get the previous week's VM backup image restored. Luckily we hadn't been doing a lot of work on that machine in the meantime.&lt;br /&gt;&lt;br /&gt;My grateful thanks to the many bloggers who came up with possible solutions - none of which worked for me:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;drop and reconfigure the &lt;a href="http://kr.forums.oracle.com/forums/thread.jspa?threadID=638113" target="_blank"&gt;repository&lt;/a&gt;&lt;/li&gt;&lt;li&gt;work around Windows's tendency to use &lt;a href="http://forums.oracle.com/forums/thread.jspa?threadID=309223&amp;amp;start=15&amp;amp;tstart=0" target="_blank"&gt;different hostnames&lt;/a&gt; depending on network connectivity&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="zemanta-pixie"&gt;&lt;img src="http://img.zemanta.com/pixy.gif?x-id=a3c85a16-d1da-8ba6-99db-9a94d25f0832" alt="" class="zemanta-pixie-img" /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-6602552325079003237?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/6602552325079003237/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=6602552325079003237' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/6602552325079003237'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/6602552325079003237'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2011/01/oracle-10g-problem-under-windows-server.html' title='Oracle 10g problem under Windows Server 2003'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-2153340161441508716</id><published>2011-01-12T10:50:00.001Z</published><updated>2011-01-12T10:50:11.556Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='software practice'/><category scheme='http://www.blogger.com/atom/ns#' term='craftsmanship'/><title type='text'>Software: Craft or Trade? You decide</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;Dan North has started a serious discussion with his &lt;a href='http://dannorth.net/2011/01/11/programming-is-not-a-craft/' target='_blank'&gt;insightful article&lt;/a&gt; about the Software Craftsmanship movement and where its manifesto possibly misses the point.&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=d51922fe-0abb-82bd-ad9b-dddd523376e9' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-2153340161441508716?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/2153340161441508716/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=2153340161441508716' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/2153340161441508716'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/2153340161441508716'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2011/01/software-craft-or-trade-you-decide.html' title='Software: Craft or Trade? You decide'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-669045606081379850</id><published>2011-01-06T16:59:00.001Z</published><updated>2011-01-06T16:59:03.229Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='software practice'/><category scheme='http://www.blogger.com/atom/ns#' term='lean'/><title type='text'>Breaking up the big rocks</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;A colleague has circulated &lt;a href='http://www.richardlawrence.info/2009/10/28/patterns-for-splitting-user-stories/' target='_blank'&gt;Richard Lawrence's nine patterns for dividing up user stories&lt;/a&gt;. These are going to be very useful. I wonder if someone will add more to make the magic Baker's Dozen?&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=2022a147-6f6b-83f3-92b9-af79a587d8fe' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-669045606081379850?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/669045606081379850/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=669045606081379850' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/669045606081379850'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/669045606081379850'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2011/01/breaking-up-big-rocks.html' title='Breaking up the big rocks'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-4057042825406737863</id><published>2011-01-06T14:36:00.001Z</published><updated>2011-01-06T14:36:30.186Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='software practice'/><category scheme='http://www.blogger.com/atom/ns#' term='soft skills'/><category scheme='http://www.blogger.com/atom/ns#' term='Social Media'/><category scheme='http://www.blogger.com/atom/ns#' term='Web 2.0'/><title type='text'>New Ideas in Social Marketing</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;Attended a stunning event last night at the BCS London conference rooms. The speakers were &lt;a href='http://www.ecademy.com/account.php?id=8' target='_blank'&gt;Thomas Power&lt;/a&gt; of &lt;a href='http://www.ecademy.com/' target='_blank'&gt;Ecademy&lt;/a&gt; and &lt;a href='http://www.headshift.com/mt/mt-cp.cgi?__mode=view&amp;amp;blog_id=1&amp;amp;id=20' target='_blank'&gt;Lee Bryant&lt;/a&gt; of &lt;a href='http://www.headshift.com/' target='_blank'&gt;Headshift&lt;/a&gt;. The event was jointly organised by Richard Tandoh, Dalim Basu and Sara Misell on behalf of the North London Branch, Elayne Coakes on behalf of the BCS Sociotechnical specialist group and me on behalf of BCS Software Practice Advancement.&lt;br/&gt;&lt;br/&gt;I learned that my use of social media was probably at the very raw beginner level - and moreover, that all the companies I have ever worked for, including my current employer, are at or below that level. If you want some insights into your level of influence measured by the effectiveness of your online behaviour (and how it compares to others), try &lt;a href='http://klout.com/' target='_blank'&gt;Klout&lt;/a&gt; or &lt;a href='http://www.peerindex.net/' target='_blank'&gt;PeerIndex&lt;/a&gt;. These applications use people's &lt;a href='http://www.twitter.com/' target='_blank'&gt;Twitter&lt;/a&gt; usernames as the primary key, so if you aren't on Twitter, you don't even get to first base.&lt;br/&gt;&lt;br/&gt;Thomas showed how the stream of information we receive from the Web is growing exponentially - his &lt;a href='http://friendfeed.com/' target='_blank'&gt;FriendFeed&lt;/a&gt; home page was updating with new events more than once a second. A potentially incredibly useful tool for cutting this deluge down to size is made by &lt;a href='http://www.my6sense.com/services/' target='_blank'&gt;My6Sense&lt;/a&gt;. They make a reader for iPhone, iPod Touch and Android devices that watches your Twitter, Facebook, News and RSS streams and brings the most important items to your attention. Thomas believes it takes around 30 hours to train it. More importantly, this being a social media world, once something has caught your attention, the my6sense app lets you &lt;b&gt;share &lt;/b&gt;it easily with your own network of contacts.&lt;br/&gt;&lt;br/&gt;In the Q&amp;amp;A session, I found out about a recently launched &lt;a href='http://www.quora.com/' target='_blank'&gt;online service&lt;/a&gt; that is attempting to cross-fertilise a crowd-sourced knowledge repository (think &lt;a href='http://www.wikipedia.com/' target='_blank'&gt;Wikipedia&lt;/a&gt;) with a personal reputation index (like &lt;a href='http://ebranding.me/resources/score/' target='_blank'&gt;eBranding Me&lt;/a&gt;). A fun way to find out more is to take the &lt;a href='http://www.quora.com/challenges' target='_blank'&gt;Quora programming challenge&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;The discussion in the pub afterwards was most illuminating too, though it veered away from social media to discussing the disaster that is likely to befall the civilised world when, not if, the next massive Coronal Mass Ejection occurs. This event is expected to occur within 10-24 months as of this writing and is likely to knock out not only communications networks (particularly satellite-based ones) but all manner of computer systems, data networks and power grids. Since everything these days is dependent on computers, we're likely to suffer supply shortages of everything from drinking water to fuel. As for withdrawing money from your bank account, you will probably be well advised to forget it for a few months. The guy telling us this has inside knowledge as a result of working for a major data security company and claims that they have working solutions to sell that will handle the backup and disaster recovery requirements of computer users from home users to data centres (remember that from the first detection of a CME, the world has only 15 minutes to secure everything before the plasma storm hits). His advice is to print out your bank statements and keep them safe along with non-perishable emergency supplies; also to have a spare laptop computer somewhere wrapped in several layers of tin foil to protect it from EMP. Contact me if you want to know more!&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=786ce897-4276-8a72-8e64-cf3ce4849b24' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-4057042825406737863?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/4057042825406737863/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=4057042825406737863' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/4057042825406737863'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/4057042825406737863'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2011/01/new-ideas-in-social-marketing.html' title='New Ideas in Social Marketing'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-7163144716346814284</id><published>2011-01-03T09:10:00.002Z</published><updated>2011-01-03T09:12:24.317Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Politics'/><title type='text'>We need to re-learn that it's OK to fail</title><content type='html'>While trying to find the answer to a festive season quiz, I stumbled across this &lt;a href="http://unimportant.blog.co.uk/2010/10/19/birthday-dagger-painkiller-addiction-snuggles-from-sammy-more-fialures-curing-the-common-cold-plugged-back-into-love-9673831/"&gt;blog post&lt;/a&gt;. Check out the "more fialures" (sic) section - it makes reassuringly heartening reading...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-7163144716346814284?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/7163144716346814284/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=7163144716346814284' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/7163144716346814284'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/7163144716346814284'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2011/01/we-need-to-re-learn-that-its-ok-to-fail.html' title='We need to re-learn that it&apos;s OK to fail'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-1925607476238372912</id><published>2010-12-05T22:00:00.003Z</published><updated>2010-12-05T22:31:40.599Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hacking'/><category scheme='http://www.blogger.com/atom/ns#' term='eCommerce'/><title type='text'>Shocking - www.amazon.co.uk disappears</title><content type='html'>This evening, I tried to buy a Christmas present for my wife that she had selected from Amazon's UK site. Imagine my surprise when I got a domain-parking page advertising naughty dating services!&lt;div&gt;&lt;br /&gt;&lt;div&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_eJ-aAjApSE0/TPwST6vK8bI/AAAAAAAABjs/ZJeCrsAv430/s320/20101205_amazon_co_uk.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5547328974407528882" /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Has Amazon allowed its domain registration to run out? It appears not - I checked the WHOIS entry. More probably, someone has hacked the DNS entry in "revenge" for last week's eviction of the WikiLeaks service from Amazon's cloud. Grow up, people!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In fact as I was trying to upload the above image, blogger.com also started to display the same kind of holding page. I had to hurriedly change to a different DNS. Who knows how long that one will last - we may be under some kind of sustained Internet hacking attack.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Trying to send an alert to anyone at Amazon by e-mail is, apparently, impossible. Nowhere on the amazon.com site is there a "contact us" link. The Amazon staff is better protected against any communication from their customers than EasyJet (see posts passim).&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-1925607476238372912?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/1925607476238372912/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=1925607476238372912' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/1925607476238372912'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/1925607476238372912'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2010/12/shocking-wwwamazoncouk-disappears.html' title='Shocking - www.amazon.co.uk disappears'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_eJ-aAjApSE0/TPwST6vK8bI/AAAAAAAABjs/ZJeCrsAv430/s72-c/20101205_amazon_co_uk.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-4062125808912839120</id><published>2010-11-13T16:37:00.003Z</published><updated>2010-11-13T17:03:28.107Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Fit'/><category scheme='http://www.blogger.com/atom/ns#' term='test-driven development'/><title type='text'>File Handles in the JVM</title><content type='html'>I recently spent three or four fruitless hours (spread across several days) trying to get a bunch of Fit tests to run reliably. The setup fixture was used to clean out the folders in which the program under test was intended to find its input data and write its output data. Subsequent fixtures created the input files, executed the program under test, and analysed the output files.&lt;br /&gt;&lt;br /&gt;So far so good, but as the number of tests gradually increased we started to get failures apparently at random. I suspected that the setup fixture was not deleting all the files out of the input and output folders, so increased the rigour of this method by invoking the FileUtils deleteDirectory method and throwing a runtime exception if it failed even after five retries.&lt;br /&gt;&lt;br /&gt;It turned out that this was frequently failing because some process was keeping file handles open on files within the test folder hierarchy. Under Windows, this prevents the containing folder from being deleted or moved. We suspected virus checkers, search indexers and the like, but it turned out to be the Fit test harness itself. Even though we had taken great care to flush and close every file stream used by our Fit fixtures, the VM was not always releasing the corresponding file handles and so the next invocation of the setup fixture failed.&lt;br /&gt;&lt;br /&gt;The answer turned out to be surprisingly simple: invoke the garbage collector and finalizer before retrying the call to deleteDirectory. Now it works every time!&lt;br /&gt;&lt;br /&gt;Code sample:&lt;pre&gt;&lt;br /&gt;...&lt;br /&gt;import static org.apache.commons.io.FileUtils.deleteDirectory;&lt;br /&gt;...&lt;br /&gt;    public static void zapDirectory(String path) {&lt;br /&gt;        ...&lt;br /&gt;        File directory = new File(path);&lt;br /&gt;        for (int i = RETRY_COUNT; directory.exists(); i--) {&lt;br /&gt;            try {&lt;br /&gt;                deleteDirectory(directory);&lt;br /&gt;            } catch(IOException e) {&lt;br /&gt;                if (i &lt;= 0) {&lt;br /&gt;                    throw new RuntimeException("Cannot delete folder \"&lt;br /&gt;                        + path + "\" because: " + e.getMessage());&lt;br /&gt;                }&lt;br /&gt;                try {&lt;br /&gt;                    System.gc();&lt;br /&gt;                    System.runFinalization();&lt;br /&gt;                    Thread.sleep(SLEEP_INTERVAL);&lt;br /&gt;                } catch(InterruptedException e1) {&lt;br /&gt;                    // don't care if interrupted&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            if (directory.exists()) {&lt;br /&gt;                throw new RuntimeException("Cannot delete folder \"&lt;br /&gt;                    + path + "\" for an unknown reason");&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-4062125808912839120?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/4062125808912839120/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=4062125808912839120' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/4062125808912839120'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/4062125808912839120'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2010/11/file-handles-in-jvm.html' title='File Handles in the JVM'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-2629318950916159035</id><published>2010-08-02T20:10:00.005+01:00</published><updated>2010-08-02T21:09:04.250+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='VMWare'/><category scheme='http://www.blogger.com/atom/ns#' term='Subversion'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><category scheme='http://www.blogger.com/atom/ns#' term='authentication'/><category scheme='http://www.blogger.com/atom/ns#' term='Software Configuration Management'/><category scheme='http://www.blogger.com/atom/ns#' term='Mercurial'/><title type='text'>Migrating a Subversion repository</title><content type='html'>&lt;p&gt;In my current project, there are a number of development teams whose code repositories have grown, separately or together, in a somewhat haphazard fashion. As part of the initiative to introduce a more streamlined development process, therefore, I want to host all repositories on one server and reorganise them in a more uniform and logical way.&lt;/p&gt;&lt;p&gt;Using &lt;a href="http://subversion.apache.org/"&gt;Subversion&lt;/a&gt;, it is relatively straightforward to move whole repositories, but taking one branch out of an existing one to add to a new repository (without losing the change history!) turns out to be surprisingly hard. After much experimentation, the best way turns out to be via &lt;a href="http://mercurial.selenic.com/"&gt;Mercurial&lt;/a&gt;'s excellent "convert" extension. Unfortunately, conversion from Hg to Subversion simply fails under Windows, so you need to use Linux.&lt;/p&gt;&lt;p&gt;This particular customer has a totally Windows-based infrastructure, as well as a particularly draconian firewall that uses Windows authentication exclusively. The following recipe therefore had to take that into account. Names have been blanked out where necessary to preserve client confidentiality.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Install the &lt;a href="http://downloads.vmware.com/d/info/desktop_downloads/vmware_player/3_0"&gt;VMWare player&lt;/a&gt; and a Linux appliance, such as the &lt;a href="http://www.quotrader.org/vm/ubuntu1004t/"&gt;Ubuntu 10.04 LTS image with VMware Tools&lt;/a&gt;.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Lightly edit the VMWare virtual machine configuration file (Ubuntu.vmx) to ensure that it has at least 1024MB of RAM. Start up the Linux VM and upgrade existing packages. This turns out to be a little more difficult than you might expect, because the Synaptic package manager (unlike Firefox) is unable to pass your Windows username and password as NTLM credentials to the network proxy server. Therefore you have to proceed as follows:&lt;/li&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Make sure that the VMWare player's network connection is set to "NAT"&lt;/li&gt;&lt;br /&gt;&lt;li&gt;In System -&amp;gt; Preferences -&amp;gt; Network Proxy, set the manual HTTP proxy to the server and and port that your Windows web browser uses. If the Web browser's Internet settings nominate a proxy auto-configuration script, you may be able to use that instead. Don't forget to set your Windows username and password. Apply system-wide (you will have to supply your Linux user password twice).&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Open Firefox and navigate to &lt;a href="http://sourceforge.net/projects/cntlm/"&gt;http://sourceforge.net/projects/cntlm/&lt;/a&gt; - download the .deb package and allow the package installer to install it. This is a local proxy server that logs onto the firewall on your behalf.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Now configure the cntlm service as follows:&lt;ul&gt;&lt;li&gt;As superuser, edit /etc/cntlm.conf and set the following values (see the &lt;a href="http://cntlm.sourceforge.net/"&gt;documentation&lt;/a&gt;):&lt;ul&gt;&lt;li&gt;Username (your Windows user ID)&lt;/li&gt;&lt;li&gt;Domain (your Windows domain)&lt;/li&gt;&lt;li&gt;Workstation (your PC name - not the full FQDN)&lt;/li&gt;&lt;li&gt;Proxy (proxy FQDN:proxy port)&lt;/li&gt;&lt;li&gt;Proxy (backup proxy FQDN:proxy port)&lt;/li&gt;&lt;li&gt;Listen 3128&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Make sure that the permissions on cntlm.conf are -rw-r--r--&lt;/li&gt;&lt;li&gt;As a normal user, run the following command:&lt;br/&gt;cntlm -v -I -M http://test.com&lt;/li&gt;&lt;li&gt;Copy and paste the resulting profile (the lines between -------------- markers) into the cntlm.conf file - search for "#Auth" to find the insertion point&lt;/li&gt;&lt;li&gt;As the superuser, start up the cntlm service:&lt;br/&gt;/etc/init.d/cntlm start&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;In System -&amp;gt; Preferences -&amp;gt; Network Proxy, set the manual HTTP and FTP proxy servers to localhost and port 3128. Username and password should still be your Windows credentials. Apply system-wide as before. Shutdown Firefox and open it again to check that the proxy settings are correct.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Open System -&amp;gt; Administration -&amp;gt; Synaptic Package Manager (it will request your Linux user password). Go to Settings and configure a manual proxy just as in System Preferences.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Still in the package manager, click Reload. You should see the package files being downloaded successfully. Click "Mark All Upgrades".&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Still in the package manager, type "subversion" into the search box. Mark both "subversion" and its dependencies and "python-subversion" for installation. Similarly for "mercurial". Finally, click "apply", click the Apply button, and sit back.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Part way through the installation process, you may encounter a warning that the Linux system image cannot be safely installed without GRUB. However, the grub loader has been superseded by grub-pc, so you can safely ignore this (click the "go ahead without grub" checkbox).&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;You can also upgrade the VMWare tools, which the player will claim are out of date. This is of unproven usefulness. It doesn't take terribly long, so you may as well. After downloading the upgrade, VMWare Player mounts it as a CD image under /media (run "df" to find out what it's called). The trick is to unzip from there into /tmp or your home directory, because the mounted volume is read-only. Then run "sudo perl &amp;lt;install-script&amp;gt;" to upgrade the software.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Assuming all has gone well, you should now be able to run Mercurial and Subversion from the command line. Test it by running the following commands:&lt;br/&gt;hg help&lt;br/&gt;svn help&lt;br/&gt;svnadmin help&lt;/li&gt;&lt;br /&gt;&lt;li&gt;You need to cache the subversion authentication parameters in order that Mercurial can invoke subversion non-interactively. To do this, make sure you are logged in as an ordinary user (not root) and run:&lt;br/&gt;svn log -l 2 REPOSITORY_URL&lt;br/&gt;where REPOSITORY_URL is the address of the repository from which you wish to migrate a branch.&lt;br /&gt;When prompted for the "user" password, just hit return. Now enter the username of a real user with access to the target repository, and hit RETURN. Next enter that user's password and hit RETURN. You should be rewarded with two lines of history from that repository.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;You must enable the convert extension by uncommenting the line containing "hgext.convert =" in /etc/mercurial/hgrc.d/hgext.rc.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Now you're all set to do the export. Create a folder (e.g. "repo_migration") and change directory into it. Create a file-mapping file such as myproject_mapping.txt:&lt;br /&gt;&lt;br /&gt;include branches/Development/myproject&lt;br /&gt;rename branches/Development/myproject trunk&lt;br /&gt;&lt;br /&gt;See the &lt;a href="http://mercurial.selenic.com/wiki/ConvertExtension"&gt;hg convert documentation&lt;/a&gt; for details of the mapping format.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The following command does the business. It will probably process around 100 revisions per minute on average, so you've got time to make lots of cups of tea:&lt;br /&gt;- hg convert -d svn --filemap myproject_mapping.txt -s svn REPOSITORY_URL NEW_REPOSITORY&lt;br /&gt;where REPOSITORY_URL is the address of the repository from which you are migrating, and NEW_REPOSITORY is the name of the local Subversion repository you want to create as the result.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;If the conversion starts to slow down, you can open a second terminal and, as superuser, set the nice level of the running hg process to -20, which should increase its priority to maximum. I'm not sure how much this helps, since the process seems mainly network-bound.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Finally, copy the new local repository to a location from which your Subversion server can serve it, and Bob's your parent's brother.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;It has just occurred to me that the reason this doesn't work under Windows is probably because we didn't have the python-subversion package installed. However, that is just a guess because the diagnostics given (exit code 1) provided no clue.&lt;/p&gt;&lt;p&gt;Ideally of course, you should just export the existing repository to Mercurial and let everyone use that instead of Subversion from now on. Unfortunately some tools we want to use, such as &lt;a href="http://www.atlassian.com/software/jira/"&gt;JIRA&lt;/a&gt; are not yet Mercurial-aware. Besides, we don't want to incur the overhead of training developers to work with a new SCM tool - it isn't that long since they even began to use Subversion.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-2629318950916159035?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/2629318950916159035/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=2629318950916159035' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/2629318950916159035'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/2629318950916159035'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2010/08/migrating-subversion-repository.html' title='Migrating a Subversion repository'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-5149299897494824708</id><published>2010-08-01T15:56:00.005+01:00</published><updated>2010-08-01T16:35:31.407+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='Open Source'/><category scheme='http://www.blogger.com/atom/ns#' term='Joomla'/><title type='text'>Custom image folder for Joomla Contacts</title><content type='html'>&lt;p&gt;Because my &lt;a href="http://st-michaels-beddington.org/mambo/" target="_blank"&gt;church web site&lt;/a&gt; has a large number of contacts, I wanted to put all the photos in their own folder. Joomla's Contacts component normally expects photos to be stored at the default image location, /images/stories. I have a folder named portraits under this folder, but Joomla doesn't recurse into it when you select an image in the contact form.&lt;/p&gt;&lt;p&gt;It turns out that you have to make only three small edits to get this working, but I spent a frustrating few hours investigating before I found out how. To save you the trouble, here's the recipe. All file paths are relative to the Joomla root.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Edit /components/com_contact/views/contact/tmpl/default.php. On line 52, change&lt;br/&gt;&lt;tt&gt;&amp;lt;?php echo JHTML::_('image', 'images/stories' . '/'.$this-&amp;gt;contact-&amp;gt;image, ...&lt;/tt&gt;&lt;br/&gt;to&lt;br/&gt;&lt;tt&gt;&amp;lt;?php echo JHTML::_('image', 'images/stories/portraits' . '/'.$this-&amp;gt;contact-&amp;gt;image, ...&lt;/tt&gt;&lt;/li&gt;&lt;li&gt;Edit /administrator/components/com_contact/admin.contact.php. On line 227, change&lt;br/&gt;&lt;tt&gt;$lists['image'] = JHTML::_('list.images', 'image', $row-&amp;gt;image );&lt;/tt&gt;&lt;br/&gt;to&lt;br/&gt;&lt;tt&gt;$lists['image'] = JHTML::_('list.images', 'image', $row-&amp;gt;image, NULL, '/images/stories/portraits/' );&lt;/tt&gt;&lt;/li&gt;&lt;li&gt;Edit /administrator/components/com_contact/admin.contact.html.php. On line 437, change&lt;br/&gt;&lt;tt&gt;jsimg='../&amp;lt;?php echo $cparams-&amp;gt;get('image_path'); ?&amp;gt;/' + ...&lt;/tt&gt;&lt;br/&gt;to&lt;br/&gt;&lt;tt&gt;jsimg='../&amp;lt;?php echo $cparams-&amp;gt;get('image_path'); ?&amp;gt;/portraits/' + ...&lt;/tt&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Afterwards, you will have to open each contact you've previously created and select the portrait anew. I did try doing a bulk edit by exporting the contacts table to CSV and globally replacing, but that was a dismal failure.&lt;/p&gt;&lt;p&gt;The Joomla maintainers are apparently part way through parameterising the location of the stories folder (see the call to &lt;tt&gt;get('image_path')&lt;/tt&gt; above). Ideally the location of the portraits would be a separate parameter. I didn't have time to do this, but this investigation clearly reveals the places where the parameter would need to be used.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-5149299897494824708?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/5149299897494824708/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=5149299897494824708' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/5149299897494824708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/5149299897494824708'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2010/08/custom-image-folder-for-joomla-contacts.html' title='Custom image folder for Joomla Contacts'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-643929024890124314</id><published>2010-07-23T22:54:00.001+01:00</published><updated>2010-07-23T22:54:58.905+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><category scheme='http://www.blogger.com/atom/ns#' term='craftsmanship'/><title type='text'>Turn any program into a Windows service</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;Today, &lt;a href='http://www.foldingsoftware.com/about' target='_blank'&gt;Oisin Mulvihill&lt;/a&gt; introduced me to his company's open source product, &lt;a href='http://www.foldingsoftware.com/servicestation/wiki' target='_blank'&gt;Service Station&lt;/a&gt;. It's very simple, very effective and stunningly useful. I am really surprised that it isn't much better known. With one short shell command, you can install any script or application (headless, command-line or GUI) as a Windows service that can be started, stopped and managed through the Services control panel. As a bonus, Service Station restarts programs that have crashed, cleans up all spawned processes when stopping a service, and provides comprehensive logging via the Windows Event Viewer - it really could not be simpler for the system administrator. It is suitable for every version of Windows from 2000 onwards.&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=40c1c8d2-9fe4-8a93-81ae-89e3749a021f' alt='' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-643929024890124314?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/643929024890124314/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=643929024890124314' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/643929024890124314'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/643929024890124314'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2010/07/turn-any-program-into-windows-service.html' title='Turn any program into a Windows service'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-7738858502282625886</id><published>2010-07-23T22:29:00.002+01:00</published><updated>2010-07-23T22:33:47.161+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Music'/><category scheme='http://www.blogger.com/atom/ns#' term='London'/><title type='text'>Great Music Venue</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;Last night my friends and colleagues from the &lt;a href="http://www.zuhlke.co.uk/" target="_blank"&gt;Zuhlke&lt;/a&gt; office and I, collectively known as &lt;b&gt;Karma4Sale&lt;/b&gt;, enjoyed playing to a packed house at &lt;a href="http://www.myspace.com/peterparkerrocks" target="_blank"&gt;Peter Parker's Rock'n'Roll Club&lt;/a&gt; in Denmark Street, London.&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_eJ-aAjApSE0/TEn-hvccZpI/AAAAAAAABDc/WcS0ryqOh0Q/%5BUNSET%5D.jpg?imgmax=400" style="max-width: 400px;" /&gt;&lt;br /&gt;Thanks to everyone who came along to listen and encourage us, to drummer Chris Sluman (sorry Chris, this is the best photo I have and you're completely invisible in it!), to the brilliant support act of young musicians from the Brit school, and not least to the incredible Mr Peter Parker, who made the evening possible in the first place and gave hands-on support throughout. I sincerely recommend his excellent club if you fancy a great night out either as a listener or as a performer.&lt;br /&gt;&lt;br /&gt;&lt;div class="zemanta-pixie"&gt;&lt;img src="http://img.zemanta.com/pixy.gif?x-id=9d13134c-f520-885b-93d0-49338fe3732f" alt="" class="zemanta-pixie-img" /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-7738858502282625886?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/7738858502282625886/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=7738858502282625886' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/7738858502282625886'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/7738858502282625886'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2010/07/great-music-venue.html' title='Great Music Venue'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_eJ-aAjApSE0/TEn-hvccZpI/AAAAAAAABDc/WcS0ryqOh0Q/s72-c/%5BUNSET%5D.jpg?imgmax=400' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-6717833940023003409</id><published>2010-05-19T10:28:00.002+01:00</published><updated>2010-05-19T10:35:44.513+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='teams'/><category scheme='http://www.blogger.com/atom/ns#' term='software practice'/><category scheme='http://www.blogger.com/atom/ns#' term='craftsmanship'/><title type='text'>BCS SPA2010 conference</title><content type='html'>Final day of the &lt;a href="http://spaconference.org/"&gt;conference &lt;/a&gt;- it's gone much too quickly as usual. My favourite session to date has been the brief whirlwind tour of agile practices given by Gwyn Morfey and Laurie Young of New Bamboo - "the Sword of Integration". This was a highly interactive session that involved everyone standing up and moving about enthusiastically, which despite the cramped room, meant that we all ended up remembering something instantly useful from the session.&lt;br /&gt;&lt;br /&gt;By the way, the sword of integration itself is just one example of an instant solution to a pressing problem. The situation was that multiple developers checking in their changes would cause each other to have merge conflicts. The solution: a paper "sword" quickly assembled, which when held conferred on the holder the right to check in - and hit anyone who checked in when they shouldn't. The principle being illustrated is "just try it" - there is no need to get it absolutely right first time. If it doesn't work, we can change it later.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-6717833940023003409?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/6717833940023003409/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=6717833940023003409' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/6717833940023003409'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/6717833940023003409'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2010/05/bcs-spa2010-conference.html' title='BCS SPA2010 conference'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-589256075950829584</id><published>2010-05-02T12:59:00.004+01:00</published><updated>2010-05-02T13:11:53.048+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='London'/><title type='text'>Real-time arrival information for London Buses</title><content type='html'>... should be &lt;a href="http://www.mobileinc.co.uk/2009/10/transport-for-london-to-enable-bus-tracking-via-sms-mobile-web-in-2011/"&gt;arriving some time in 2011&lt;/a&gt; - provided, of course, that there are no unforeseen traffic problems :-)&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;By the way, the link in that post has become obsolete. Try &lt;a href="http://www.tfl.gov.uk/corporate/projectsandschemes/11560.aspx"&gt;this one&lt;/a&gt; instead.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Meanwhile, some enterprising private individual has connected live running information from various feeds with Google's &lt;a href="http://code.google.com/apis/maps/"&gt;Map API&lt;/a&gt; to create &lt;a href="http://www.livebus.org/greater-london/"&gt;Live Bus&lt;/a&gt; - but for the stops I am principally interested in, it has no information feeds as yet.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-589256075950829584?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/589256075950829584/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=589256075950829584' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/589256075950829584'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/589256075950829584'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2010/05/real-time-arrival-information-for.html' title='Real-time arrival information for London Buses'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-4922425877826446821</id><published>2010-01-28T09:30:00.004Z</published><updated>2010-01-28T10:21:19.683Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='eclipse pde'/><category scheme='http://www.blogger.com/atom/ns#' term='VMWare'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='Ubuntu'/><category scheme='http://www.blogger.com/atom/ns#' term='Mercurial'/><title type='text'>Ubuntu Desktop 9.10</title><content type='html'>For a project recently begun, I needed a Linux virtual machine and I downloaded the excellent &lt;a href="http://chrysaor.info/?page=images"&gt;Chrysaor VMWare appliance&lt;/a&gt; pre-built with Ubuntu Desktop 9.10 (karmic koala) and the VMWare Tools (which actually work as specified - you can cut/paste text and even entire files between your host OS and the VM).&lt;br /&gt;&lt;br /&gt;NB I was only able to download this using a direct internet connection, because our company firewall blocks &lt;a href="http://en.wikipedia.org/wiki/BitTorrent_%28protocol%29"&gt;BitTorrent&lt;/a&gt;. There don't appear to be any FTP or HTTP mirrors of these VMWare images.&lt;br /&gt;&lt;br /&gt;There were just a couple of problems with this virtual machine image, for which I have discovered workarounds.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Timezone persistently defaults to EST, no matter what I do in the time/date control panel. It turns out that certain system files need editing by hand (change to reflect your actual location and language):&lt;br /&gt;&lt;ul&gt;&lt;li&gt;sudo rm /etc/localtime&lt;/li&gt;&lt;li&gt;sudo ln -s /usr/share/zoneinfo/Europe/London /etc/localtime&lt;/li&gt;&lt;li&gt;sudo vi /etc/timezone -- set it to Europe/London&lt;/li&gt;&lt;li&gt;sudo vi /etc/profile -- add the following line at the end:&lt;br /&gt;export TZ=/etc/localtime&lt;/li&gt;&lt;li&gt;sudo vi /etc/default/locale -- set it as follows:&lt;br /&gt;LANG="en_GB.UTF-8"&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Login crash: for a while I thought I had broken the system by installing some upgrade or enabling shared folders. The symptom was that when I logged in, the progress bar would be displayed for a few seconds but instead of displaying the desktop, Ubuntu would restart the windowing system and display the login prompt again. I eventually discovered by trial and error that this was due to starting up in full-screen on my second monitor. Provided I always login while the VM is running in a non-maximised window, it seems very reliable. If you're suffering similar problems, look in your vmware.log file for messages similar to the following:&lt;br /&gt;&lt;pre&gt;VMXVmdbGuestLaunchMenuCB: buf is null.&lt;br /&gt;VMXVmdbGuestLaunchMenuCB: failed: ret = VMDB failure&lt;br /&gt;GuestRpc: Channel 3 reinitialized.&lt;/pre&gt;&lt;/li&gt;&lt;/ol&gt;I recommend that the first thing you do is create a new user ID for yourself with admin rights, and log in under that user to do everything else.&lt;br /&gt;&lt;br /&gt;I upgraded &lt;a href="http://mercurial.selenic.com/wiki/Mercurial"&gt;Mercurial&lt;/a&gt; to 1.4.1 and &lt;a href="http://tortoisehg.bitbucket.org/"&gt;TortoiseHg&lt;/a&gt; to 0.9.2 by downloading the following Debian packages and installing them manually using &lt;span style="font-weight: bold;"&gt;dpkg -i&lt;/span&gt;:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;mercurial_1.4.1-1_i386.deb and mercurial-common_1.4.1-1_all.deb from &lt;a href="ftp://mirror.switch.ch/mirror/ubuntu/pool/universe/m/mercurial/"&gt;ftp://mirror.switch.ch/mirror/ubuntu/pool/universe/m/mercurial/&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;tortoisehg_0.9.2-1_all.deb and tortoisehg-nautilus_0.9.2-1_all.deb from &lt;a href="ftp://mirror.switch.ch/mirror/ubuntu/pool/universe/t/tortoisehg/"&gt;ftp://mirror.switch.ch/mirror/ubuntu/pool/universe/t/tortoisehg/&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;Note that Tortoise doesn't work unless you install the python-iniparse package. Version 0.3.1-1 works with Tortoise 0.9.2-1.&lt;br /&gt;&lt;br /&gt;I was able to get Eclipse (Galileo) as a Ubuntu package and installed the excellent HgEclipse plugin from http://hge.javaforge.com/hgeclipse using the Eclipse "Install New Software" option.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-4922425877826446821?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/4922425877826446821/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=4922425877826446821' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/4922425877826446821'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/4922425877826446821'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2010/01/ubuntu-desktop-910.html' title='Ubuntu Desktop 9.10'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-4345764685172973845</id><published>2010-01-13T11:30:00.002Z</published><updated>2010-01-13T11:32:58.907Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='software practice'/><category scheme='http://www.blogger.com/atom/ns#' term='craftsmanship'/><title type='text'>Craftsmanship for Teams</title><content type='html'>Very interesting discussion thread on &lt;a href="http://groups.google.co.uk/group/software_craftsmanship/browse_thread/thread/1403b2d25877332f"&gt;Software Craftsmanship as a team exercise&lt;/a&gt;. In response to Cory Foy's posting, Steven Smith makes an interesting analogy with coaching a sports team and says how that is actually carried through in his practice.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-4345764685172973845?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/4345764685172973845/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=4345764685172973845' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/4345764685172973845'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/4345764685172973845'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2010/01/craftsmanship-for-teams.html' title='Craftsmanship for Teams'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-3655512453231039450</id><published>2010-01-13T10:25:00.002Z</published><updated>2010-01-13T10:44:22.186Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Software Configuration Management'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><category scheme='http://www.blogger.com/atom/ns#' term='Mercurial'/><title type='text'>Mercurial - managing a repository</title><content type='html'>Last Autumn, I set up a repository server with &lt;a href="http://www.selenic.com/mercurial/"&gt;Mercurial&lt;/a&gt;. While not particularly difficult, it took a while to get all the configuration exactly correct, in particular, to leave no security loopholes. With some assistance from &lt;a href="http://www.zuehlke.com/"&gt;Zuhlke's&lt;/a&gt; IT centre, this was satisfactorily completed and the server is in production use.&lt;br /&gt;&lt;br /&gt;It takes a little while to get used to the idea that you can't just access files directly from the repository server, as you can with &lt;a href="http://www.nongnu.org/cvs/"&gt;CVS&lt;/a&gt; and &lt;a href="http://subversion.tigris.org/"&gt;Subversion&lt;/a&gt;. Instead, anyone wishing to get hold of the repository contents has to install a copy of the Mercurial software on their own machine (on Windows PCs, my choice would be &lt;a href="http://tortoisehg.bitbucket.org/"&gt;TortoiseHg&lt;/a&gt;) and "clone" the repository. While this makes it a bit tedious for someone who just needs one or two files out of a big repository, it's great for teams of developers who can each check files in and out of their local workspace before merging a consistent set of changes with the central development branch.&lt;br /&gt;&lt;br /&gt;I was quite surprised, however, by the lack of web-based admin facilities. There ought to be a control panel to allow suitably authorised people to create and delete collections of repositories with specified access permissions, set up and delete repository user accounts etc. Currently you have to use the shell commands and in some cases, this involves superuser privileges (e.g. to change ownership of new repositories to www-data so that the Apache FCGI scripts can access them).&lt;br /&gt;&lt;br /&gt;Because I was unable to find such a facility either natively or under &lt;a href="http://www.webmin.com/"&gt;Webmin&lt;/a&gt;, I have embarked on developing some scripts to provide these functions. I have adapted the Python scripts and modules, HTML templates and stylesheets of Mercurial itself for the purpose. Anyone keen to help or to get access to this code is invited to contact me - immo.huneke _a_ zuhlke.com.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-3655512453231039450?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/3655512453231039450/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=3655512453231039450' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/3655512453231039450'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/3655512453231039450'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2010/01/mercurial-managing-repository.html' title='Mercurial - managing a repository'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-430275768568252710</id><published>2010-01-13T10:23:00.001Z</published><updated>2010-01-13T10:25:33.018Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Transport'/><category scheme='http://www.blogger.com/atom/ns#' term='London'/><title type='text'>Unimaginative train operators</title><content type='html'>I was infuriated by the actions of the railway company SouthEastern and London Underground this morning, which added to the aggravation caused by the weather.&lt;br /&gt;&lt;br /&gt;Due to an accident (I assume) Stafford Road between Wallington and the A23 was gridlocked, so my usual bus into Croydon was not likely to run any time soon.&lt;br /&gt;&lt;br /&gt;I trudged through the snow to the nearest railway station and did manage to catch a train into London Bridge. It took nearly twice as long as normal, and when we arrived, London Bridge station was very congested. The Underground station entrance had been closed "due to overcrowding" (due to lack of trains I think). Everyone went to Platform 6 to try to get on a service to Charing Cross or Waterloo.&lt;br /&gt;&lt;br /&gt;Several trains came and went, too full to take more than a few passengers. Then a half-empty one came in and stopped but the doors did not open. Eventually an announcement was made that this train was not due to stop at this station. But since it had stopped anyway at a red light, why didn't they open the doors and clear some of the backlog of frustrated passengers?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-430275768568252710?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/430275768568252710/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=430275768568252710' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/430275768568252710'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/430275768568252710'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2010/01/unimaginative-train-operators.html' title='Unimaginative train operators'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-857665899452154540</id><published>2010-01-06T20:34:00.004Z</published><updated>2010-01-06T20:57:04.540Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Religion'/><category scheme='http://www.blogger.com/atom/ns#' term='Politics'/><title type='text'>Making Life Hell?</title><content type='html'>A friend, who I think is a Moslem, sent me the attached "quick and dirty" translation of an article in &lt;a href="http://www.milliyet.com.tr/Yazar.aspx?aType=YazarDetay&amp;KategoriID=4&amp;ArticleID=1181459&amp;PAGE=1"&gt;Milliyet&lt;/a&gt; by Semih I'diz. He asked for his name not to be published. My response is shown below.&lt;br /&gt;&lt;hr/&gt;&lt;br /&gt;They are Making Life Hell for Moslems&lt;br/&gt;&lt;br /&gt;Semih I˙diz sidiz@milliyet.com.tr&lt;br/&gt;&lt;br /&gt;Monday, 4 January 2010&lt;br /&gt;&lt;br /&gt;First, a Nigerian madman called Ömer Faruk Abdulmuttalib is caught while trying to blow up an American passenger plane. After that, a young man from Somalia, whose name was not disclosed, tries to kill the danish cartoonist Kurt W Estergaard, who caused indignation in the moslem world with his Mohammed cartoons.&lt;br /&gt;&lt;br /&gt;Then, life becomes unbearable again for the moslems in the west. There are increased signs that this is not a transitional but a permanent condition. The congregation leaders of millions of moslems living in the west remain spectators while their living space shrinks.&lt;br /&gt;&lt;br /&gt;Basic reason is "cultural differences". The aforementioned congregation leaders cannot bring themselves to demonstrate the condemning stance that would satisfy the western public, although they live in the west and share the benefits of doing so.&lt;br /&gt;&lt;br /&gt;They limit their reactions to a few "politically required" public statements. When they try to explain the situation by referring to Israel or to the US invasion of Iraq, they only increase the indignation felt against moslems.&lt;br /&gt;&lt;br /&gt;We are talking about the psychology of the western society within which millions of moslems are living. The fact that people walking on the streets in the west are killed in the name of Islam cancels out the "explanatory arguments" of the moslem congregation leaders.&lt;br /&gt;&lt;br /&gt;Under these circumstances, the "man on the street" in the west, who is not very sophisticated to start with, cannot see the difference between the few madmen misusing religion and the millions of moslems going after their business and who want to live without upsetting anyone.&lt;br /&gt;&lt;br /&gt;To summarise, one cannot explain to a Dutch person the killling of Theo Van Gogh in the name of Islam, irrespective of what an unpleasant person he was. One cannot explain the knife-and-axe attack on Westergaard while he was sitting at home with his grandson, even if he was beginning to show extreme right-wing tendencies.&lt;br /&gt;&lt;br /&gt;In the meanwhile, we can also see that the aggressive madmen we mentioned are providing the opportunity to the extreme Right in the west for developing its anti-moslem arguments. Indeed, after the attack on Westergaard, calls of "Throw out the moslems that do not adhere to our laws and customs" have immediately started in Denmark.&lt;br /&gt;&lt;br /&gt;One also needs to see the minaret referendum in Switzerland in the same framework. Actually, Switzerland is one of the countries in Europe with the least of issues with its moslem minority. In spite of this, the terror being carried out in the world in the name of Islam has caused even the Swiss public to take an anti-moslem stance.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://fra.europa.eu/fraWebsite/home/infocus09_0712_en.htm"&gt;A study carried out recently&lt;/a&gt; by the "European Union Agency for Fundamental Rights" disclosed the negative developments in Europe regarding moslems. According to this study, if you are a moslem or you "look like a moslem", your chances of finding a job, moving to certain neighbourhoods or even moving freely within society is becoming increasingly difficult.&lt;br /&gt;&lt;br /&gt;Some even see the plans for installing "naked body" scanners in European airports as a result of the attack of the Nigerian madman in the same framework. After a certain point, being naked is not such an issue for a western person. There will be many who will say "I accept it for security".&lt;br /&gt;&lt;br /&gt;The situation among moslems is totally different due to the understanding of privacy as well as religious and cultural values. The covering up of women already shows the sensitivity there. According to some voices, once this equipment is in operation, moslems will give up travelling to the west or travelling outside the countries they live in the west.&lt;br /&gt;&lt;br /&gt;Thus, the factors of security and control will increase. Those who do not accept these factors will "return to where they came from and remain there". This is the largest consequence from the deeds of the 9/11 criminals, the madmen from Somalia and Nigeria.&lt;br /&gt;&lt;br /&gt;They do not contribute to improving the living conditions of moslems in the Gaza Strip or Iraq. Just the opposite, either consciously or intentionally, they play into the hands of the extreme-rightists in Europe, such as Geert Wilders.&lt;br /&gt;&lt;br /&gt;To put it in a nutshell, they bring about the conditions for making life hell for moslems in the west.&lt;br /&gt;&lt;hr/&gt;&lt;br /&gt;Hi xxxxx,&lt;br /&gt;&lt;br /&gt;Thanks for the article. Thought-provoking reading first thing in the morning! I will think carefully about forwarding it. I think that particularly the point about the full-body scanners at airports (and major rail stations as well, quite possibly - did you know about that?) is well made. I hadn't previously considered their likely impact on members of certain religions, though I don't feel particularly comfortable myself even being "patted down" and wouldn't relish the thought of effectively being inspected without my clothes on.&lt;br /&gt;&lt;br /&gt;It isn't only Moslems who are being impacted by the extra "security" measures. They make life more expensive and less convenient for everyone, though possibly to a greater degree for members of certain races and religious minorities in the West. In some ways, this plays into the hands of the extremists. During WWII, the British public was determined not to let the enemy destroy their way of life, so beyond taking a few precautions such as a blackout against bombers, and evacuating children from the big cities, they cheerfully carried on regardless of the war. I think it's time to rediscover that resolve to live proudly according to the values we believe in, keep our eyes and ears open, and take a few risks for the sake of a well-balanced society.&lt;br /&gt;&lt;br /&gt;Lutheran theologian Dietrich Bonhoeffer wisely warned (in 1934!) that safety and security are mutually exclusive. What he meant was that if nation states entered a race to build up their defences in the name of peace, they would endanger everyone by exposing them to a greater risk of war - and how right he was. We are facing a similar situation today. There is a global threat to civilised society from some sadly deluded religious fanatics. Those who think that the threat can be averted by military means are similarly deluded and similarly threaten civil liberties. Another way must be found. For almost 30 years, the United Kingdom faced fanatical Irish nationalists who were prepared to sacrifice innocent lives on a massive scale to pursue their political ends. It was only when we abandoned our entrenched positions and began to negotiate that an accommodation became possible. It even turned out that at least some of the nationalists were not such odious individuals after all.&lt;br /&gt;&lt;br /&gt;Instead of expending prodigious resources in the "war on terror", we should all be pulling together to face common threats, such as climate change and mass extinction of rare species. Also see &lt;a href="http://www.spacedaily.com/reports/Russian_Scientists_Warn_Of_Asteroid_Impact_Hazard_In_2035_999.html" target="_blank"&gt;this story&lt;/a&gt;. Let's hope that the world can come to its senses in the nick of time, as it usually seems to manage. Is that a hopeful message with which to begin the year 2010?&lt;br /&gt;&lt;br /&gt;Best regards,&lt;br /&gt;Immo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-857665899452154540?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/857665899452154540/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=857665899452154540' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/857665899452154540'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/857665899452154540'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2010/01/making-life-hell.html' title='Making Life Hell?'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-5927281713235749175</id><published>2010-01-06T11:30:00.001Z</published><updated>2010-01-06T11:33:32.491Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='publishing'/><category scheme='http://www.blogger.com/atom/ns#' term='craftsmanship'/><title type='text'>Software Engineering Best Practices</title><content type='html'>&lt;a href="http://www.gilb.com/"&gt;Tom Gilb&lt;/a&gt; recommends Capers Jones's latest book &lt;a href="http://bit.ly/4sxShQ"&gt;Software Engineering Best Practices&lt;/a&gt;. From my quick reading of the preface and introduction, it certainly looks like a thorough piece of work!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-5927281713235749175?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/5927281713235749175/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=5927281713235749175' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/5927281713235749175'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/5927281713235749175'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2010/01/software-engineering-best-practices.html' title='Software Engineering Best Practices'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-5118194936665305394</id><published>2009-09-05T21:47:00.003+01:00</published><updated>2009-09-05T21:57:08.521+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Water'/><category scheme='http://www.blogger.com/atom/ns#' term='Space'/><title type='text'>Another space tourist - so what?</title><content type='html'>I've just read about Guy Laliberté's &lt;a href="http://www.onedrop.org/en/mission_space/poetic_social_mission.aspx"&gt;Poetic Social Mission&lt;/a&gt; for the One Drop Foundation. The seventh private space traveller is doing more with his once-in-a-lifetime opportunity than just enjoying himself - he plans to stage a worldwide music and arts event involving himself aboard the ISS, to draw attention to the worldwide need for fair and equitable access to water.&lt;br /&gt;&lt;br /&gt;The guest list sounds brilliant (Peter Gabriel, U2, Shakira and many others) - the downside is that the two-hour spectacular is due to kick off at 8pm Eastern on October 9th, which makes it about 1am in our time zone. I think it's being broadcast via YouTube, so perhaps we'll be able to watch it later on? Details about this are a bit sketchy at the moment - the site just says "broadcast right here".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-5118194936665305394?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/5118194936665305394/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=5118194936665305394' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/5118194936665305394'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/5118194936665305394'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2009/09/another-space-tourist-so-what.html' title='Another space tourist - so what?'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-8153034482690004216</id><published>2009-08-05T21:58:00.003+01:00</published><updated>2009-08-05T22:26:38.414+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Comedy'/><category scheme='http://www.blogger.com/atom/ns#' term='Heritage'/><title type='text'>Save Bletchley Park with Boffoonery!</title><content type='html'>&lt;p&gt;The title says it all really.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.codemanship.com/"&gt;Jason Gorman&lt;/a&gt; has managed to get some amazing events off the ground in the past couple of years and this one should be absolutely excellent. It's called &lt;b&gt;Boffoonery!&lt;/b&gt; ("buffoonery for boffins") - a once-only comedy benefit gig to raise money for the extremely important &lt;a href="http://www.bletchleypark.org/"&gt;wartime heritage site&lt;/a&gt; (Station X) and unique &lt;a href="http://www.tnmoc.org/"&gt;computing museum&lt;/a&gt; that is &lt;a href="http://www.boffoonery.com/about.html"&gt;Bletchley Park&lt;/a&gt; near Milton Keynes.&lt;/p&gt;&lt;p&gt;Jason's partners in crime are comedy writer James Cary, whose credits include hit TV comedies like My Hero and My Family and who also writes the cult BBC Radio 4 sitcom Hut 33, which is set at Bletchley Park, and veteran TV and radio comedy producer David Tyler.&lt;/p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.tnmoc.org/UserFiles/image/home-img2.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 99px; height: 99px;" src="http://www.tnmoc.org/UserFiles/image/home-img2.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;p&gt;The show is still taking shape, but Jason is delighted to be able to confirm that Robert Llewellyn (Red Dwarf), Richard Herring (Fist Of Fun, This Morning With Richard Not Judy) and cerebral stand-up Robin Ince are on the bill. More big name comedians and comedy writers are TBA, so keep en eye out for updates.&lt;/p&gt;&lt;p&gt;The best way we can support Bletchley Park is to send a message to government and funding bodies about how much we care. If the show were to sell out, and sell out quickly, that would send a very clear message indeed.&lt;/p&gt;&lt;p&gt;And since you ask - yes, you can help. Tickets go on sale on Wednesday Aug 12th at 9am. Please help to spread the word and create a splash on Wednesday. Here are some of the ways you can help:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Buy your tickets on Aug 12th&lt;/li&gt;&lt;li&gt;Tell your friends and colleagues about Boffoonery!, and encourage them to buy their tickets on Aug 12th&lt;/li&gt;&lt;li&gt;Print off copies of the show's A4 poster, which you can download from &lt;a href="http://www.boffoonery.com/"&gt;www.boffoonery.com&lt;/a&gt;, and stick them up on your noticeboards at work&lt;/li&gt;&lt;li&gt;Blog about Boffoonery, and pass on these suggestions about how people can help save Bletchley Park&lt;/li&gt;&lt;li&gt;If you're a Twitter user, on the morning of Aug 12th send a tweet about #boffoonery and &lt;a href="http://www.boffoonery.com/"&gt;www.boffoonery.com&lt;/a&gt;, and RT any #boffoonery tweets that cross your path&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;It's going to be brilliant evening, and your kindness and generosity will ensure that generations to come will be able to see and experience the achievements of those brilliant boffins whose ingenuity saved 22 million lives and ushered in the information age.&lt;/p&gt;&lt;p&gt;You can find out more by visiting &lt;a href="http://www.boffoonery.com/"&gt;www.boffoonery.com&lt;/a&gt;, or following #boffoonery on Twitter or "boffoonery" on Facebook.&lt;/p&gt;&lt;div&gt;A pity there isn't a theatre big enough in Bletchley Park itself to host this event! That said, the Bloomsbury Theatre is easier for me to get to...&lt;/div&gt;&lt;p&gt;Don't forget: tickets go on sale on 12th August 2009 at 9am and the show takes place on Tuesday Nov 3rd.&lt;/p&gt;&lt;p&gt;PS other efforts to support the National Museum of Computing at Bletchley Park include this amazing &lt;a href="http://stnx.at/"&gt;URL Shortener&lt;/a&gt; called &lt;b&gt;Station X&lt;/b&gt;. Keep up the good work, guys!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-8153034482690004216?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/8153034482690004216/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=8153034482690004216' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/8153034482690004216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/8153034482690004216'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2009/08/save-bletchley-park-with-boffoonery.html' title='Save Bletchley Park with Boffoonery!'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-4160166869086850417</id><published>2009-07-27T09:36:00.002+01:00</published><updated>2009-07-27T09:47:29.858+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='homelessness'/><category scheme='http://www.blogger.com/atom/ns#' term='London'/><category scheme='http://www.blogger.com/atom/ns#' term='Credit Crunch'/><title type='text'>Gimme Shelter</title><content type='html'>A friend has been made homeless - as a result of a bout of illness, he got behind with his rent payments. One morning his landlord just turned up with a heavy friend and dumped him and most of his belongings outside without a key.&lt;br /&gt;&lt;br /&gt;While this is clearly an illegal eviction (the landlord should have taken the court route), my friend is unable to defend himself because he's still not well and besides, he's sure that no-one will believe his version of events. Well, it is fairly monstrous.&lt;br /&gt;&lt;br /&gt;Today he rang &lt;a href="http://www.shelter.org.uk/"&gt;Shelter&lt;/a&gt; to try to obtain help (having already had a pretty hopeless interview with the emergency housing office in his borough - they took the attitude that since he didn't have a court order evicting him, he must have made himself intentionally homeless). He reports that he got an answerphone message that began "Welcome to Shelter. Please note that &lt;span style="font-weight: bold;"&gt;we cannot provide accommodation&lt;/span&gt;..."&lt;br /&gt;&lt;br /&gt;Well, what on Earth is Shelter for then?&lt;br /&gt;&lt;br /&gt;I am also disappointed that &lt;a href="http://www.salvationarmy.org.uk/"&gt;The Salvation Army&lt;/a&gt; was unwilling to help him - I have been supporting it with a regular monthly donation for years as I was under the impression that it provided help to the homeless.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-4160166869086850417?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/4160166869086850417/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=4160166869086850417' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/4160166869086850417'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/4160166869086850417'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2009/07/gimme-shelter.html' title='Gimme Shelter'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-1083907608671303711</id><published>2009-07-20T13:48:00.004+01:00</published><updated>2009-07-20T14:52:09.842+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='security'/><category scheme='http://www.blogger.com/atom/ns#' term='authentication'/><category scheme='http://www.blogger.com/atom/ns#' term='privacy'/><title type='text'>Passwords passé?</title><content type='html'>I've just read a highly amusing and (for Twitter) &lt;a href="http://www.basexblog.com/2009/07/16/google-apps-twitter-hack-raises-red-flags-on-password-security/"&gt;embarrassing story&lt;/a&gt; about the loss of confidential information stored by a Twitter staffer under Google Apps.&lt;br /&gt;&lt;br /&gt;The article closes by trotting out the usual advice about making usernames and passwords secure - make them long and cryptic, don't use the same credentials for more than one service, and don't write them down. However, I heard a piece on BBC Radio 4 not long ago in which Damian Grammaticus investigated computer security and hacking. It showed that any Windows password under 14 characters long could be cracked in seconds, regardless of how many punctuation characters and digits it contained. Since we're all forced to register with dozens, if not hundreds of different IT services on the Internet and our employers' networks, it simply isn't possible for standard-issue mortals to memorise that many cryptic usernames and passwords (particularly where IT policy demands that the password be changed regularly).&lt;br /&gt;&lt;br /&gt;Common approaches to overcome these wetware limitations include&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Writing usernames and passwords down - not recommended because anyone could find them and steal your precious secret information&lt;/li&gt;&lt;li&gt;Using a standard username and password for many different sites - again not recommended because if a thief finds out one valid combination, (s)he can access all your accounts&lt;/li&gt;&lt;li&gt;Generating usernames and passwords by means of some function, which you can compute mentally without too much effort and which preferably takes the current month and/or the URL of the service as parameters - this works OK in certain situations, but because the algorithm can't be terribly complicated, someone could reverse-engineer it and have access to all your accounts&lt;/li&gt;&lt;li&gt;Using a password manager application: something that you install on your laptop (say) and which stores all your usernames and passwords for you, encrypted of course, so that you can only gain access using a master password or even biometric authentication - disadvantages may include the risk of losing the device or the master access key, as well as the inconvenience of having to have the device to hand whenever you need one of your account credentials (not to mention the cost of the password manager itself)&lt;/li&gt;&lt;li&gt;Trusting an Internet service such as DataInherit to manage the keys for you, which has the advantage that should you die or be incapacitated, a nominated person or persons can automatically be given access to selected accounts in your portfolio - disadvantages include the price and the number of steps you have to go through to retrieve any given username and password&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Surely the time is ripe for a security architecture that fully separates authentication from authorisation. Depending on your spending power and level of paranoia, you could procure authentication services from any reputable trust authority of your choosing, which could make use of a single very secure identifier and pass phrase, optionally combined with more stringent authentication factors such as digital certificates, RSA SecurID devices, or even biometrics. The identity thus established would be securely and trustworthily conveyed to whatever service you were trying to access - regardless of whether it is on a company intranet, the public Internet or your ATM network.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Unfortunately the Twitters and Googles of this world, not to mention the myriad online shopping sites, still want you to register with them directly and not with some third-party authentication provider. This is because they believe that there's value in knowing your real world (meatspace) name and address, age, marital status and what have you so that they can push targeted marketing at you. It doesn't seem to bother them that the majority of the data thus gathered is probably untrue, because most Internet users are paranoid about giving away such information.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I want single sign-on to be ubiquitous, effortless, virtually unhackable and foolproof (as well as heritable, as directed by me, when I leave this world, so that my digital assets are not locked away forever). By "ubiquitous", I mean that I should be able to use the same sign-on for my employer's network as for any client's network which wants to authorise me to access some selection of their IT services, for Internet services on which I register and preferably at the bank's ATM too. By "effortless", I mean that authenticating myself to all these services is necessary only once per computer per day and ideally doesn't require me to memorise anything, or at most one thing. A physical token in addition, or a biometric, would be acceptable.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The theoretical foundations already exist, underpinning such standards as &lt;a href="http://en.wikipedia.org/wiki/Kerberos_(protocol)"&gt;Kerberos&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/WS-Trust"&gt;WS-Trust&lt;/a&gt;. But to make it work in the real world of competing and highly disparate IT services, the community of service providers would need to discover some kind of shared interest in implementing it as standard. A &lt;a href="http://bcs.org/server.php?show=conWebDoc.2844"&gt;grand computing challenge&lt;/a&gt; for the new millennium, perhaps?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-1083907608671303711?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/1083907608671303711/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=1083907608671303711' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/1083907608671303711'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/1083907608671303711'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2009/07/passwords-passe.html' title='Passwords passé?'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-7951850868462003290</id><published>2009-06-15T17:40:00.001+01:00</published><updated>2009-06-15T17:40:10.719+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='software practice'/><category scheme='http://www.blogger.com/atom/ns#' term='test-driven development'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='craftsmanship'/><title type='text'>Test-Driven Design is not testing</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;I've recently worked with a team doing its first agile project (though one or two team members had been involved in an agile project before). The most difficult concept to get across was TDD - test driven design. I found that people really didn't grok the idea until I pair-programmed with them for a couple of hours. I wonder why that might be.&lt;br/&gt;&lt;br/&gt;&lt;a href='http://behaviour-driven.org/Introduction' target='_blank'&gt;Dan North&lt;/a&gt; has suggested one possibility. He observed that newcomers to TDD often don't get the really big payback because they continue to think that TDD is mainly about testing - even if they will admit that writing the tests before the code leads to better quality code. They never transition to treating TDD as a design process, letting them discover the API to a component they're writing, nor to the realisation that TDD is about defining the behaviour of their component and its interactions with other components of the system.&lt;br/&gt;&lt;br/&gt;&lt;a href='http://peripateticaxiom.blogspot.com/2008/03/tests-and-gauges.html' target='_blank'&gt;Keith Braithwaite&lt;/a&gt; has put forward another consideration. In physical engineering disciplines, practitioners speed up their work process by using gauges. There are many kinds, from the simple spark plug gap gauge, which is simply a sliver of metal to slide between the electrodes, to electronic vernier calliper gauges that can be pre-set to a precise dimension with tolerances above and below. Each workpiece is tested at each stage of the process by checking its dimensions with the appropriate gauge(s). Workpieces that are out of tolerance are sent back for rework or scrapped. Our unit tests are a bit like that - they provide a safeguard that the software component we're working on still meets all its requirements following any engineering we've done.&lt;br/&gt;&lt;br/&gt;It occurred to me today that unit and acceptance tests, particularly if automated, perform another valuable function in the context of an agile (especially a lean) development process. Whereas the waterfall processes familiar to most developers are characterised by "quality gates" at key stages, every single artifact in an agile development has its own little quality gate, manifested in the appropriate tests. This theoretically frees the development process from the usual bottlenecks that the quality gates tend to become.&lt;br/&gt;&lt;br/&gt;I say "theoretically", because in many instances agile development projects have to take place within a quality system that doesn't take advantage of incremental delivery. Instead, continued approval and in many cases funding for the project tends to be contingent on passing the traditional quality gates following requirements analysis, functional specification, high-level design, low-level design, coding, integration, system test and acceptance. Project managers are therefore forced to conjure up some kind of spurious linkage between the milestones laid down in the rigid quality system and some arbitrary points along their product release plan. This can hamper their freedom to adjust the release plan in response to changing circumstances and emerging technical insights.&lt;br/&gt;&lt;br/&gt;This could be avoided if the quality system could recognise that properly written tests represent every work product of a software development project apart from the code itself. It should therefore simply insist on a verification at each iteration (or at each release, perhaps) that the tests comprehensively and comprehensibly represent the requirements of the business on the system under development and that the required set of tests pass repeatably. I say "the required set" because there's always the possibility that some tests will intentionally fail - e.g. where they have been written to test features that are not yet in the current release.&lt;br/&gt;&lt;br/&gt;In other words, TDD can be used to eliminate the quality-gate bottlenecks of quality systems that assume waterfall development processes.&lt;br/&gt;&lt;br/&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-7951850868462003290?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/7951850868462003290/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=7951850868462003290' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/7951850868462003290'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/7951850868462003290'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2009/06/test-driven-design-is-not-testing.html' title='Test-Driven Design is not testing'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-2076625803593208626</id><published>2009-05-15T11:59:00.004+01:00</published><updated>2009-05-15T12:11:32.959+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='teams'/><category scheme='http://www.blogger.com/atom/ns#' term='software practice'/><category scheme='http://www.blogger.com/atom/ns#' term='lean'/><title type='text'>24th March 2009: Theory of Constraints Challenged</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;My sincere thanks to &lt;a href='http://www.kevinrutherford.co.uk/' target='_blank'&gt;Kevin Rutherford&lt;/a&gt; and &lt;a href='http://www.allankelly.net/'&gt;Allan Kelly&lt;/a&gt; for co-presenting a fascinating session about lean software development to the &lt;a href='http://www.bcs.org/server.php?show=nav.9418' target='_blank'&gt;BCS Kingston &amp;amp; Croydon branch&lt;/a&gt; on 24th March this year, entitled &lt;a href='http://www.bcs.org/server.php?show=ConWebDoc.20825' target='_blank'&gt;"Lean, Constraints, Action!"&lt;/a&gt;. The audience was excellent too and helped us re-create a famous experiment related by &lt;a href='http://www.toc-goldratt.com/index.php?cont=21' target='_blank'&gt;Eliyahu Goldratt&lt;/a&gt; in &lt;a href='http://www.amazon.co.uk/Goal-Process-Ongoing-Improvement/dp/0566086654/' target='_blank'&gt;"The Goal"&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lh3.ggpht.com/_eJ-aAjApSE0/Sg0_y8h-PxI/AAAAAAAABAw/s1NXA4h0kR4/%5BUNSET%5D.jpg" target=_blank&gt;&lt;img src='http://lh3.ggpht.com/_eJ-aAjApSE0/Sg0_y8h-PxI/AAAAAAAABAw/s1NXA4h0kR4/%5BUNSET%5D.jpg?imgmax=800' style='max-width: 400px;'/&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;(Click images to see a larger version)&lt;br /&gt;&lt;br /&gt;I had participated in &lt;a href='http://www.vancouver.wsu.edu/fac/holt/em530/Docs/DiceGames.htm' target='_blank'&gt;this game&lt;/a&gt; previously at the London &lt;a href='http://www.xpday.org/2008/keynotes' target='_blank'&gt;XP Day 2008&lt;/a&gt; (facilitated by &lt;a href='http://availagility.wordpress.com/' target='_blank'&gt;Karl Scotland&lt;/a&gt; in an Open Space session). It is designed to demonstrate an intuitively paradoxical finding: that a lean, pull-oriented flow substantially reduces the amount of inventory or work in progress (WIP), &lt;b&gt;while improving throughput&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;However, I had a sneaky feeling that the experiment was biased, because in the first "push" simulation, the assembly line was not pre-loaded with WIP, while in the second "pull" simulation, the line was pre-loaded with workpieces at each "workstation's" input buffer up to either the maximum limit or to 50% of that limit. Therefore in a simulation of 10 rounds (equivalent to ten working days - approximately equal to the average cycle time in a six-workstation setup) the push simulation will only start to produce output towards the very end of the simulation, while the pull simulation will produce something from the very first day.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lh5.ggpht.com/_eJ-aAjApSE0/Sg1En5KocGI/AAAAAAAABA0/JQiC0iXe01o/%5BUNSET%5D.jpg" target=_blank&gt;&lt;img src='http://lh5.ggpht.com/_eJ-aAjApSE0/Sg1En5KocGI/AAAAAAAABA0/JQiC0iXe01o/%5BUNSET%5D.jpg?imgmax=800' style='max-width: 400px;'/&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;So I got Allan and Kevin to agree to vary the rules a little bit, to try to get closer to a "steady state" from the first "day". Before each of the two simulations, our teams placed three Lego blocks on each of the coasters representing the input buffers of the second through sixth workstations (the first workstation of course has the whole of the product backlog as its input hopper). In fact, as it turned out, four workpieces would have been closer to the true steady state in the pull simulation, even more in the push simulation.&lt;br /&gt;&lt;br /&gt;Off our teams went and played the production line for ten rounds each. In the push simulation, the die was passed in order from workstation 1 to workstation 6 during each round and the number of workpieces transferred to the next input buffer was the number thrown, up to the number of pieces available in the workstation's input buffer. Instances of starvation were rare under this system, but did occur sometimes. At the end we counted up the number of pieces that had come off the end of the line and the number currently in progress (i.e. on any of the five input buffers for workstations 2 to 6).&lt;br /&gt;&lt;br /&gt;In the pull simulation, the die was passed in the opposite direction and the input buffers were constrained to a maximum of six workpieces. So if the next input buffer had three pieces already in it and the player threw anything over a 3, they could only pass along 3 more workpieces (subject to their own input buffer holding at least 3, of course). Once again, the results after 10 rounds were compared.&lt;br /&gt;&lt;br /&gt;The results didn't surprise me particularly, but I think some of the others were a little taken aback:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lh3.ggpht.com/_eJ-aAjApSE0/Sg1IHLqFAcI/AAAAAAAABA4/EcfUcmYO2Sg/%5BUNSET%5D.jpg" target=_blank&gt;&lt;img src='http://lh3.ggpht.com/_eJ-aAjApSE0/Sg1IHLqFAcI/AAAAAAAABA4/EcfUcmYO2Sg/%5BUNSET%5D.jpg?imgmax=800' style='max-width: 400px;'/&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As you can see, the constraint resulted in both lower WIP and lower throughput. This makes sense when you consider that there were far more occasions during the pull game than during the push game when players were unable to process the full number of workpieces indicated by the die.&lt;br /&gt;&lt;br /&gt;Looking back at the &lt;a target='_blank' href='http://www.vancouver.wsu.edu/fac/holt/em530/Docs/DiceGames.htm'&gt;game notes&lt;/a&gt;, it is noted that if the simulation is run for much longer than 10 days, the pull (or Kanban) system "will rarely produce as much as the traditional push". This may have escaped the attention of some readers (or perhaps it's a more recent edit - I don't know).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lh4.ggpht.com/_eJ-aAjApSE0/Sg1J_0PTIvI/AAAAAAAABA8/mMHU63cb0ek/%5BUNSET%5D.jpg" target=_blank&gt;&lt;img src='http://lh4.ggpht.com/_eJ-aAjApSE0/Sg1J_0PTIvI/AAAAAAAABA8/mMHU63cb0ek/%5BUNSET%5D.jpg?imgmax=800' style='max-width: 400px;'/&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;My conclusion is that you get nothing for free. The cost of reducing WIP is reduced throughput, which is perfectly acceptable as long as you're aware of it. Software development projects are not production lines in any case, so it is very unlikely that any developer will sit around kicking her or his heels if the work runs out on a given day. There are always low priority tasks such as fettling the build system, cleaning up the documentation on the project Wiki, answering user support requests etc. - or just take the next item off the product backlog and raise the kanban limit temporarily.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-2076625803593208626?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/2076625803593208626/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=2076625803593208626' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/2076625803593208626'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/2076625803593208626'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2009/05/24th-march-2009-theory-of-constraints.html' title='24th March 2009: Theory of Constraints Challenged'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_eJ-aAjApSE0/Sg0_y8h-PxI/AAAAAAAABAw/s1NXA4h0kR4/s72-c/%5BUNSET%5D.jpg?imgmax=800' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-3223512199395535088</id><published>2009-05-05T16:56:00.002+01:00</published><updated>2009-05-05T17:06:33.706+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='software practice'/><category scheme='http://www.blogger.com/atom/ns#' term='craftsmanship'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Distributed bug-tracking in Haskell</title><content type='html'>At the recent &lt;a href="http://www.spaconference.org/spa2009/"&gt;SPA 2009&lt;/a&gt; conference, there was a lot of talk about functional programming, Haskell in particular (a couple of years ago, the flavour of the month had been Erlang). Just to prove that Haskell is no longer "just a research language", along comes &lt;a href="http://www.distract.wellquite.org/"&gt;DisTract&lt;/a&gt;, a distributed issue-tracking system that runs in Firefox browsers. If you're already using Git, Darcs, Mercurial or Monotone as your distributed software configuration management solution, the author reasoned, why shouldn't you be able to close bugs while you're off-line at the same time as you check in your fix? Caveat: I have not tried this yet, but it sounds like a really neat idea. Does anyone know of a user forum?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-3223512199395535088?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/3223512199395535088/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=3223512199395535088' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/3223512199395535088'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/3223512199395535088'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2009/05/distributed-bug-tracking-in-haskell.html' title='Distributed bug-tracking in Haskell'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-8492371426030123673</id><published>2009-04-09T14:02:00.002+01:00</published><updated>2009-04-09T14:26:16.449+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='software practice'/><category scheme='http://www.blogger.com/atom/ns#' term='test-driven development'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='London'/><title type='text'>SPA2009 - first impressions</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;Maybe I'm biased, of course, but for me the &lt;a href='http://www.spaconference.org/spa2009/' target='_blank'&gt;SPA2009&lt;/a&gt; conference felt even better than last year's. I think it had the right mix of technical and non-technical sessions, mostly of very high quality, and a few really interesting BOF (birds of a feather) sessions - which for once, didn't feel as if they were just squeezed in at the last minute.&lt;br/&gt;&lt;br/&gt;Functional programming (in particular, Haskell) was a major theme this year, as was testing. My eyes were opened to the possibility of doing test-driven development (TDD) in Haskell - in fact, functional languages are better at this than imperative (stateful) languages. It was also good to meet up with a lot of familiar faces at the joint &lt;a href='http://www.xpdeveloper.net/'&gt;XtC&lt;/a&gt; meeting on the Tuesday night.&lt;br/&gt;&lt;br/&gt;My session notes are on my other laptop. I will try to post them on the &lt;a href='http://bcs-spa.org/' target='_blank'&gt;SPA SG site&lt;/a&gt; over the Easter weekend, other duties permitting.&lt;br/&gt;&lt;br/&gt;&lt;div class='zemanta-pixie'&gt;&lt;img src='http://img.zemanta.com/pixy.gif?x-id=525cec7a-cb38-8a33-a5b5-abc1adac3a70' class='zemanta-pixie-img'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-8492371426030123673?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/8492371426030123673/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=8492371426030123673' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/8492371426030123673'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/8492371426030123673'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2009/04/spa2009-first-impressions.html' title='SPA2009 - first impressions'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-1701960335680678092</id><published>2009-04-04T09:29:00.003+01:00</published><updated>2009-04-09T14:55:14.053+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Web 2.0'/><title type='text'>Automating testing of web sites with multiple browsers</title><content type='html'>After several days of trying, I've just abandoned an attempt to automate web site tests with multiple browsers (Firefox, Internet Explorer, Safari and Opera under various operating systems). My findings are written up &lt;a href="http://clearspace.openqa.org/message/60051"&gt;here&lt;/a&gt;. Briefly, I think that &lt;a href="http://seleniumhq.org/projects/remote-control/"&gt;Selenium RC&lt;/a&gt; has the right architecture, but currently the linkage between the RC server and the browser only works 100% for Firefox. This isn't enough.&lt;br /&gt;&lt;br /&gt;It seems from the documentation that &lt;a href="http://wtr.rubyforge.org/"&gt;Watir&lt;/a&gt; should support the functionality needed. Can anyone confirm that it's possible to test pages such as &lt;a href="http://sisustusliikeid.fi/layout/js/scriptaculous-js-1.7.0/test/functional/ajax_autocompleter2_test.html"&gt;this one&lt;/a&gt; in at least three different browser types with it?&lt;br /&gt;&lt;br /&gt;Update (9 April): I discovered that Selenium RC has a start-up parameter "-proxyInjectionMode", which is equivalent to choosing the "*pi..." launchers where available. Unfortunately this only works with "*firefox", so you might just as well use "*pifirefox". It isn't clear to me why it causes tests to fail when they launch a browser with "*mock".&lt;br /&gt;&lt;br /&gt;I was also reminded at the SPA2009 conference that it might be worth trying out Cucumber, rSpec, Concordion or other tools, so long as they will drive more than one browser.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-1701960335680678092?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/1701960335680678092/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=1701960335680678092' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/1701960335680678092'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/1701960335680678092'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2009/04/automating-testing-of-web-sites-with.html' title='Automating testing of web sites with multiple browsers'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-7933115424144328560</id><published>2009-03-19T10:51:00.002Z</published><updated>2009-03-19T10:54:01.032Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='teams'/><category scheme='http://www.blogger.com/atom/ns#' term='soft skills'/><category scheme='http://www.blogger.com/atom/ns#' term='Credit Crunch'/><title type='text'>Why people think it's OK to cheat / steal</title><content type='html'>Dan Ariely has given a brilliant talk about this and how it impacts the global economic crisis. Watch this on &lt;a href="http://www.ted.com/talks/dan_ariely_on_our_buggy_moral_code.html"&gt;Ted&lt;/a&gt; - it'll be 16 minutes well spent. Good insights into human psychology and behaviour.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-7933115424144328560?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/7933115424144328560/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=7933115424144328560' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/7933115424144328560'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/7933115424144328560'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2009/03/why-people-think-its-ok-to-cheat-steal.html' title='Why people think it&apos;s OK to cheat / steal'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-955754937492967680</id><published>2009-03-17T15:19:00.011Z</published><updated>2011-05-26T11:17:57.197+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='software practice'/><category scheme='http://www.blogger.com/atom/ns#' term='management'/><title type='text'>Tools to support agile methods</title><content type='html'>The whole point of managing a project using an agile method is to &lt;a href="http://uncyclopedia.wikia.com/wiki/Agile_software_development"&gt;use lots of coloured cards and post-it notes&lt;/a&gt;, but sometimes you have to fall back on a boring old software tool. The thorny question keeps arising: which one do I recommend?&lt;br /&gt;&lt;br /&gt;Many different project management tools exist, at different price-points and levels of functionality. A long list is shown below. It is important to be clear about a project's requirements for a tool before selecting. Avoid the temptation to extend any tool you select or to spend much effort integrating it with the rest of your project environment – this is a sure way to lock yourself into a single supplier.&lt;br /&gt;&lt;br /&gt;The following list of tools is not exhaustive, though I have kept adding to it as I came across new tools:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.project-open.org/"&gt;]project-open[&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.achievo.org/"&gt;Achievo&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.activecollab.com/"&gt;ActiveCollab&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.agilebuddy.com/"&gt;Agilebuddy&lt;/a&gt; - reported by a comment on this post to be a full-featured agile project management software tool, which is easy to use and great for Scrum teams. Offered on a subscription model for US$9.95 per user per month&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.agilefant.org/"&gt;Agilefant&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.agile42.com/cms/pages/download/"&gt;Agilo&lt;/a&gt; – based on the &lt;a href="http://trac.edgewall.org/"&gt;Trac&lt;/a&gt; issue-management tool and said to support only a single project at a time&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://airtodo.sourceforge.net/"&gt;airTODO&lt;/a&gt; – PMBOK rather than agile, but minimalist (an Eclipse plug-in)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;AxoSoft's &lt;a href="http://www.axosoft.com/"&gt;OnTime &lt;/a&gt;- available as a hosted cloud solution, a Windows native application or as a web application, one comment under this post has reported that it "great for agile / scrum development". Comparable in scope to Trac, but looks a lot more snazzy&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.bananascrum.com/"&gt;Banana Scrum&lt;/a&gt; - according to one comment below, this is a nice, web based tool that helps without getting in team's way&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.extremeplanner.com/"&gt;Extreme Planner&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://confluence.atlassian.com/display/JIRAEXT/GreenHopper"&gt;Greenhopper&lt;/a&gt; – a JIRA plugin favoured by some Scrum teams&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://icescrum.org/"&gt;IceScrum&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://studios.thoughtworks.com/mingle-agile-project-management"&gt;Mingle&lt;/a&gt; - provides a shared workspace for agile teams, supporting XP, Scrum and custom hybrid approaches. Includes a virtual card wall, wiki, charts, reports and more. Integrated with issue tracking and continuous build. Priced US$995 per user with substantial discounts for multiple licences, academic institutions etc.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.pivotaltracker.com/"&gt;Pivotal Tracker&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.projectcards.com/"&gt;ProjectCards&lt;/a&gt; – mixed approach that uses both physical cards and software&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.projectkoach.com/"&gt;ProjectKoach&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.rallydev.com/"&gt;Rally&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www-01.ibm.com/software/rational/products/rtc/"&gt;Rational Team Concert&lt;/a&gt; - integrates work item, continuous integration builds and software configuration management (SCM) on the collaborative infrastructure of the Jazz Team Server&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.redmine.org/"&gt;redMine&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.scrumedge.com/"&gt;Scrum Edge&lt;/a&gt; - someone commented below that it was much simpler to use than most other Scrum tools&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.scrumworks.com/"&gt;Scrumworks&lt;/a&gt; - quite popular free open source package, heavily forms-based, can integrate with JIRA&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.silverstripesoftware.com/"&gt;Silver Catalyst&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.zuehlke.com/en/know-how/technologies/agile-software-development/"&gt;StuffPlanner&lt;/a&gt; – Zühlke's inhouse-developed browser-based tool now at version 0.1 and with an Eclipse Mylyn connector available; access can be provided by arrangement&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.targetprocess.com/"&gt;TargetProcess&lt;/a&gt; - designed to support Scrum, XP and custom Agile processes particularly in the .NET environment. Includes a comprehensive set of tools and features, including defect-tracking, test management and customer helpdesk portal. Community edition free for up to 5 users&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.twproject.com/"&gt;teamwork&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.tinypm.com/"&gt;tinyPM&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.versionone.com/"&gt;VersionOne&lt;/a&gt; - very full-featured, supports Scrum, DSDM, XP and AUP across multiple projects. Priced from US$348 per user per year, there is a free "team edition" for one team of up to 10&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.xpstorystudio.com/"&gt;XP Story Studio&lt;/a&gt; – no development since 2004&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.xplanner.org/"&gt;XPlanner&lt;/a&gt;&lt;/li&gt; - a popular free open source planning and tracking tool for XP. Quite simple in keeping with the low-ceremony agile approach&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.openxprocess.com/"&gt;xProcess&lt;/a&gt; - free open source project management and process improvement tool, focused particularly on agile and priority-driven approaches. Preconfigured processes include Scrum, FDD, Prince2, Unified and others; can be tailored. Gantt/Burndowns/target status continuously updated. See also &lt;a href="http://www.xprocess.eu.com/"&gt;xProcess Europe&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://xpweb.sourceforge.net/"&gt;XPWeb&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;A number of web sites compare small subsets of the available software tools, including&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.agile-tools.net/"&gt;http://www.agile-tools.net/&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://brunomiranda.com/past/2008/8/19/agile_project_management_tools/"&gt;http://brunomiranda.com/past/2008/8/19/agile_project_management_tools/&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://agilesoftwaredevelopment.com/blog/mattgrommes"&gt;http://agilesoftwaredevelopment.com/blog/mattgrommes&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.life-cycle.de/journal/"&gt;http://www.life-cycle.de/journal/&lt;/a&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/5605173550883974775-955754937492967680?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/955754937492967680/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=955754937492967680' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/955754937492967680'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/955754937492967680'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2009/03/tools-to-support-agile-methods.html' title='Tools to support agile methods'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-5923391675207754475</id><published>2009-03-17T10:40:00.002Z</published><updated>2009-03-17T10:48:30.346Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='ID cards'/><category scheme='http://www.blogger.com/atom/ns#' term='Big Brother'/><category scheme='http://www.blogger.com/atom/ns#' term='national identity register'/><category scheme='http://www.blogger.com/atom/ns#' term='privacy'/><category scheme='http://www.blogger.com/atom/ns#' term='no2id'/><title type='text'>Latest unwarranted privacy violation</title><content type='html'>The &lt;a href="http://www.telegraph.co.uk/news/uknews/4987415/All-travel-plans-to-be-tracked-by-Government.html"&gt;Daily Telegraph&lt;/a&gt; reports that the travel plans and personal details of everyone leaving Britain are to be tracked by the Government. Under the "e-borders" scheme, they intend to make it a criminal offence not to submit, in advance of every trip, personal information such as passport and credit card details, home and email addresses and exact travel plans. This is already starting to happen.&lt;br /&gt;&lt;br /&gt;The kind of thing that e-borders enables is illustrated by &lt;a href="http://www.telegraph.co.uk/news/uknews/road-and-rail-transport/4996018/Motorists-could-be-banned-from-leaving-Britain-over-unpaid-parking-fines.html"&gt;this story&lt;/a&gt;, which shows that you could be stopped from leaving the country if you have unpaid parking fines or indeed any other mark against your name. What are the chances that before the year is out, we'll be reading stories about innocent people trying to travel abroad who get arrested at the airport or sea port thanks to some mix-up?&lt;br /&gt;&lt;br /&gt;With developments like these, it's hard to believe that we are not living in a police state.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-5923391675207754475?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/5923391675207754475/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=5923391675207754475' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/5923391675207754475'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/5923391675207754475'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2009/03/latest-unwarranted-privacy-violation.html' title='Latest unwarranted privacy violation'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-2314465954047391338</id><published>2009-03-17T10:33:00.003Z</published><updated>2009-03-17T10:37:45.090Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='software practice'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>CodeCity</title><content type='html'>This looks really intriguing: &lt;a href="http://www.inf.unisi.ch/phd/wettel/codecity-wof.html"&gt;CodeCity&lt;/a&gt; gives a really nice way to visualise properties of Java code bases. An example is shown below (an analysis of Azureus v2.5.00):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.inf.unisi.ch/phd/wettel/pics/wof/azureus-2500-coarse.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 740px; height: 390px;" src="http://www.inf.unisi.ch/phd/wettel/pics/wof/azureus-2500-coarse.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It's a free download, so give it a try on your own code!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-2314465954047391338?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/2314465954047391338/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=2314465954047391338' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/2314465954047391338'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/2314465954047391338'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2009/03/codecity.html' title='CodeCity'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-2231491435964559213</id><published>2009-02-26T22:22:00.002Z</published><updated>2009-02-26T22:32:16.151Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='eclipse pde'/><category scheme='http://www.blogger.com/atom/ns#' term='software practice'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse rcp'/><category scheme='http://www.blogger.com/atom/ns#' term='craftsmanship'/><title type='text'>My Favourite Keyboard Shortcuts</title><content type='html'>That was the title of a session I proposed for today's first-ever Software Craftsmanship Conference, at the BBC's attractive Media Centre in London's White City. To my surprise, the session was accepted. It worked quite well despite attracting only about half a dozen participants. I certainly learned a good deal from it!&lt;br /&gt;&lt;br /&gt;The&lt;a href="http://softwarecraftsmanship.wikidot.com/myfavouritekeyboardshortcutsoutputs"&gt; output of the session&lt;/a&gt; has been posted on the conference Wiki. However, you'll have to be logged in to see it, as the wiki is private to conference participants. I don't know if Jason Gorman plans to change this now the conference is over.&lt;br /&gt;&lt;br /&gt;The top tips (as a result of a quick spot vote at the end) were:&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-weight:bold;"&gt;three-step refactoring tango&lt;/span&gt;: Jason's recipe for method extraction where one or more parameters are themselves method calls. In Eclipse, it goes ALT-SHIFT-L (extract local variable), ALT-SHIFT-M (extract method), then ALT-SHIFT-I (inline local variable as method parameter).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Expand/shrink current selection&lt;/span&gt;: In Eclipse, ALT-SHIFT-up/down arrow or in IDEA, CTRL-w/W. With the cursor on a given word, the word is selected. Repeated applications of the same keyboard combo selects progressively larger portions of the source file (up to and including the entire file). Using the opposite key combination reduces the size of the selection all the way back to 0.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-2231491435964559213?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/2231491435964559213/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=2231491435964559213' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/2231491435964559213'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/2231491435964559213'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2009/02/my-favourite-keyboard-shortcuts.html' title='My Favourite Keyboard Shortcuts'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-797403603652258694</id><published>2009-02-18T09:57:00.002Z</published><updated>2009-02-18T10:04:14.281Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='eclipse pde'/><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Canoo'/><category scheme='http://www.blogger.com/atom/ns#' term='test-driven development'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><category scheme='http://www.blogger.com/atom/ns#' term='Hibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='WebTest'/><category scheme='http://www.blogger.com/atom/ns#' term='jMock'/><title type='text'>Test-Driven Web Development on Spring and Hibernate</title><content type='html'>&lt;a href="http://witi-work.blogspot.com/"&gt;Adam Shimali&lt;/a&gt; and I will be piloting our TDD course at &lt;a href="http://spa2009.org/"&gt;SPA2009&lt;/a&gt; on the Sunday afternoon. Three two-hour samples of a full two-day course for free - and you get a 10% discount off the cost of the full course for yourself or a colleague.&lt;br /&gt;&lt;br /&gt;The course is very hands-on. If you bring a laptop (Windows or MacOS) we can provide you with the complete Eclipse development environment installation on a CD or memory stick - you'll be good to go in about five minutes. It will help if you've done a bit of Java programming before, but even this is not essential as you'll be paired with someone experienced.&lt;br /&gt;&lt;br /&gt;There's still time to book for SPA2009, but don't delay!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-797403603652258694?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/797403603652258694/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=797403603652258694' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/797403603652258694'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/797403603652258694'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2009/02/test-driven-web-development-on-spring.html' title='Test-Driven Web Development on Spring and Hibernate'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-8653821927899887098</id><published>2009-02-17T10:53:00.003Z</published><updated>2009-02-17T11:07:20.135Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='teams'/><category scheme='http://www.blogger.com/atom/ns#' term='software practice'/><category scheme='http://www.blogger.com/atom/ns#' term='lean'/><title type='text'>Agile and Lean - complementary or conflicting?</title><content type='html'>Dave West has contributed an article entitled &lt;a href="http://www.infoq.com/articles/backlog-not-waste"&gt;A Marriage Made in Heaven?&lt;/a&gt;. I found it very instructive to read that as well as the comments attached to it. To my mind, there are things that the software community can learn (and has learned) from lean manufacturing, but in many respects software development is much more of a joint creative act. As Dave says, &lt;a href="http://www.naur.com/comp/c1-4.html"&gt;Peter Naur&lt;/a&gt; as long ago as 1985 equated programming with &lt;a href="http://zatoichi.homeip.net/~brain/wiki/index.php/Programming_as_theory_building"&gt;collaborative theory-building&lt;/a&gt; - in other words, it has much in common with research at the forefront of physics or mathematics, where results are difficult to predict and effort is almost impossible to forecast.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-8653821927899887098?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/8653821927899887098/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=8653821927899887098' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/8653821927899887098'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/8653821927899887098'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2009/02/agile-and-lean-complementary-or.html' title='Agile and Lean - complementary or conflicting?'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-8979223594732050242</id><published>2009-02-16T23:46:00.002Z</published><updated>2009-02-16T23:59:16.596Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='ID cards'/><category scheme='http://www.blogger.com/atom/ns#' term='Big Brother'/><category scheme='http://www.blogger.com/atom/ns#' term='national identity register'/><category scheme='http://www.blogger.com/atom/ns#' term='no2id'/><title type='text'>BALPA refuses to co-operate with ID card scheme</title><content type='html'>Well done, the British Airline Pilots Association. It has refused to co-operate with the odious National ID register, as reported in &lt;a href="http://www.timesonline.co.uk/tol/travel/news/article5741216.ece"&gt;The Times&lt;/a&gt;. I especially enjoyed reading BALPA's clear views on the insidious methods the Government has chosen to bring in the ID cards:&lt;br /&gt;&lt;br /&gt;"It is clear that the Government's staged introduction of biometric identity cards first to overseas students, then to migrant workers and then for aviation workers, represents a way of picking off what are seen as easy targets."&lt;br /&gt;&lt;br /&gt;It'll be interesting to see what the Home Office chooses to do next. They can't afford to be seen to back down in the face of such a challenge to their "authority", yet they can't force airlines to sack valuable staff. So I expect that a technical pretext will be found for not requiring the airline pilots to carry the cards after all, and the department will go after another softer target first.&lt;br /&gt;&lt;br /&gt;It is beyond me why the Government keeps on trying to introduce this scheme. The Tories and LibDems have both pledged to scrap the whole thing as soon as Labour is voted out of office, which only gives them a couple more years at most to push it through. Sadly, the stubborn and unimaginative lot currently in power are likely to waste hundreds of millions of pounds of our money on this folly before it is finally sunk.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-8979223594732050242?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/8979223594732050242/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=8979223594732050242' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/8979223594732050242'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/8979223594732050242'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2009/02/balpa-refuses-to-co-operate-with-id.html' title='BALPA refuses to co-operate with ID card scheme'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-7116574573300680206</id><published>2009-01-26T16:34:00.002Z</published><updated>2009-01-26T16:54:16.464Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Credit Crunch'/><title type='text'>Predictably Irrational: the international financial crisis</title><content type='html'>My eternal gratitude to Dan Ariely and his &lt;a href="http://www.predictablyirrational.com/"&gt;Predictably/Irrational blog&lt;/a&gt; for pointing out the existence of a &lt;a href="http://www.thisamericanlife.org/Radio_Episode.aspx?episode=355"&gt;radio programme&lt;/a&gt; and its &lt;a href="http://www.thisamericanlife.org/extras/radio/355_transcript.pdf"&gt;transcript in PDF&lt;/a&gt;, which for the first time properly explained to me why we're in such a mess. I wonder what collective idiocy is next up.&lt;br /&gt;&lt;br /&gt;It also provides a sobering reminder that it's usually a bad idea to throw money at a problem. In this particular instance, Gordon Brown's fantastic idea to "save the world" by hosing all our cash and then some into the banks' pool of money supply was such a bad idea that it must stand as one of the most monumentally stupid decisions of all time. Read the transcript yourself to find out why.&lt;br /&gt;&lt;br /&gt;Anyone without the requisite quarter of an hour to hand can refer to &lt;a href="http://www.duffbert.com/duffbert/blog.nsf/d6plinks/TDUF-6FGKJ5"&gt;this&lt;/a&gt; very much more succinct, but necessarily less thorough, tale. It seems prescient, having been posted in 2005!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-7116574573300680206?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/7116574573300680206/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=7116574573300680206' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/7116574573300680206'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/7116574573300680206'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2009/01/predictably-irrational-international.html' title='Predictably Irrational: the international financial crisis'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-3230555523614508525</id><published>2009-01-23T17:15:00.002Z</published><updated>2009-01-23T17:19:20.371Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='soft skills'/><category scheme='http://www.blogger.com/atom/ns#' term='publishing'/><title type='text'>How to write conference session proposals</title><content type='html'>Most of you probably already know how to do this - after all, you get your papers accepted at conferences all over the world all the time, right?&lt;br /&gt;&lt;br /&gt;If (like me) you find your brilliant ideas trampled underfoot as often as not, read &lt;a href="http://plg.uwaterloo.ca/~migod/research/beckOOPSLA.html"&gt;Kent Beck's advice&lt;/a&gt;. It may have been written over 15 years ago, but I'm certain it applies equally well today. It's also charmingly self-referential.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-3230555523614508525?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/3230555523614508525/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=3230555523614508525' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/3230555523614508525'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/3230555523614508525'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2009/01/how-to-write-conference-session.html' title='How to write conference session proposals'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-8533860011481975419</id><published>2009-01-06T18:11:00.002Z</published><updated>2009-01-06T18:32:44.429Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='EasyMock'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='test-driven development'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><category scheme='http://www.blogger.com/atom/ns#' term='jMock'/><title type='text'>Mock external components using AOP</title><content type='html'>Mark Nadelson has provided a well-written &lt;a href="http://java.sys-con.com/node/767418"&gt;tutorial&lt;/a&gt; for a novel (to me, at any rate) use of &lt;a href="http://en.wikipedia.org/wiki/Aspect-oriented_programming"&gt;Aspect-Oriented Programming&lt;/a&gt; in Java. Read the "print" version to get the whole article in one lump without the commercials.&lt;br /&gt;&lt;br /&gt;When you write &lt;a href="http://junit.org/"&gt;jUnit&lt;/a&gt; tests, you often encounter a need to create mock objects (e.g. using &lt;a href="http://www.jmock.org/"&gt;JMock&lt;/a&gt; or &lt;a href="http://www.easymock.org/"&gt;EasyMock&lt;/a&gt;) that can simulate some external dependency of the software under test. Mark has extended this idea to any external component that has an interface. In order to determine whether the software under test uses a mock component or the real one, he uses dynamic aspect-weaving by means of &lt;a href="http://static.springframework.org/spring/docs/2.5.x/reference/aop.html"&gt;Spring AOP&lt;/a&gt; with &lt;a href="http://static.springframework.org/spring/docs/2.5.x/reference/aop.html#aop-ataspectj"&gt;AspectJ annotations&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I've got to have a play with this approach to see whether it can be used flexibly enough to support &lt;a href="http://en.wikipedia.org/wiki/Test-driven_development"&gt;TDD&lt;/a&gt; fully. One problem I could foresee is that the pointcut specification is not in the test script but in the mock object (i.e. the class that implements the aspect). So it might be less than straightforward to link the mock object to specific test cases/steps. By contrast, when you use JMock in a jUnit test, you specify both the mock object and its expectations in one place.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-8533860011481975419?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/8533860011481975419/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=8533860011481975419' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/8533860011481975419'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/8533860011481975419'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2009/01/mock-external-components-using-aop.html' title='Mock external components using AOP'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-5933741983634669762</id><published>2009-01-05T14:34:00.003Z</published><updated>2009-01-05T15:23:18.873Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='XPath'/><category scheme='http://www.blogger.com/atom/ns#' term='SOA'/><category scheme='http://www.blogger.com/atom/ns#' term='Canoo'/><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><category scheme='http://www.blogger.com/atom/ns#' term='WebTest'/><title type='text'>XPath made simple</title><content type='html'>I know I'm a bit behind the curve on this one, but I've only just stumbled across a really useful tool:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://xpath.alephzarro.com/"&gt;XPather&lt;/a&gt; can&lt;br /&gt;&lt;ul&gt;&lt;li&gt;generate &lt;a href="http://www.w3.org/TR/xpath20/"&gt;XPaths&lt;/a&gt; while browsing or inspecting HTML/XML/*ML documents&lt;/li&gt;&lt;li&gt;evaluate your XPaths and inspect the results&lt;/li&gt;&lt;li&gt;extract the content of *ML documents&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;The latest version 1.4.1 was released on June 18 2008 (Firefox 3.0 compatible).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://xpath.alephzarro.com/"&gt;XPather&lt;/a&gt; is a simple &lt;a href="http://www.mozilla.com/firefox/"&gt;Firefox&lt;/a&gt; extension that integrates both with the browser and its &lt;a href="https://addons.mozilla.org/firefox/addon/6622"&gt;DOMInspector&lt;/a&gt;. It is designed to be lightweight and cross-platform. It is valuable mainly as a web/XML-app development and debugging tool. In combination with the DOMInspector, which I can also highly recommend, it is particularly useful for developing &lt;a href="http://webtest.canoo.com/"&gt;WebTest&lt;/a&gt; scripts: right-click in any element of a page that you want your script to compare or set, and the option "Show in XPather" pops up a new window with the precise XPath to select that element.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-5933741983634669762?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/5933741983634669762/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=5933741983634669762' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/5933741983634669762'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/5933741983634669762'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2009/01/xpath-made-simple.html' title='XPath made simple'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-5547767157413916492</id><published>2008-12-16T09:22:00.003Z</published><updated>2008-12-16T09:52:47.677Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='SOA'/><category scheme='http://www.blogger.com/atom/ns#' term='Native'/><category scheme='http://www.blogger.com/atom/ns#' term='Web 2.0'/><title type='text'>Return of the Thick Client?</title><content type='html'>Web 2.0 is taking all sorts of unexpected directions. The latest to come to my attention are two initiatives aimed at offloading processor load from server to client.&lt;br /&gt;&lt;br /&gt;First up, Google announced a new developer project named &lt;a href="http://google-code-updates.blogspot.com/2008/12/native-client-technology-for-running.html"&gt;Native Client&lt;/a&gt;. With Native Client, Google aims to "give web developers access to the full power of the client's CPU while maintaining the browser neutrality, OS portability and safety that people expect from web applications." As far as I can see, it's what Java Applets were originally designed to do - and look how successful they've been. At least outside the enterprise environment (where desktop configurations tend to be strictly controlled), applets suffered from the "write once, debug everywhere" syndrome and have largely fallen out of use. It'll be interesting to see whether an Internet-savvy company like Google makes a success of this new approach.&lt;br /&gt;&lt;br /&gt;Next, a start-up named &lt;a href="http://www.thinkgos.com/"&gt;Good OS&lt;/a&gt; has announced &lt;a href="http://www.thinkgos.com/cloud.php"&gt;Cloud&lt;/a&gt;, "a browser operating system". I am trying hard to get my head around that concept. They claim that it's an environment for enhancing the user's Internet experience and that it can be co-hosted on Windows, Linux or other operating systems. If I have read the scant information available correctly, the idea is that your machine will start up already logged on to your favourite portal (Yahoo, Google, Windows Live...) and that core applications such as Skype, which are accessed from a MacOS-like object dock, run within their own dedicated browser tab on top of Cloud's integrated compressed Linux kernel. Whenever you need to, you can switch to the native OS with a single key press.&lt;br /&gt;&lt;br /&gt;Unfortunately the "Why Cloud?" page on Good OS's web site is unfinished, so it is difficult to comprehend the vision behind the product. A clue might be that it is being bundled with the Gigabyte touch-screen &lt;a href="http://www.gigabyte.com.tw/News/Notebook/News_List.aspx?NewsID=1398"&gt;Netbook&lt;/a&gt; models and so looks like a lower-cost alternative to &lt;a href="http://en.wikipedia.org/wiki/Microsoft_Windows_CE"&gt;Windows CE&lt;/a&gt;. Perhaps the company is aiming for an "Internet Appliance" niche. It made a name for itself by supplying the &lt;a href="http://www.techcrunch.com/2007/11/04/gos-where-computers-are-headed/"&gt;gOS Linux&lt;/a&gt; operating system for the ultra-low-cost &lt;a href="http://www.walmart.com/catalog/product.do?product_id=7754614"&gt;Wal-Mart PCs&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-5547767157413916492?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/5547767157413916492/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=5547767157413916492' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/5547767157413916492'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/5547767157413916492'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/12/return-of-thick-client.html' title='Return of the Thick Client?'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-6527401154696334594</id><published>2008-12-15T17:21:00.002Z</published><updated>2008-12-15T17:39:19.587Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Canoo'/><category scheme='http://www.blogger.com/atom/ns#' term='test-driven development'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='WebTest'/><title type='text'>Testing web applications? Cucumber is the cool new kid on the block</title><content type='html'>I've had quite complimentary things to say about &lt;a href="http://webtest.canoo.com/"&gt;Canoo WebTest&lt;/a&gt;, but one thing it doesn't provide out of the box is a representation of the tests that your average customer is able to read and understand intuitively - that is to say, a tabular format like &lt;a href="http://fit.c2.com/"&gt;Fit&lt;/a&gt; or a narrative of the "Given... when... then... " form.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.rubyinside.com/cucumber-the-latest-in-ruby-testing-1342.html"&gt;Cucumber&lt;/a&gt; to the rescue! I heard several people mention this at the recent &lt;a href="http://xpday.org/"&gt;XP Day&lt;/a&gt; in London. I hope to investigate it in more depth soon.&lt;br /&gt;&lt;br /&gt;I would be interested to know whether it can be used to test anything other than &lt;a href="http://ruby-lang.org/"&gt;Ruby&lt;/a&gt; code and whether it can drive a web browser to interact with &lt;a href="http://en.wikipedia.org/wiki/Rich_Internet_Application"&gt;Rich Internet Applications&lt;/a&gt; (RIAs). Stuart Ervine's and Nat Pryce's &lt;a href="http://code.google.com/webtoolkit/overview.html"&gt;GWT&lt;/a&gt; development demo at XP Day was truly impressive. Nat has combined &lt;a href="http://code.google.com/p/webdriver/"&gt;WebDriver&lt;/a&gt; with &lt;a href="http://code.google.com/p/windowlicker/"&gt;WindowLicker&lt;/a&gt; to create a clean interface between a test script and synchronous or asynchronous RIAs. But telling a &lt;a href="http://junit.sourceforge.net/"&gt;jUnit&lt;/a&gt; test to move the mouse cursor into a particular widget and click the button was nothing if not verbose!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-6527401154696334594?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/6527401154696334594/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=6527401154696334594' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/6527401154696334594'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/6527401154696334594'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/12/testing-web-applications-cucumber-is.html' title='Testing web applications? Cucumber is the cool new kid on the block'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-231689980296925246</id><published>2008-12-04T18:09:00.003Z</published><updated>2008-12-04T18:15:54.406Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='SMS'/><category scheme='http://www.blogger.com/atom/ns#' term='Vodafone'/><category scheme='http://www.blogger.com/atom/ns#' term='Text Centre'/><title type='text'>Sending SMS texts from the PC desktop</title><content type='html'>Ever left your mobile at home and needed to send a text to someone? And even to receive that person's reply without access to your phone? Or just found that ten-finger typing is quicker than predictive TXTing with two thumbs?&lt;br /&gt;&lt;br /&gt;I've discovered &lt;a href="http://online.vodafone.co.uk/dispatch/Portal/appmanager/vodafone/wrp?_nfpb=true&amp;amp;_pageLabel=template10&amp;amp;pageID=BS_0011"&gt;Vodafone Text Centre&lt;/a&gt; does the job (see feature summary in the attached message). You can install it for free, but note that the cost of SMS messages you send using Text Centre goes on to your normal Vodafone mobile account.&lt;br /&gt;&lt;br /&gt;There's a very comprehensive manual and &lt;a href="http://www.vodafone.co.uk/textcentre"&gt;online help&lt;/a&gt;. Make sure your Outlook isn't running before you start installing (use Task Manager to kill it if necessary).&lt;br /&gt;&lt;br /&gt;In a test here in the office, I found that my first outgoing message was delivered in just a few seconds, whereas the reply took around 10 minutes to reach my Outlook inbox (you can choose to have the reply routed to your mobile instead, of course, which is quicker but means that you don't have access to Outlook's convenience features when forwarding or filing the reply).&lt;br /&gt;&lt;br /&gt;If you're in the habit of leaving Outlook running when you leave the office, you can also get Text Centre to alert you by SMS when you receive an e-mail (or only for high-priority e-mails) or to send you an SMS alert of upcoming appointments.&lt;br /&gt;&lt;br /&gt;Overall, I am impressed. With Vodafone Text Centre you can:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Send text messages to individuals and groups from your PC, using your existing contacts and distribution lists.&lt;/li&gt;&lt;li&gt;Choose to have replies sent to your mobile phone or to your e-mail inbox.&lt;/li&gt;&lt;li&gt;Receive appointment reminders via text messages.&lt;/li&gt;&lt;li&gt;Choose to receive text messages to notify you of urgent e-mails.&lt;/li&gt;&lt;/ul&gt; Vodafone says that Text Centre will be upgraded on a regular basis, so suggests that you visit the &lt;a href="http://online.vodafone.co.uk/dispatch/Portal/appmanager/vodafone/wrp?_nfpb=true&amp;amp;_pageLabel=template10&amp;amp;pageID=BS_0011"&gt;website&lt;/a&gt; from time to time to ensure you have the most up-to-date version of the software.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-231689980296925246?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/231689980296925246/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=231689980296925246' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/231689980296925246'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/231689980296925246'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/12/sending-sms-texts-from-pc-desktop.html' title='Sending SMS texts from the PC desktop'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-7777758610586214974</id><published>2008-11-19T17:17:00.000Z</published><updated>2008-11-19T17:21:19.361Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='PDF'/><title type='text'>Munging PDF files and pages</title><content type='html'>Having scanned over a dozen handwritten pages from my notebook into a PDF file, I had to invert every other page to make it possible to read the whole thing. It took me a while to find the answer, but YOU can go straight to &lt;a href="http://www.pdfhacks.com/pdftk/"&gt;the solution&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;The command line is&lt;pre&gt;&lt;br /&gt;pdftk.exe scannedfile.pdf cat 1 2S 3 4S 5 6S 7 8S 9 10S 11 12S output readablefile.pdf&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-7777758610586214974?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/7777758610586214974/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=7777758610586214974' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/7777758610586214974'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/7777758610586214974'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/11/munging-pdf-files-and-pages.html' title='Munging PDF files and pages'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-9010162721388153464</id><published>2008-11-10T17:09:00.003Z</published><updated>2008-11-10T18:05:38.074Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><category scheme='http://www.blogger.com/atom/ns#' term='Rack'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse pde'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='Ramaze'/><title type='text'>Ramaze - first impressions continued</title><content type='html'>&lt;a href="http://aspsp.blogspot.com/2008/11/ramaze-first-impressions.html"&gt;My earlier posting&lt;/a&gt; was getting too long, so I'm continuing in this new one. Meanwhile, the tutorial's author has kindly left a comment on the original posting, indicating that the tutorial is due to be updated pretty soon. I look forward to that!&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ramaze.net/tutorials:todolist-11"&gt;Chapter 11&lt;/a&gt; of the tutorial can be used pretty much as-is, but I found that after an error, the redirection specified by the error method would be overwritten by the helper aspect. After some research, I discovered that the latest version of Ramaze supports a redirection status operator, &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;redirected?&lt;/span&gt;&lt;/span&gt;. Using this, the helper aspect can be written very simply:&lt;br /&gt;&lt;pre&gt;helper :aspect&lt;br /&gt;after( :create, :delete, :open, :close ) {&lt;br /&gt;  redirect Rs() unless redirected?&lt;br /&gt;}&lt;/pre&gt;&lt;a href="http://ramaze.net/tutorials:todolist-12"&gt;Chapter 12&lt;/a&gt; of the tutorial needs no changes, except that you don't have to add the flash section to the page template because we did it earlier.&lt;br /&gt;&lt;br /&gt;Now I wanted to convert the application to something more suited to enterprise deployment (and also more suited to shared hosting deployment - typically such environments provide an Apache server and MySQL database). So the first thing to do was to move from YAML to SQL - I chose MySQL.&lt;br /&gt;&lt;br /&gt;If you haven't yet installed &lt;a href="http://dev.mysql.com/downloads/mysql/5.0.html#downloads"&gt;MySQL&lt;/a&gt;, do so before the next step. Take care to ensure that your PATH environment variable contains the MySQL binary as well as its libraries (hold down the Windows key and press PAUSE to bring up the system properties, then choose Environment Variables in the Advanced tab). For example, on my system the System PATH begins:&lt;br /&gt;&lt;pre&gt;C:\ruby\bin;&lt;br /&gt;C:\Program Files\MySQL\MySQL Server 5.0\bin;&lt;br /&gt;C:\Program Files\MySQL\MySQL Server 5.0\lib\opt;&lt;br /&gt;C:\Program Files\MySQL\MySQL Server 5.0\lib\debug;&lt;br /&gt;...&lt;/pre&gt;Add a new database for the application and create a user account named "ramaze" with password "TodoList" for both localhost and remote-host access:&lt;br /&gt;&lt;pre&gt;mysql -u root -p&lt;br /&gt;******&lt;br /&gt;CREATE DATABASE IF NOT EXISTS todolist_db;&lt;br /&gt;GRANT SELECT, INSERT, UPDATE, DELETE, CREATE,&lt;br /&gt;  DROP, RELOAD, PROCESS, FILE, REFERENCES, INDEX,&lt;br /&gt;  ALTER, SHOW DATABASES, CREATE TEMPORARY TABLES,&lt;br /&gt;  LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW,&lt;br /&gt;  CREATE ROUTINE, ALTER ROUTINE ON *.*&lt;br /&gt;  TO 'ramaze'@'localhost'&lt;br /&gt;  IDENTIFIED BY 'TodoList' WITH GRANT OPTION;&lt;br /&gt;GRANT SELECT, INSERT, UPDATE, DELETE, CREATE,&lt;br /&gt;  DROP, RELOAD, PROCESS, FILE, REFERENCES, INDEX,&lt;br /&gt;  ALTER, SHOW DATABASES, CREATE TEMPORARY TABLES,&lt;br /&gt;  LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW,&lt;br /&gt;  CREATE ROUTINE, ALTER ROUTINE ON *.*&lt;br /&gt;  TO 'ramaze'@'%'&lt;br /&gt;  IDENTIFIED BY 'TodoList' WITH GRANT OPTION;&lt;br /&gt;quit&lt;/pre&gt;I decided to use &lt;a href="http://sequel.rubyforge.org/"&gt;Sequel&lt;/a&gt; as my database access layer. You probably also have to install the gems &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;mysql&lt;/span&gt;&lt;/span&gt; and &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;sequel&lt;/span&gt;&lt;/span&gt; before the code will work - I am not sure about the &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;mysql&lt;/span&gt;&lt;/span&gt; gem, as it was one of the things I installed before I eventually discovered the need to set up the PATH correctly.&lt;br /&gt;&lt;pre&gt;gem install sequel&lt;br /&gt;gem install mysql&lt;/pre&gt;I tried choosing the 'ruby' option, but this was unable to generate the native code on my machine. So I uninstalled it and tried again, choosing the 'mswin32' option, which worked fine.&lt;br /&gt;&lt;br /&gt;Now take a safety copy of your model file, todolist.rb, and start modifying it to use MySQL instead of YAML. Replace the following lines:&lt;br /&gt;&lt;pre&gt;require 'ramaze/store/default'&lt;br /&gt;TodoList = Ramaze::Store::Default.new('todolist.yaml')&lt;/pre&gt;with the following lines:&lt;br /&gt;&lt;pre&gt;require 'rubygems'&lt;br /&gt;require 'sequel'&lt;br /&gt;&lt;br /&gt;DB = Sequel.mysql('todolist_db',&lt;br /&gt;  :user =&gt; 'ramaze',&lt;br /&gt;  :password =&gt; 'TodoList',&lt;br /&gt;  :host =&gt; 'localhost')&lt;br /&gt;&lt;br /&gt;class TodoList &amp;lt; Sequel::Model(:tasks)&lt;br /&gt;  set_schema do&lt;br /&gt;    primary_key :id&lt;br /&gt;    varchar :title, unique =&amp;gt; true, :null =&gt; false&lt;br /&gt;    boolean :done&lt;br /&gt;  end&lt;br /&gt;end&lt;/pre&gt;To begin with, I tried using the title as the primary key. But I soon found that not only was it necessary to define the &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;title&lt;/span&gt;&lt;/span&gt; field first and then separately to name it as the primary key, the user-supplied title was not always suitable as a key value due to the presence of shell metacharacters and so on. So I decided to go with the Sequel flow and use a system-generated ID as the primary key.&lt;br /&gt;&lt;br /&gt;Next I found that the model didn't support the method &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;original()&lt;/span&gt;&lt;/span&gt;, which the original simple model supports. So I supplied one myself (subsequently found to be unnecessary after refactoring &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;main.rb&lt;/span&gt;&lt;/span&gt;):&lt;br /&gt;&lt;pre&gt;  # Copy all records into a list&lt;br /&gt;  def self.original&lt;br /&gt;    tasks = []&lt;br /&gt;    self.dataset.each {|r| tasks.push [r[:title], {:done =&gt; r[:done]}]}&lt;br /&gt;    return tasks&lt;br /&gt;  end&lt;/pre&gt;More important was to add some initialisation code after the class was defined:&lt;br /&gt;&lt;pre&gt;unless TodoList.table_exists?&lt;br /&gt;  DB.transaction do&lt;br /&gt;    puts &amp;quot;Creating table 'tasks'\n&amp;quot;&lt;br /&gt;    TodoList.create_table&lt;br /&gt;  end&lt;br /&gt;end&lt;/pre&gt;Now try running the application. It seems to work, but nothing gets stored in the database. At this point we have to bite the bullet and refactor the &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;main&lt;/span&gt;&lt;/span&gt; module to support a more relational view of the underlying data model.&lt;br /&gt;&lt;br /&gt;In the &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;index()&lt;/span&gt;&lt;/span&gt; method, we'll start using the ID of each task to identify it instead of the title. Instead of requesting an array of key-value pairs from the &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;original()&lt;/span&gt;&lt;/span&gt; method, we get an array of &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;task&lt;/span&gt;&lt;/span&gt; objects from the &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;dataset()&lt;/span&gt;&lt;/span&gt; method. That of course implies that we have to extract the title and the ID from the &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;task&lt;/span&gt;&lt;/span&gt; object and use them as appropriate:&lt;br /&gt;&lt;pre&gt;  def index&lt;br /&gt;    @title = [&amp;quot;To-Do List&amp;quot;]&lt;br /&gt;    @tasks = []&lt;br /&gt;    TodoList.dataset.each do |task|&lt;br /&gt;      id = task[:id]&lt;br /&gt;      title = task[:title]&lt;br /&gt;      if task[:done]&lt;br /&gt;        status = 'done'&lt;br /&gt;        toggle = A('Open Task', :href =&gt; Rs(:open, id))&lt;br /&gt;      else&lt;br /&gt;        status = 'not done'&lt;br /&gt;        toggle = A('Close Task', :href =&gt; Rs(:close, id))&lt;br /&gt;      end&lt;br /&gt;      delete = A('Delete', :href =&gt; Rs(:delete, id))&lt;br /&gt;      @tasks &lt;&lt; [title, status, toggle, delete]&lt;br /&gt;    end&lt;br /&gt;    @tasks.sort!&lt;br /&gt;  end&lt;/pre&gt;The methods &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;open()&lt;/span&gt;&lt;/span&gt;, &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;close()&lt;/span&gt;&lt;/span&gt;, &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;task_status()&lt;/span&gt;&lt;/span&gt; and &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;delete()&lt;/span&gt;&lt;/span&gt; have to change because they all now take an &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;id&lt;/span&gt;&lt;/span&gt; as parameter:&lt;br /&gt;&lt;pre&gt;  def delete id&lt;br /&gt;    unless TodoList.delete id&lt;br /&gt;      failed "Cannot delete task no.: #{id}"&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def open id&lt;br /&gt;    task_status id, false&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  def close id&lt;br /&gt;    task_status id, true&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def task_status id, status&lt;br /&gt;    unless task = TodoList[id]&lt;br /&gt;      failed "No such task no.: #{id}"&lt;br /&gt;      redirect_referer&lt;br /&gt;    end&lt;br /&gt;    task[:done] = status&lt;br /&gt;    TodoList[id] = task&lt;br /&gt;  end&lt;/pre&gt;I decided to override the &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;[]=&lt;/span&gt;&lt;/span&gt; method of the model, so that tasks would actually be written to the database. It was an easy step from there to create a new row in the tasks table whenever the ID parameter to this method was absent or &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;nil&lt;/span&gt;&lt;/span&gt;. So the &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;create()&lt;/span&gt;&lt;/span&gt; method becomes: &lt;br /&gt;&lt;pre&gt;  def create&lt;br /&gt;    if title = request['title']&lt;br /&gt;      title.strip!&lt;br /&gt;      if title.empty?&lt;br /&gt;        failed("Please enter a title")&lt;br /&gt;        redirect '/new'&lt;br /&gt;      end&lt;br /&gt;      if TodoList.find(:title =&gt; title)&lt;br /&gt;        failed("Task '#{title}' already exists")&lt;br /&gt;      else&lt;br /&gt;        TodoList[nil] = {:title =&gt; title, :done =&gt; false}&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;  end&lt;/pre&gt;Note the check for duplicates, which is easy to do now that we can look up titles in the dataset.&lt;br /&gt;&lt;br /&gt;Turning to the file &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;todolist.rb&lt;/span&gt;&lt;/span&gt;, here are the methods I had to add to allow tasks to be added and deleted in the database:&lt;br /&gt;&lt;pre&gt;  def self.delete(id)&lt;br /&gt;    puts &amp;quot;Attempting to delete '#{id}'\n&amp;quot;&lt;br /&gt;    DB.transaction do&lt;br /&gt;      if task = TodoList.find(:id =&gt; id)&lt;br /&gt;        task.destroy()&lt;br /&gt;      else&lt;br /&gt;        puts &amp;quot;Not found\n&amp;quot;&lt;br /&gt;        return false&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  # Assignment should update the underlying database&lt;br /&gt;  def self.[]=(id, values)&lt;br /&gt;    DB.transaction do&lt;br /&gt;      if (id == nil || !(task = TodoList.find(:id =&gt; id)))&lt;br /&gt;        task = TodoList.new&lt;br /&gt;      end&lt;br /&gt;      task.title = values[:title]&lt;br /&gt;      task.done = values[:done]&lt;br /&gt;      task.save&lt;br /&gt;    end&lt;br /&gt;  end&lt;/pre&gt;That's pretty much it. But before I stopped, I wanted to prettify the user interface a bit. I didn't like the fact that the column widths tended to change whenever the sole &amp;quot;not done&amp;quot; item was added to or deleted from the list, and in any case I preferred clickable icons to text links. So I designed some icons:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh3.ggpht.com/_eJ-aAjApSE0/SRh0zWr537I/AAAAAAAAA7U/aPEF9ti41Yg/s200/notdone_sml.gif" align="left"&gt; not done&lt;br/&gt;&lt;br /&gt;&lt;img src="http://2.bp.blogspot.com/_eJ-aAjApSE0/SRh1J1pAD1I/AAAAAAAAA7c/GVX6Ne9o0bI/s200/done_sml.gif" align="left"&gt; done&lt;br/&gt;&lt;br /&gt;&lt;img src="http://lh5.ggpht.com/_eJ-aAjApSE0/SRh1KTuv-qI/AAAAAAAAA7k/P-LrqzCEAks/s200/delete_sml.gif" align="left"&gt; delete&lt;br /&gt;&lt;br /&gt;Feel free to copy the icon images. To let the Mongrel server access these, they have to be placed in the folder "public" of your project. Then I redesigned the index() method and the corresponding index.html file very slightly to use these (first declaring some constants):&lt;br /&gt;&lt;pre&gt;  DELETE_ICON  = '&amp;lt;img src=&amp;quot;delete_sml.gif&amp;quot;&amp;gt;'&lt;br /&gt;  NOTDONE_ICON = '&amp;lt;img src=&amp;quot;notdone_sml.gif&amp;quot;&amp;gt;'&lt;br /&gt;  DONE_ICON    = '&amp;lt;img src=&amp;quot;done_sml.gif&amp;quot;&amp;gt;'&lt;br /&gt;  &lt;br /&gt;  # the index action is called automatically when no other action is specified&lt;br /&gt;  def index&lt;br /&gt;    @title = [&amp;quot;To-Do List&amp;quot;]&lt;br /&gt;    @tasks = []&lt;br /&gt;    TodoList.dataset.each do |task|&lt;br /&gt;      id = task[:id]&lt;br /&gt;      title = task[:title]&lt;br /&gt;      if task[:done]&lt;br /&gt;        toggle = A(DONE_ICON, :href =&amp;gt; Rs(:open, id))&lt;br /&gt;      else&lt;br /&gt;        toggle = A(NOTDONE_ICON, :href =&amp;gt; Rs(:close, id))&lt;br /&gt;      end&lt;br /&gt;      delete = A(DELETE_ICON, :href =&amp;gt; Rs(:delete, id))&lt;br /&gt;      @tasks &amp;lt;&amp;lt; [title, toggle, delete]&lt;br /&gt;    end&lt;br /&gt;    @tasks.sort!&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;    &amp;lt;p&amp;gt;&amp;lt;a href=&amp;quot;/new&amp;quot;&amp;gt;New Task&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;    &amp;lt;?r if @tasks.empty? ?&amp;gt;&lt;br /&gt;      &amp;lt;p&amp;gt;No Tasks&amp;lt;/p&amp;gt;&lt;br /&gt;    &amp;lt;?r else ?&amp;gt;&lt;br /&gt;      &amp;lt;table&amp;gt;&lt;br /&gt;  &amp;lt;?r @tasks.each do |title, toggle, delete| ?&amp;gt;&lt;br /&gt;    &amp;lt;tr&amp;gt;&lt;br /&gt;      &amp;lt;td class=&amp;quot;title&amp;quot; &amp;gt; #{title}  &amp;lt;/td&amp;gt;&lt;br /&gt;      &amp;lt;td class=&amp;quot;toggle&amp;quot;&amp;gt; #{toggle} &amp;lt;/td&amp;gt;&lt;br /&gt;      &amp;lt;td class=&amp;quot;delete&amp;quot;&amp;gt; #{delete} &amp;lt;/td&amp;gt;&lt;br /&gt;    &amp;lt;/tr&amp;gt;&lt;br /&gt;  &amp;lt;?r end ?&amp;gt;&lt;br /&gt;      &amp;lt;/table&amp;gt;&lt;br /&gt;    &amp;lt;?r end ?&amp;gt;&lt;/pre&gt;The full source code is attached in the comments to this post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-9010162721388153464?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/9010162721388153464/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=9010162721388153464' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/9010162721388153464'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/9010162721388153464'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/11/ramaze-first-impressions-continued.html' title='Ramaze - first impressions continued'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_eJ-aAjApSE0/SRh0zWr537I/AAAAAAAAA7U/aPEF9ti41Yg/s72-c/notdone_sml.gif' height='72' width='72'/><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-267417439390048160</id><published>2008-11-08T16:12:00.000Z</published><updated>2008-11-08T16:44:51.467Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Motoring'/><title type='text'>Headlights</title><content type='html'>While I'm on the subject of motoring, why is it that some people insist on driving along well-lit roads at night with headlights on full-power dipped beam or even high beam? It doesn't allow them to see any better, but significantly impairs the ability of oncoming drivers to see what's near their car. Many's the time when I have been uncertain of the amount of space between a dazzling pair of headlamps on the opposite side of the road and parked vehicles on my side, so that I have had to stop. Once I nearly knocked down a guy crossing the road behind a car coming towards me - he was wearing dark clothes and was simply hidden by the glare from the headlamps.&lt;br /&gt;&lt;br /&gt;The only situation in which I will agree that the use of something stronger than sidelights is useful is when I'm approaching a corner. Traffic coming from another direction announces itself by the headlight beam cast ahead. Yet even this is sometimes misleading, as there are plenty of idiots who will park at the side of the road leaving their headlamps switched on. As we don't need this kind of advance warning during the daytime, why should it be required at night?&lt;br /&gt;&lt;br /&gt;I always choose sidelights or dim-dip headlights when motoring in areas with good street lighting, out of consideration to other drivers - yet they frequently flash me, assuming that I have forgotten to switch on my lights properly. Other sins include the use of fog lights front and rear when there is no fog. This is particularly dangerous when the road is wet, because they are mounted low down and the reflections off the water can almost blind other road users.&lt;br /&gt;&lt;br /&gt;Rules 113 and 114 of the &lt;a href="http://www.direct.gov.uk/en/TravelAndTransport/Highwaycode/DG_070190"&gt;Highway Code&lt;/a&gt; sum up the requirements of the law, which seem perfectly common-sense:&lt;br /&gt;&lt;br /&gt;You MUST&lt;br /&gt;&lt;ul&gt;&lt;li&gt;ensure all sidelights and rear registration plate lights are lit between sunset and sunrise&lt;br /&gt;&lt;/li&gt;&lt;li&gt;use headlights at night, except on a road which has lit street lighting. These roads are generally restricted to a speed limit of 30 mph (48 km/h) unless otherwise specified&lt;br /&gt;&lt;/li&gt;&lt;li&gt;use headlights when visibility is seriously reduced (see Rule 226)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Night (the hours of darkness) is defined as the period between half an hour after sunset and half an hour before sunrise.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;You MUST NOT&lt;br /&gt;&lt;ul&gt;&lt;li&gt;use any lights in a way which would dazzle or cause discomfort to other road users, including pedestrians, cyclists and horse riders&lt;br /&gt;&lt;/li&gt;&lt;li&gt;use front or rear fog lights unless visibility is seriously reduced. You MUST switch them off when visibility improves to avoid dazzling other road users (see Rule 226)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;In stationary queues of traffic, drivers should apply the parking brake and, once the following traffic has stopped, take their foot off the footbrake to deactivate the vehicle brake lights. This will minimise glare to road users behind until the traffic moves again.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-267417439390048160?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/267417439390048160/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=267417439390048160' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/267417439390048160'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/267417439390048160'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/11/headlights.html' title='Headlights'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-7390189407264128987</id><published>2008-11-08T15:49:00.000Z</published><updated>2008-11-08T16:11:02.417Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Motoring'/><category scheme='http://www.blogger.com/atom/ns#' term='London'/><title type='text'>Driving and Parking in London</title><content type='html'>If you want to keep your sanity, don't own a car in London. Occasionally however, you need one. For those occasions, I'm very much in favour of car-club schemes like &lt;a href="http://www.citycarclub.co.uk/"&gt;CityCarClub&lt;/a&gt;, &lt;a href="http://zipcar.co.uk/"&gt;ZipCar&lt;/a&gt; and &lt;a href="http://streetcar.co.uk/"&gt;StreetCar&lt;/a&gt;, but none of them has a depot anywhere near my house yet. So I still own a car, but I don't use it very much. At certain times of day, I have found that it actually took me longer to drive somewhere than it would have taken to walk. And you don't have to pay a congestion charge for walking.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;However, I'm currently on a project that involves flying to a customer site in Europe several times a month, leaving London City Airport very early in the morning - so early in fact that I would miss the flight if I tried to go by public transport. In the past, I have used a minicab instead, but fares have recently gone up so much that I resorted to driving to the airport myself. If you stay at least two days, you can book a space at the airport car park on the Internet and save a fair bit of money, but not for a single day - and the parking costs almost as much as the minicab.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To the rescue came a new service called &lt;a href="http://www.parkatmyhouse.com/"&gt;ParkAtMyHouse&lt;/a&gt;. Such a simple yet elegant idea - anyone with a garage or a bit of parking space can advertise it on-line and you simply haggle about the price. The web site handles the reservation and communication between owner and renter of the space. There's a feedback mechanism similar to eBay. The service levies a fee of 10% of the rent paid for its services, which seems reasonable as you would not have any other way of discovering these cheap parking spaces. You can rent by the hour, day, week, month or longer. I didn't find anything very close to the airport, but only two stops away on the DLR was someone willing to rent me a space for only £5 a day - job done!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-7390189407264128987?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/7390189407264128987/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=7390189407264128987' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/7390189407264128987'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/7390189407264128987'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/11/driving-and-parking-in-london.html' title='Driving and Parking in London'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-1314488858923055794</id><published>2008-11-05T23:49:00.000Z</published><updated>2008-11-10T16:43:14.607Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><category scheme='http://www.blogger.com/atom/ns#' term='Rack'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse pde'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='Ramaze'/><title type='text'>Ramaze - first impressions</title><content type='html'>I've spent the past couple of days evaluating &lt;a href="http://ramaze.net/"&gt;Ramaze&lt;/a&gt;. I started with the tutorial To-Do-List example and tried to move beyond that to something resembling a real web application backed with a proper database (MySQL). In general, I feel that this framework is more intuitive to use and therefore gets results faster than e.g. &lt;a href="http://www.rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt;, if you're having to learn both from scratch. I also found it very easy to refactor the code, because it encourages a fairly aspect-oriented style and all changes are loaded immediately without having to re-start the server. Last but not least, the designers of Ramaze have considered enterprise-level deployment requirements from the very start, so your Ramaze application can run on anything from a shared virtual host rented for a few dollars per year to an enterprise server farm or on-demand compute-cloud configurations.&lt;br /&gt;&lt;br /&gt;Ramaze also leverages the power of Ruby in very elegant ways. For example, here's a description of a &lt;a href="http://ducktyped.com/2008/8/1/a-minimal-cms-module-for-ramaze-apps"&gt;basic content-management system&lt;/a&gt; based on Ramaze in just a single page of code.&lt;br /&gt;&lt;br /&gt;I'm going to walk you through the &lt;a href="http://ramaze.net/tutorials:todolist"&gt;to-do list tutorial&lt;/a&gt;, which dates back to 31st January 2008. Ramaze has evolved a fair bit since then and I have had to find out what the changes are to adapt the tutorial to the current version. Hopefully my observations will be incorporated in a future version of the tutorial. All of my work was done on Windows XP (blame my employer, not me :-) so the installation instructions etc. are related to that.&lt;br /&gt;&lt;br /&gt;First of all, if you don't yet have &lt;a href="http://www.ruby-lang.org/"&gt;Ruby&lt;/a&gt; and Ramaze installed, here's how you do it:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Grab the latest &lt;a href="http://www.ruby-lang.org/en/downloads/"&gt;Ruby installer&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Install with default options&lt;/li&gt;&lt;li&gt;Open a command shell and make sure that your Ruby bin directory is on the PATH&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"  style=" font-weight: bold;font-family:'courier new';"&gt;gem install ramaze&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;You may find yourself being asked to approve the installation of various dependencies. Just agree to each one. If gem offers you options (ruby, java, mswin32 etc.), choose "ruby" or "mswin32" (assuming you're on a Windows 32-bit machine).&lt;br /&gt;&lt;br /&gt;My next big problem came with &lt;a href="http://www.eclipse.org/"&gt;Eclipse&lt;/a&gt;. I wanted to use Eclipse as my IDE for Ruby and Ramaze. Trying to use the Help -&gt; Software Updates feature to install Ruby support, I discovered by much trial and error that it was possible to do so, provided you configure the update site http://update.aptana.com/update/rails/3.2/ and select "Uncategorized -&gt; Ruby Development Tools" and nothing else. Using this plug-in, you get a language-sensitive editor and the ability to launch Ruby applications, not much else, but it's a whole lot better than using just a text editor. The first time you try to open the Ruby perspective, the Hierarchy pane displays an error message ("Could not create the view: org/eclipse/search/internal/ui/text/ResourceTransferDragAdapter"). Just close it and use the Navigator pane instead. I'd be interested to know if there is a better Ruby plug-in for Eclipse.&lt;br /&gt;&lt;br /&gt;While I was about it, I also installed the Web Page Editor from one of the Eclipse update sites. This came in useful when I was working on template pages later.&lt;br /&gt;&lt;br /&gt;Then I started working my way through the tutorial. The first discrepancy came in &lt;a href="http://ramaze.net/tutorials:todolist-3"&gt;chapter 3&lt;/a&gt; - the View. Ramaze has evolved so that you supply just partial pages under the &lt;span class="Apple-style-span"  style=" font-weight: bold;font-family:'courier new';"&gt;view&lt;/span&gt; folder. So the &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;view/index.xhtml&lt;/span&gt;&lt;/span&gt; file in the tutorial should contain only the part of the page that will be supplied to the main page template in the variable &lt;span class="Apple-style-span"  style=" font-weight: bold;font-family:'courier new';"&gt;@content&lt;/span&gt;. It looks like this:&lt;br /&gt;&lt;pre&gt;  &amp;lt;ul&amp;gt;&lt;br /&gt;   &amp;lt;?r&lt;br /&gt;     TodoList.each do |title, value|&lt;br /&gt;     status = value[:done] ? 'done' : 'not done'&lt;br /&gt;   ?&amp;gt;&lt;br /&gt;     &amp;lt;li&amp;gt;#{title}: #{status}&amp;lt;/li&amp;gt;&lt;br /&gt;   &amp;lt;?r end ?&amp;gt;&lt;br /&gt; &amp;lt;/ul&amp;gt;&lt;/pre&gt;Of course, at this stage you won't have assigned a value to &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;@title&lt;/span&gt;&lt;/span&gt;, so your page will be rendered without a page title or first heading.&lt;br /&gt;&lt;br /&gt;Also on this page, ignore the instruction to "run ramaze" from the command line. That won't work under Windows. Instead, Eclipse comes to the rescue. Just right-click the &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;start.rb&lt;/span&gt;&lt;/span&gt; file in the Navigator pane and select "Run As... -&gt; Ruby Application". When you want to terminate the server, click the red stop button in the console pane. Subsequently you can re-run the server by selecting &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;start.rb&lt;/span&gt;&lt;/span&gt; from the pull-down menu under Eclipse's green Run button.&lt;br /&gt;&lt;br /&gt;In &lt;a href="http://ramaze.net/tutorials:todolist-4"&gt;chapter 4&lt;/a&gt; of the tutorial, again please omit the HTML scaffolding and just write&lt;br /&gt;&lt;pre&gt;  &amp;lt;?r if @tasks.empty? ?&amp;gt;&lt;br /&gt;   No Tasks&lt;br /&gt; &amp;lt;?r else ?&amp;gt;&lt;br /&gt;   &amp;lt;ul&amp;gt;&lt;br /&gt;     &amp;lt;?r @tasks.each do |title, status| ?&amp;gt;&lt;br /&gt;       &amp;lt;li&amp;gt;#{title}: #{status}&amp;lt;/li&amp;gt;&lt;br /&gt;     &amp;lt;?r end ?&amp;gt;&lt;br /&gt;   &amp;lt;/ul&amp;gt;&lt;br /&gt; &amp;lt;?r end ?&amp;gt;&lt;/pre&gt;Now add the following line at the very top of the &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;index&lt;/span&gt;&lt;/span&gt; method:&lt;br /&gt;&lt;pre&gt;  @title = ["To-Do List"]&lt;/pre&gt;The standard page template inserts this value both in the page title and the top-level heading. You may have noticed that the &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;MainController&lt;/span&gt;&lt;/span&gt; contains the line&lt;br /&gt;&lt;pre&gt;  layout '/page'&lt;/pre&gt;This indicates that the file &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;view/page.xhtml&lt;/span&gt;&lt;/span&gt; will be used as the template, not &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;src/element/page.rb&lt;/span&gt;&lt;/span&gt; as described in the tutorial.&lt;br /&gt;&lt;br /&gt;In &lt;a href="http://ramaze.net/tutorials:todolist-5"&gt;chapter 5&lt;/a&gt; of the tutorial, obviously you should not add the level-one heading as shown. Just put the link at the very top of the file &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;view/index.xhtml&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Next, the new file &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;view/new.xhtml&lt;/span&gt;&lt;/span&gt; is also much simplified:&lt;br /&gt;&lt;pre&gt;  &amp;lt;a href="/"&amp;gt;Back to TodoList&amp;lt;/a&amp;gt;&lt;br /&gt; &amp;lt;form method="POST" action="create"&amp;gt;&lt;br /&gt;   Task: &amp;lt;input type="text" name="title" /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;   &amp;lt;input type="submit" /&amp;gt;&lt;br /&gt; &amp;lt;/form&amp;gt;&lt;/pre&gt;Before creating an action for &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;create&lt;/span&gt;&lt;/span&gt;, as described in the tutorial, you will also need an action for &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;new&lt;/span&gt;&lt;/span&gt;. This is the only way that I have found to generate a title for the &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;new.xhtml&lt;/span&gt;&lt;/span&gt; page. Insert the following in &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;main.rb&lt;/span&gt;&lt;/span&gt;:&lt;br /&gt;&lt;pre&gt;def new&lt;br /&gt;@title = ["Create a new To-Do List item"]&lt;br /&gt;# See view/new.xhtml&lt;br /&gt;end&lt;/pre&gt;&lt;a href="http://ramaze.net/tutorials:todolist-6"&gt;Chapter 6&lt;/a&gt; of the tutorial remains pretty much unchanged. Just remember not to delete the &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;@title&lt;/span&gt;&lt;/span&gt; initialisation at the very top of the &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;index&lt;/span&gt;&lt;/span&gt; method.&lt;br /&gt;&lt;br /&gt;In &lt;a href="http://ramaze.net/tutorials:todolist-7"&gt;chapter 7&lt;/a&gt; of the tutorial, I found that I was able to add and delete tasks to my heart's content until I tried deleting a task such as "Lunch with Bob?". Ramaze has a very simple mapping scheme from URL path to action argument, which stops parsing the path_info as soon as it encounters a "?" or ";". I spent a considerable amount of time trying to think of ways to circumvent this and pass the offending characters as url-encoded escape sequences, but in the end it was all to no avail. The lesson is that you would be well advised to never use user-supplied values as keys into your data. Instead, treat the user-supplied string as a data field and generate your own system ID for each item. By the way, this lesson applies equally well in other frameworks. Following my completion of the tutorial I will show how I refactored the code to achieve greater robustness. For now, just avoid using metacharacters in your task titles!&lt;br /&gt;&lt;br /&gt;The solution to the problem of stuck tasks was of course to edit the YAML database file to delete the offending characters.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ramaze.net/tutorials:todolist-8"&gt;Chapter 8&lt;/a&gt; of the tutorial seems to me now to be more or less redundant. All I had to do was to modify the file &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;view/page.xhtml&lt;/span&gt;&lt;/span&gt; slightly to incorporate the error message from the &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;flash&lt;/span&gt;&lt;/span&gt; object. Here's the resulting body section:&lt;br /&gt;&lt;pre&gt;   &amp;lt;h1&amp;gt;#{@title}&amp;lt;/h1&amp;gt;&lt;br /&gt;  &amp;lt;div id="error"&amp;gt;&lt;br /&gt;    &amp;lt;p&amp;gt;#{flash[:error]}&amp;lt;/p&amp;gt;&lt;br /&gt;  &amp;lt;/div&amp;gt;&lt;br /&gt;  &amp;lt;div id="content"&amp;gt;&lt;br /&gt;    #@content&lt;br /&gt;  &amp;lt;/div&amp;gt;&lt;/pre&gt;Note that there is no need for any logic to decide whether an error message is present. If it's there, it gets rendered as part of the page. Otherwise the renderer omits that element.&lt;br /&gt;&lt;br /&gt;The prettification step in &lt;a href="http://ramaze.net/tutorials:todolist-9"&gt;chapter 9&lt;/a&gt; of the tutorial still applies as it stands, except that the stylesheet entries are inserted into the file &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;view/page.xhtml&lt;/span&gt;&lt;/span&gt; instead of the &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;Page&lt;/span&gt;&lt;/span&gt; element. I also added a style for the error message, where present. The resulting HTML header now contains the following entries:&lt;br /&gt;&lt;pre&gt;   &amp;lt;style type="text/css"&amp;gt;&lt;br /&gt;    body      { margin:      2em; font-family:Verdana }&lt;br /&gt;    #content  { margin-left: 2em;               }&lt;br /&gt;    #error    { margin-left: 2em; color:red;    }&lt;br /&gt;  &amp;lt;/style&amp;gt;&lt;br /&gt;  &amp;lt;style type="text/css"&amp;gt;&lt;br /&gt;    table     { width:       80%;               }&lt;br /&gt;    tr        { background:  #efe; width:100%;  }&lt;br /&gt;    tr:hover  { background:  #dfd;              }&lt;br /&gt;    td.title  { font-weight: bold; width: 60%;  }&lt;br /&gt;    td.status { margin:      1em;               }&lt;br /&gt;    a         { color:       #3a3;              }&lt;br /&gt;  &amp;lt;/style&amp;gt;&lt;/pre&gt;I had real fun in &lt;a href="http://ramaze.net/tutorials:todolist-10"&gt;chapter 10&lt;/a&gt; of the tutorial. Firstly, I had to install the mongrel adapter:&lt;br /&gt;&lt;pre&gt;gem install mongrel&lt;/pre&gt;For both mongrel itself and its &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;fastthread&lt;/span&gt;&lt;/span&gt; dependency, I chose the "ruby" option.&lt;br /&gt;When I tried to start Ramaze again, it complained that some other process was already listening on port 80. After some detective work with process explorer, I discovered that this was a little peer-to-peer application called &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;kservice&lt;/span&gt;&lt;/span&gt; from Kontiki Inc. I had probably unwittingly installed it with some Internet media player. After following the &lt;a href="http://www.opinionatedgeek.com/Blog/blogentry=000175/BlogEntry.aspx"&gt;uninstall instructions&lt;/a&gt; kindly blogged by "Geoff" I was finally able to start my server on port 80.&lt;br /&gt;&lt;br /&gt;(to be continued)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-1314488858923055794?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/1314488858923055794/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=1314488858923055794' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/1314488858923055794'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/1314488858923055794'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/11/ramaze-first-impressions.html' title='Ramaze - first impressions'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-2935571706316401276</id><published>2008-10-31T11:34:00.000Z</published><updated>2008-10-31T11:43:44.305Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='SOA'/><category scheme='http://www.blogger.com/atom/ns#' term='virtualisation'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><title type='text'>SOA adoption reported to be accelerating</title><content type='html'>I was interested to read &lt;a href="http://www.ebizq.net/blogs/archives/2008/10/the_acceleratio_1.php"&gt;this interview&lt;/a&gt; with Jason English, the VP of Corporate Marketing for iTKO. It shows that Service Oriented Architecture is coming of age when vendors are offering viable testing and virtualisation solutions.&lt;br /&gt;&lt;br /&gt;It also previews the virtual conference &lt;a href="http://www.ebizq.net/events/soa_in_action/"&gt;SOA in Action&lt;/a&gt;, coming on November 19th, 2008, for which it looks as if it is free to sign up. "SOA in Action will feature keynotes by Gartner's Yefim Natis and Forrester's Randy Heffner, as well as a panel discussion led by ebizQ's Joe McKendrick and featuring Phil Wainewright of ZDNet and Dr. Chris Harding of The Open Group."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-2935571706316401276?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/2935571706316401276/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=2935571706316401276' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/2935571706316401276'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/2935571706316401276'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/10/soa-adoption-reported-to-be.html' title='SOA adoption reported to be accelerating'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-7616376357084768912</id><published>2008-10-29T05:03:00.000Z</published><updated>2008-10-28T22:09:31.470Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Native'/><title type='text'>Java Native Access</title><content type='html'>Every Java programmer knows about &lt;a href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/"&gt;JNI&lt;/a&gt;, but what about &lt;a href="https://jna.dev.java.net/"&gt;JNA&lt;/a&gt;?&lt;br /&gt;&lt;br /&gt;I'm pretty impressed with this. The documentation seems pretty comprehensive and the examples are well constructed. The software seems very stable. Obviously you can kill the VM if you dereference invalid pointers etc., but after a short period of familiarisation, I found that I could knock together a Java API for a subset of an existing C/C++ DLL (&lt;a href="http://msdn.microsoft.com/en-us/library/aa163249.aspx"&gt;kernel32&lt;/a&gt;), using just the published API documentation to guide me, in very little time. I wrote a little test program that gets the compressed and uncompressed size of arbitrary files, and prints proper error messages for files it cannot open.&lt;br /&gt;&lt;br /&gt;I make no claim that the example code is particularly elegant, but it shows what you can do. One great advantage is that you don't need to install a separate C/C++ development environment if a DLL already exists that gives you the needed native functionality.&lt;br /&gt;&lt;br /&gt;Note that JNI is built for raw speed - some applications use it for example to perform graphics manipulations thousands of times a second. Using JNA, because it uses inspection and all kinds of clever tricks, you need to budget about ten times as much execution time per transition from Java to native machine code and back again. For many applications, that's irrelevant because native code is only called infrequently (up to a few hundred times a second).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-7616376357084768912?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/7616376357084768912/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=7616376357084768912' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/7616376357084768912'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/7616376357084768912'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/10/java-native-access.html' title='Java Native Access'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-937647617636049821</id><published>2008-10-14T19:04:00.000+01:00</published><updated>2008-10-14T11:06:46.147+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ITIL'/><category scheme='http://www.blogger.com/atom/ns#' term='VMWare'/><category scheme='http://www.blogger.com/atom/ns#' term='virtualisation'/><title type='text'>Myths and Realities about Virtualisation</title><content type='html'>I just came across an excellent article by Amrit Williams entitled &lt;a href="http://techbuddha.wordpress.com/2008/09/26/myths-misconceptions-half-truths-and-lies-about-virtualization/"&gt;Myths, Misconceptions, Half-Truths and Lies about Virtualization&lt;/a&gt;. Read it especially for the discussion thread that follows it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-937647617636049821?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/937647617636049821/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=937647617636049821' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/937647617636049821'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/937647617636049821'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/10/myths-and-realities-about.html' title='Myths and Realities about Virtualisation'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-1792251352445971401</id><published>2008-10-14T17:49:00.000+01:00</published><updated>2008-10-14T10:02:58.743+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Canoo'/><category scheme='http://www.blogger.com/atom/ns#' term='test-driven development'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><category scheme='http://www.blogger.com/atom/ns#' term='Hibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='WebTest'/><category scheme='http://www.blogger.com/atom/ns#' term='jMock'/><title type='text'>New Test-Driven Development training course</title><content type='html'>I have just completed work on a training course in test-driven development, intended for delivery over two days or self-study, which uses the development of a dating service as a worked example. Along the way, students will learn to use &lt;a href="http://en.wikipedia.org/wiki/Data_Access_Object"&gt;data access objects&lt;/a&gt; (DAO), &lt;a href="http://en.wikipedia.org/wiki/Object-relational_mapping"&gt;Object-Relational Mapping&lt;/a&gt; (ORM) using &lt;a href="http://www.hibernate.org/"&gt;Hibernate&lt;/a&gt;, &lt;a href="http://www.springframework.org/"&gt;Spring&lt;/a&gt;, &lt;a href="http://www.jmock.org/"&gt;jMock&lt;/a&gt; and &lt;a href="http://webtest.canoo.com/"&gt;Canoo WebTest&lt;/a&gt;. These tools will, I hope, provide them with good insights into the way that test-driven approaches alter the way in which software architectures grow, leading to more robust yet flexible designs.&lt;br /&gt;&lt;br /&gt;My thanks to &lt;a href="http://witi-work.blogspot.com/"&gt;Adam Shimali&lt;/a&gt;, who developed the material initially. He and I aim to present a five-hour "taster" of this course on the Sunday afternoon at &lt;a href="http://www.spa2009.org/"&gt;SPA2009&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-1792251352445971401?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/1792251352445971401/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=1792251352445971401' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/1792251352445971401'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/1792251352445971401'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/10/new-test-driven-development-training.html' title='New Test-Driven Development training course'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-5515387401948032415</id><published>2008-10-14T17:40:00.000+01:00</published><updated>2008-10-14T09:47:50.351+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='teams'/><category scheme='http://www.blogger.com/atom/ns#' term='software practice'/><category scheme='http://www.blogger.com/atom/ns#' term='soft skills'/><title type='text'>Improving team dynamics</title><content type='html'>Interested in making your team more effective? I found the following &lt;a href="http://www.cateams.com/index.php?id=48"&gt;list of useful links&lt;/a&gt; just now after reconnecting to a former colleague on &lt;a href="http://pulse.plaxo.com/pulse/"&gt;Plaxo Pulse&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;And of course, my own company &lt;a href="http://tinyurl.com/34mdeb"&gt;Zühlke Engineering&lt;/a&gt; offers tools, coaching and training to agile teams.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-5515387401948032415?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/5515387401948032415/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=5515387401948032415' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/5515387401948032415'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/5515387401948032415'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/10/improving-team-dynamics.html' title='Improving team dynamics'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-9182546294296961435</id><published>2008-08-05T18:15:00.000+01:00</published><updated>2008-08-05T10:47:41.374+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vcf'/><category scheme='http://www.blogger.com/atom/ns#' term='Perl'/><category scheme='http://www.blogger.com/atom/ns#' term='Regular Expressions'/><category scheme='http://www.blogger.com/atom/ns#' term='Regex'/><category scheme='http://www.blogger.com/atom/ns#' term='vcard'/><title type='text'>Importing free-format address lists into vCard (.vcf) and Excel</title><content type='html'>A colleague had the following problem: he had a Word document containing information about many different companies he dealt with. They were more or less in a standardised form, with the name of the company on the first line of each "record" and the address on the second (or on the same line in some cases), but after that it was pretty haphazard - sometimes telephone numbers were prefixed with TEL:, sometimes not, sometimes the URLs were listed beneath a heading of "Websites:", sometimes not, and so on.&lt;br /&gt;&lt;br /&gt;His desire was to export this information in a form that it could be treated much more like a proper database - spreadsheet format would be a start. Exporting the Word document to text was easy, but where to go from there? I started toying around with a Perl script to try to clean up the data, and found that there were some convenient modules around for capturing input to a vCard standard format.&lt;br /&gt;&lt;br /&gt;The attached script uses the &lt;a href="http://search.cpan.org/%7Ellap/Text-vCard-2.03/lib/Text/vCard.pm"&gt;Text::vCard&lt;/a&gt; module (which you'll have to install manually from CPAN as it isn't available using PPM) with its Addressbook and Node packages to build up a whole address book from the input file. Although I have made no attempt at elegance, it has a good stab at parsing UK-style and US-style company names and addresses into their constituent fields, provided they are separated by commas. NB there are no contact names, as the original data file didn't have any - this is left as an exercise for the reader!&lt;br /&gt;&lt;span style="font-size:78%;"&gt;&lt;pre&gt;#!/usr/bin/perl -w&lt;br /&gt;#&lt;br /&gt;# convert a file to address records in VCF (vCard) format&lt;br /&gt;# reads standard input and writes to standard output&lt;br /&gt;#&lt;br /&gt;if ( $#ARGV + 1 != 0 ) {&lt;br /&gt;  print STDERR "usage: parse_addresses &amp;lt;inputfile.txt &amp;gt;outputfile.vcf\n";&lt;br /&gt;  exit;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;use Text::vCard::Addressbook;&lt;br /&gt;&lt;br /&gt;my $addressbook = new Text::vCard::Addressbook;&lt;br /&gt;# For testing / debugging: load a pre-existing address book&lt;br /&gt;#my $addressbook =&lt;br /&gt;#  Text::vCard::Addressbook-&amp;gt;new(&lt;br /&gt;#  { 'source_file' =&amp;gt; 'C:/temp/Text-vCard-2.03/rfc2426.vcf', } );&lt;br /&gt;&lt;br /&gt;while ( !eof STDIN ) {&lt;br /&gt;  parseEntry($addressbook);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;print $addressbook-&amp;gt;export();&lt;br /&gt;&lt;br /&gt;sub parseEntry {&lt;br /&gt;  my ($addressbook) = @_;&lt;br /&gt;&lt;br /&gt;  my $line = &amp;lt;STDIN&amp;gt;;&lt;br /&gt;  chomp($line);&lt;br /&gt;&lt;br /&gt;  # First line should contain organisation name and optionally its address&lt;br /&gt;  my ( $org, $addr );&lt;br /&gt;  if ( $line =~ m'^\s*([0-9A-Za-z][^:]*)\:?\s*$' ) {&lt;br /&gt;    $org = $1;&lt;br /&gt;    chomp( $line = &amp;lt;STDIN&amp;gt; );&lt;br /&gt;    $addr = $line;&lt;br /&gt;  }&lt;br /&gt;  elsif ( $line =~ m'^\s*([0-9A-Za-z][^:]*)\:\s*(\S.*)$' ) {&lt;br /&gt;    $org  = $1;&lt;br /&gt;    $addr = $2;&lt;br /&gt;  }&lt;br /&gt;  else {&lt;br /&gt;    # Not recognised&lt;br /&gt;    print STDERR "Not recognised start of entry: $line\n";&lt;br /&gt;    while ( ( defined $line ) &amp;&amp; ( $line !~ '^\s*$' ) ) {&lt;br /&gt;      chomp( $line = &amp;lt;STDIN&amp;gt; );&lt;br /&gt;      print STDERR "Discarding: $line\n";&lt;br /&gt;    }&lt;br /&gt;    return undef;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  # print STDERR "Organisation: $org -- Address: $addr\n";&lt;br /&gt;  my $vCard = $addressbook-&amp;gt;add_vcard();&lt;br /&gt;  $vCard-&amp;gt;version('3.0');&lt;br /&gt;  $vCard-&amp;gt;add_node({ 'node_type' =&amp;gt; 'ORG' })-&amp;gt;name($org);&lt;br /&gt;  my $adr = $vCard-&amp;gt;add_node( { 'node_type' =&amp;gt; 'ADR' } );&lt;br /&gt;  my @unsorted = ();&lt;br /&gt;  $addr =~ s/\W*$//; # Remove trailing spaces and full-stops&lt;br /&gt;  foreach my $adrField ( split( ',', $addr ) ) {&lt;br /&gt;    if ( $adrField =~ m'^\s*([A-Z][A-Za-z ]+\s)?([-0-9]{4,11})\s*([A-Z][A-Za-z]+)?\s*$' ) {&lt;br /&gt;      # US state and zip-code&lt;br /&gt;      my $state = $1;&lt;br /&gt;      chop( $state ) if defined $state;&lt;br /&gt;      my $zip_code = $2;&lt;br /&gt;      my $country = $3;&lt;br /&gt;      if ( defined $state ) { $adr-&amp;gt;region($state); }&lt;br /&gt;      $adr-&amp;gt;post_code($zip_code);&lt;br /&gt;      if ( defined $country ) { $adr-&amp;gt;country($country); }&lt;br /&gt;    } elsif ( $adrField =~ m'^\s*([A-Z][A-Za-z ]+\s)?([A-Z]{1,2}[0-9O]{1,2}[A-Z]? [0-9O]{1,2}[A-Z]{2})\s*([A-Z][A-Za-z ]+)?\s*$' ) {&lt;br /&gt;      # UK county and post-code&lt;br /&gt;      my $county = $1;&lt;br /&gt;      chop ($county) if defined $county;&lt;br /&gt;      my $post_code = $2;&lt;br /&gt;      my $country = $3;&lt;br /&gt;      if ( defined $county ) { $adr-&amp;gt;region($county); }&lt;br /&gt;      $post_code =~ s/O([0-9][A-Z]?) ([0-9])/0$1 $2/;&lt;br /&gt;      $post_code =~ s/O([A-Z])? ([0-9])/0$1 $2/;&lt;br /&gt;      $post_code =~ s/ O([0-9])/ O$1/;&lt;br /&gt;      $post_code =~ s/ ([0-9])O([A-Z]{2})/ $1O$2/;&lt;br /&gt;      $adr-&amp;gt;post_code($post_code);&lt;br /&gt;      if ( defined $country ) { $adr-&amp;gt;country($country); }&lt;br /&gt;    } elsif ( $adrField =~ m'P.*BOX\s*(\d+)'i ) {&lt;br /&gt;      # Post Office Box&lt;br /&gt;      my $po_box = $1;&lt;br /&gt;      $adr-&amp;gt;po_box($po_box);&lt;br /&gt;    } elsif ( $adrField =~ m'^\s*(\d+\s+[A-Za-z0-9 ]+$)' ) {&lt;br /&gt;      # House number and street&lt;br /&gt;      my $street = $1;&lt;br /&gt;      $adr-&amp;gt;street($street);&lt;br /&gt;    } elsif ( $adrField =~ m'^\s*([A-Z][A-Za-z0-9 ]+$)' ) {&lt;br /&gt;      push @unsorted, $1;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  # Retrieve unsorted items in reverse order&lt;br /&gt;  if (!defined $adr-&amp;gt;country() &amp;&amp; $#unsorted &amp;gt; 2) {&lt;br /&gt;    my $country = pop @unsorted;&lt;br /&gt;    if (defined $country &amp;&amp; $country =~ m'[A-Z][A-Za-z ]+') {&lt;br /&gt;      $adr-&amp;gt;country( $country );&lt;br /&gt;    } else {&lt;br /&gt;      push @unsorted, $country;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  if (!defined $adr-&amp;gt;region() &amp;&amp; $#unsorted &amp;gt; 1) {&lt;br /&gt;    my $region = pop @unsorted;&lt;br /&gt;    if (defined $region &amp;&amp; $region =~ m'[A-Z][A-Za-z ]+') {&lt;br /&gt;      $adr-&amp;gt;region( $region );&lt;br /&gt;    } else {&lt;br /&gt;      push @unsorted, $region;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  if (!defined $adr-&amp;gt;city()) {&lt;br /&gt;    my $city = pop @unsorted;&lt;br /&gt;    if (defined $city &amp;&amp; $city =~ m'[A-Z][A-Za-z ]+') {&lt;br /&gt;      $adr-&amp;gt;city( $city );&lt;br /&gt;    } else {&lt;br /&gt;      push @unsorted, $city;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  if (!defined $adr-&amp;gt;street()) {&lt;br /&gt;    $adr-&amp;gt;street( pop @unsorted );&lt;br /&gt;  }&lt;br /&gt;  if ($#unsorted &amp;gt;= 0) {&lt;br /&gt;    $adr-&amp;gt;extended ( join (', ', @unsorted) );&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  chomp( $line = &amp;lt;STDIN&amp;gt; );&lt;br /&gt;  while ( ( defined $line ) &amp;&amp; ( $line !~ '^\s*$' ) ) {&lt;br /&gt;    if ( $line =~ m'^\s*(https?\://\S+)'i ) {&lt;br /&gt;      $vCard-&amp;gt;url($1);&lt;br /&gt;    } elsif ( $line =~ m'(www\.\S+)'i ) {&lt;br /&gt;      $vCard-&amp;gt;url($1);&lt;br /&gt;    } elsif ( $line =~ m'(\S+@\S+)\s*$' ) {&lt;br /&gt;      my $email = $1;&lt;br /&gt;      my $node  = $vCard-&amp;gt;add_node( { 'node_type' =&amp;gt; 'EMAIL' } );&lt;br /&gt;      my @types = qw (work internet);&lt;br /&gt;      $node-&amp;gt;add_types( \@types );&lt;br /&gt;      $node-&amp;gt;value($email);&lt;br /&gt;    } elsif ( $line =~ m'^\s*(\+?[0-9() ]+)$' ) {&lt;br /&gt;      my $tel   = $1;&lt;br /&gt;      my $node  = $vCard-&amp;gt;add_node( { 'node_type' =&amp;gt; 'TEL' } );&lt;br /&gt;      my @types = qw (work voice);&lt;br /&gt;      $node-&amp;gt;add_types( \@types );&lt;br /&gt;      $node-&amp;gt;value($tel);&lt;br /&gt;    } elsif ( $line =~ m'^\s*tel.*\:\s*(\S.*)$'i ) {&lt;br /&gt;      my $tel   = $1;&lt;br /&gt;      my $node  = $vCard-&amp;gt;add_node( { 'node_type' =&amp;gt; 'TEL' } );&lt;br /&gt;      my @types = qw (work voice);&lt;br /&gt;      $node-&amp;gt;add_types( \@types );&lt;br /&gt;      $node-&amp;gt;value($tel);&lt;br /&gt;    } elsif ( $line =~ m'^\s*fax.*\:\s*(\S.*)$'i ) {&lt;br /&gt;      my $tel   = $1;&lt;br /&gt;      my $node  = $vCard-&amp;gt;add_node( { 'node_type' =&amp;gt; 'TEL' } );&lt;br /&gt;      my @types = qw (work fax);&lt;br /&gt;      $node-&amp;gt;add_types( \@types );&lt;br /&gt;      $node-&amp;gt;value($tel);&lt;br /&gt;    } elsif ( $line =~ m'^[^:]*name[^:]*\:\s*(\S.*)$'i ) {&lt;br /&gt;      $vCard-&amp;gt;fn($1);&lt;br /&gt;    } elsif ( $line =~ m'^\s*([^:]+)\:\s*$' ) {&lt;br /&gt;      my $noteHead = $1;&lt;br /&gt;      chomp( $line = &amp;lt;STDIN&amp;gt; );&lt;br /&gt;      if ( $line =~ m'^\s*(https?\://\S+)'i ) {&lt;br /&gt;        $vCard-&amp;gt;url($1);&lt;br /&gt;      } elsif ( $line =~ m'(www\.\S+)'i ) {&lt;br /&gt;        $vCard-&amp;gt;url($1);&lt;br /&gt;      } elsif ( $line =~ m'(\S+@\S+)\s*$' ) {&lt;br /&gt;        my $email = $1;&lt;br /&gt;        my $node  = $vCard-&amp;gt;add_node( { 'node_type' =&amp;gt; 'EMAIL' } );&lt;br /&gt;        my @types = qw (work internet);&lt;br /&gt;        $node-&amp;gt;add_types( \@types );&lt;br /&gt;        $node-&amp;gt;value($email);&lt;br /&gt;      } elsif ( $line =~ m'^\s*(\+?[0-9() ]+)$' ) {&lt;br /&gt;        my $tel   = $1;&lt;br /&gt;        my $node  = $vCard-&amp;gt;add_node( { 'node_type' =&amp;gt; 'TEL' } );&lt;br /&gt;        my @types = qw (work voice);&lt;br /&gt;        $node-&amp;gt;add_types( \@types );&lt;br /&gt;        $node-&amp;gt;value($tel);&lt;br /&gt;      } else {&lt;br /&gt;        $vCard-&amp;gt;note("$noteHead: $line");&lt;br /&gt;      }&lt;br /&gt;    } elsif ( $line =~ m'^\s*([^:]+)\:\s*(\S.*)$' ) {&lt;br /&gt;      my $noteHead = $1;&lt;br /&gt;      my $note = $2;&lt;br /&gt;      $vCard-&amp;gt;note("$noteHead: $note");&lt;br /&gt;    } else {&lt;br /&gt;      print STDERR "Cannot understand entry detail: $line\n";&lt;br /&gt;    }&lt;br /&gt;    chomp( $line = &amp;lt;STDIN&amp;gt; );&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;1;    # End.&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;(Look out for cut-off long lines in the above - copy/paste works far better in Firefox than in Internet Explorer. If you have problems, ask me to e-mail you a copy of the script). The script spits out the resulting vCard file to the standard output. Anything it can't parse is echoed to standard error.&lt;br /&gt;&lt;br /&gt;I found a really nifty converter from VCF to CSV at &lt;a href="http://labs.brotherli.ch/vcfconvert/"&gt;http://labs.brotherli.ch/vcfconvert/&lt;/a&gt; - once you've got a pile of addresses in spreadsheet format, you can do anything with it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-9182546294296961435?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/9182546294296961435/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=9182546294296961435' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/9182546294296961435'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/9182546294296961435'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/08/importing-free-format-address-lists.html' title='Importing free-format address lists into vCard (.vcf) and Excel'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-4543742463232902121</id><published>2008-07-24T18:25:00.000+01:00</published><updated>2008-07-24T10:25:46.992+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Erlang'/><title type='text'>Dayfindr - a suitable case for viral marketing</title><content type='html'>I frequently recommend my colleague &lt;a href="http://21ccw.blogspot.com/"&gt;Ben Nortier's&lt;/a&gt; demonstration application &lt;a href="http://dayfindr.com/"&gt;Dayfindr&lt;/a&gt;. This is a simple calendar co-ordinator, allowing an arbitrarily large group of people to find a date or dates when everyone will be available to undertake some kind of joint activity, such as a meeting, theatre visit etc. Although it doesn't deal with subtleties like specific times of day, the comment facility is there to let you fine-tune your entries.&lt;br /&gt;&lt;br /&gt;Briefly, Ben put this together as an exercise in &lt;a href="http://www.erlang.org/"&gt;Erlang / OTP&lt;/a&gt; programming and it's getting an ever-increasing amount of use simply through word-of-mouth recommendation. So far it has easily coped with everything that's been thrown at it. Every time I show it to someone, it knocks them sideways with its straightforward simplicity, robustness and speed, even though it is hosted on a virtual server with very frugal memory and processor allocations. Give it a try and see what you think!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-4543742463232902121?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/4543742463232902121/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=4543742463232902121' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/4543742463232902121'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/4543742463232902121'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/07/dayfindr-suitable-case-for-viral.html' title='Dayfindr - a suitable case for viral marketing'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-8277429486400545715</id><published>2008-07-16T05:44:00.000+01:00</published><updated>2008-07-15T21:44:39.950+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software practice'/><title type='text'>Software Practice - The State of the Art</title><content type='html'>The British Computer Society's specialist group for  Software Practice Advancement is staging a series of talks entitled &lt;a href="http://www.bcs-spa.org/index.php?page=autumn-series"&gt;The State of the Art&lt;/a&gt;. This features five talks from six of the leading experts in their respective fields, ranging from architecture to team dynamics.&lt;br /&gt;&lt;br /&gt;It's excellent value at just £90 plus VAT - discounted to just £75 plus VAT for members of the specialist group or of the BCS generally. Numbers are limited, so book soon!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-8277429486400545715?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/8277429486400545715/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=8277429486400545715' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/8277429486400545715'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/8277429486400545715'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/07/software-practice-state-of-art.html' title='Software Practice - The State of the Art'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-6330653862028251083</id><published>2008-07-08T00:02:00.000+01:00</published><updated>2008-07-07T16:04:02.556+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='eclipse pde'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse rcp'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><title type='text'>Maven multi-module builds and Eclipse PDE</title><content type='html'>I have not blogged about Maven and Eclipse for a while, but I have learned a couple of important new lessons recently.&lt;br /&gt;&lt;br /&gt;1. Even though OSGI gives you the capability of supporting multiple versions of the same bundle simultaneously, the same isn't true of Eclipse features that contain those bundles (a.k.a. Eclipse plug-ins). So I discovered that when feature A depends on feature B and C, where B depends on feature D version 1.1.0 and C depends on feature D version 1.1.2, you will get two versions of feature D in your Eclipse target platform, resulting in a cryptic error message from the PDE build of the form "unable to find feature: D". What it means is that B wants version 1.1.0 of D, but this has been masked by the presence of version 1.1.2. Our likely approach to this will be to avoid putting version dependencies (at least, versions of included features) into feature.xml files at all. There is no need, after all: the precise versions of everything needed should be specified in the accompanying POM, which assembles the RCP target platform for the build.&lt;br /&gt;&lt;br /&gt;2. If you're using multi-module builds, there is no point in using goals such as "test" or "package". Unless you at least install the artifact created during the build of each module into your local Maven repository, the next module along will still get the previous version as a dependency, and the build will fail.&lt;br /&gt;&lt;br /&gt;3. If you're using multi-module builds, don't run the install or deploy goal in the same invocation as the site or site-deploy goal. Maven tries to generate the site documentation for the top level before it has built the subordinate levels, so the dependencies required to create the reports are not present and the build will fail. We now routinely run "mvn clean install" or "mvn clean deploy" followed by "mvn site" or "mvn site-deploy" respectively.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-6330653862028251083?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/6330653862028251083/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=6330653862028251083' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/6330653862028251083'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/6330653862028251083'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/07/maven-multi-module-builds-and-eclipse.html' title='Maven multi-module builds and Eclipse PDE'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-7552717879378050177</id><published>2008-05-12T05:15:00.000+01:00</published><updated>2008-05-11T21:18:57.158+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ID cards'/><category scheme='http://www.blogger.com/atom/ns#' term='Big Brother'/><category scheme='http://www.blogger.com/atom/ns#' term='national identity register'/><category scheme='http://www.blogger.com/atom/ns#' term='privacy'/><category scheme='http://www.blogger.com/atom/ns#' term='no2id'/><title type='text'>Government security experts express concerns about ID Card scheme</title><content type='html'>In today’s &lt;a href="http://www.guardian.co.uk/politics/2008/may/11/idcards.civilliberties"&gt;Observer&lt;/a&gt;, it is revealed that the Government’s own security experts are worried about Labour’s plans to introduce mandatory ID cards. Here are some choice quotes:&lt;br /&gt;&lt;br /&gt;"In a potentially damaging revelation, which undermines claims that the scheme will enhance national security, the group has concluded that [ID cards] will be prone to corruption...&lt;br /&gt;&lt;br /&gt;"The Isap report goes on to warn that the scheme may not be embraced by government departments, suggesting the cards are not being well received in some Whitehall departments.&lt;br /&gt;&lt;br /&gt;"The panel also warns the initiative is struggling to fulfil its remit. It states that the scheme lacks a ‘robust and transparent operational data governance regime and clear data architecture’, suggesting there is confusion over its roll-out."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-7552717879378050177?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/7552717879378050177/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=7552717879378050177' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/7552717879378050177'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/7552717879378050177'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/05/government-security-experts-express.html' title='Government security experts express concerns about ID Card scheme'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-3821534606801604735</id><published>2008-04-24T17:15:00.000+01:00</published><updated>2008-04-24T09:24:52.282+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='eclipse pde'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse rcp'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><title type='text'>Eclipse and Maven - a quick update</title><content type='html'>I have not posted anything about the progress of my researches into Eclipse and Maven integration for a while. That's because for a long time, we didn't get significantly further along in our research. But just recently we've started making significant progress again.&lt;br /&gt;&lt;br /&gt;A very important lesson was that the &lt;a href="http://mojo.codehaus.org/pde-maven-plugin/"&gt;pde-maven-plugin&lt;/a&gt; is really not worth persevering with - at least in our situation. We decided that we wanted to build every Eclipse plug-in and every Eclipse feature using its own POM, so that we could for example generate code coverage reports for each component individually and also configuration-manage them at that level of granularity. It turned out to be not all that difficult to invoke the PDE headless build for these circumstances from Maven using about two dozen lines of Ant script.&lt;br /&gt;&lt;br /&gt;After nine months of Eclipse 3.3, the pde-maven-plugin has still not been officially updated to handle the changes from Eclipse 3.2 (we had to use the &lt;a href="http://snapshots.repository.codehaus.org/org/codehaus/mojo/pde-maven-plugin/1.0-alpha-2-SNAPSHOT/"&gt;Alpha 2 snapshot&lt;/a&gt; version downloaded from Codehaus) and so we're concerned that we might have similar upward compatibility problems when Eclipse 3.4 comes out in a few months.&lt;br /&gt;&lt;br /&gt;When it's all been finalised, I hope to publish a longer explanation of how our build system works here. Don't hold your breath though; at the moment we still have to solve a few issues - for example, we need to figure out how to produce the source plug-ins alongside the executable ones.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-3821534606801604735?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/3821534606801604735/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=3821534606801604735' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/3821534606801604735'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/3821534606801604735'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/04/eclipse-and-maven-quick-update.html' title='Eclipse and Maven - a quick update'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-8494181141734365410</id><published>2008-04-03T22:47:00.000+01:00</published><updated>2008-04-03T14:47:35.767+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Regular Expressions'/><category scheme='http://www.blogger.com/atom/ns#' term='Regex'/><title type='text'>Having problems with string matching / replacing in Java?</title><content type='html'>I find it almost impossible to write Java &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/regex/Pattern.html"&gt;regular expressions&lt;/a&gt; correctly first time. They are pretty hard to get your head around (unless your head is a peculiar shape :-)&lt;br /&gt;&lt;br /&gt;A trial-and-error approach is much eased by FileFormat's &lt;a href="http://www.fileformat.info/tool/regex.htm"&gt;Regular Expression Test Page&lt;/a&gt;. At the bottom of the page you'll find a number of links to useful references and tutorials, which may help you eliminate some of the error from this approach.&lt;br /&gt;&lt;br /&gt;The site is worth bookmarking anyway for its range of format conversion tools and information about file extensions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-8494181141734365410?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/8494181141734365410/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=8494181141734365410' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/8494181141734365410'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/8494181141734365410'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/04/having-problems-with-string-matching.html' title='Having problems with string matching / replacing in Java?'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-5742813924307706624</id><published>2008-04-01T23:40:00.000+01:00</published><updated>2008-04-01T15:54:53.206+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='eclipse pde'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse rcp'/><title type='text'>Taking the pain out of Eclipse RCP builds and exports</title><content type='html'>It is well worth reading the manual, as the old saying goes - but sometimes the manual can be misleading, especially if the software being documented has evolved since it was written.&lt;br /&gt;&lt;h3&gt;Eclipse Help&lt;/h3&gt;If you're using Eclipse 3.3, the advice in the 2006 edition of &lt;a href="http://eclipsercp.org/book/"&gt;The Book&lt;/a&gt; about enabling Help in your Eclipse RCP applications is no longer quite accurate. Section 13.2 ("Getting the Help Plug-ins") tells you to install lots of things, while my experimentation has shown that all you need are the following plug-ins in your target platform and any launch configuration, plus their dependencies:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;org.eclipse.help.ui&lt;/li&gt;&lt;li&gt;org.eclipse.help.webapp&lt;/li&gt;&lt;/ul&gt;You will also find this information in the built-in help provided with Eclipse RCP Developer under Platform Plug-in Developer Guide -&gt; User assistance support -&gt; Help -&gt; Configuration/setup -&gt; Rich Client Platform (RCP) help. On discovering it, I felt a little like &lt;a href="http://answers.yahoo.com/question/index?qid=20080319203636AALeDby&amp;amp;show=7"&gt;Arthur Dent&lt;/a&gt; finding the planning application for the bypass through his house (look for the telling phrase "Beware of the Leopard")! Interestingly, the &lt;a href="http://help.eclipse.org/help33/topic/org.eclipse.platform.doc.isv/guide/ua_help_setup_rcp.htm"&gt;on-line version of the same help page&lt;/a&gt; disagrees - listing a lot of superfluous plug-ins - which confused me for quite a while.&lt;br /&gt;&lt;br /&gt;The dependencies, all of which you can copy from the plugins folder of your Eclipse installation to your target platform, are as follows:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;org.eclipse.help.base&lt;/li&gt;&lt;li&gt;org.apache.jasper&lt;/li&gt;&lt;li&gt;org.apache.lucene&lt;/li&gt;&lt;li&gt;org.apache.lucene.analysis&lt;/li&gt;&lt;li&gt;org.eclipse.equinox.http.jetty&lt;/li&gt;&lt;li&gt;org.eclipse.equinox.http.registry&lt;/li&gt;&lt;li&gt;org.eclipse.equinox.http.servlet&lt;/li&gt;&lt;li&gt;org.eclipse.equinox.jsp.jasper&lt;/li&gt;&lt;li&gt;org.eclipse.equinox.jsp.jasper.registry&lt;/li&gt;&lt;li&gt;org.eclipse.osgi.services&lt;/li&gt;&lt;li&gt;javax.servlet&lt;/li&gt;&lt;li&gt;javax.servlet.jsp&lt;/li&gt;&lt;li&gt;org.mortbay.jetty&lt;/li&gt;&lt;li&gt;org.apache.commons.logging&lt;/li&gt;&lt;li&gt;org.apache.commons.el&lt;/li&gt;&lt;/ul&gt;Also, to use Eclipse Help successfully under Windows (and that includes your own help for exported / launched applications), you have to have your Internet Explorer preferences set up to use no proxy server when accessing localhost / 127.0.0.1. One way to do this in Internet Explorer's Tools -&gt; Internet Options -&gt; Connections -&gt; LAN Settings is to turn off all three main check boxes. You could also try setting the "auto detect settings" checkbox &lt;b&gt;or&lt;/b&gt; the manual proxy server configuration (provided you also check the "bypass proxy server for local addresses" checkbox).&lt;br /&gt;&lt;h3&gt;Editing and Debugging&lt;/h3&gt;For some things, Eclipse needs source plug-ins to be present in the &lt;span style="font-style:italic;"&gt;target platform&lt;/span&gt; location, not just in the installation location.I have not yet established all the circumstances under which this may be the case, but I have found that if you are trying to use the special-purpose editor to work on a plugin.xml file, unless the source plug-ins are present in the target platform location, when you right-click on an extension point in the Extensions tab you won't see the correct extension types in the context menu (just "Generic").&lt;br /&gt;&lt;br /&gt;To support the most common types of UI extension, such as menu entries, copy the source plug-ins for org.eclipse.platform and org.eclipse.rcp from your Eclipse plugins folder into the target platform (hint: they are folders!). It is not even necessary to select them when specifying the target platform in Eclipse Preferences, but does no harm.&lt;br /&gt;&lt;h3&gt;Source organisation&lt;/h3&gt;It turns out that the line of least resistance is to separate your plug-ins and features into two groups:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;All the stuff you have access to in source form directly from its repository&lt;/li&gt;&lt;li&gt;Everything else - basically the Eclipse and third-party stuff&lt;/li&gt;&lt;/ul&gt;The second category forms your Eclipse RCP target platform, which should be a minimal Eclipse RCP installation plus all the features and plug-ins and their dependencies that you need in your application, plus source plug-ins where available. I created a target platform initially by downloading the &lt;a href="http://download.eclipse.org/eclipse/downloads/drops/R-3.3.1.1-200710231652/index.php#RCPRuntime"&gt;RCP Runtime Platform&lt;/a&gt; plus &lt;a href="http://download.eclipse.org/eclipse/downloads/drops/R-3.3.1.1-200710231652/index.php#RCPSDK"&gt;Delta Pack&lt;/a&gt; (version 3.3.1.1, which matches the version of Eclipse RCP Developer I was using), but then deleted a lot of things that were not relevant to my intended deployment architecture before adding the plug-ins and features I really needed (see above).&lt;br /&gt;&lt;br /&gt;For the first category, I recommend setting up your source folder structure to match the output in the build directory.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;product root&lt;/li&gt;&lt;ul&gt;&lt;li&gt;features&lt;/li&gt;&lt;ul&gt;&lt;li&gt;a.b.c.d.feature&lt;/li&gt;&lt;li&gt;etc.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;plugins&lt;/li&gt;&lt;ul&gt;&lt;li&gt;a.b.c.d&lt;/li&gt;&lt;li&gt;a.b.c.d.product&lt;/li&gt;&lt;li&gt;a.b.c.d.update-site&lt;br /&gt;&lt;/li&gt;&lt;li&gt;etc.&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;/ul&gt;It helps if you append "feature", "product" or "update-site" as the last component of the folder name, as appropriate, where a folder contains something other than a plug-in. Once each of these has been turned into an Eclipse project in your workspace, they will simply appear as a linear alphabetically ordered list in the package explorer, so this helps you to navigate.&lt;br /&gt;&lt;br /&gt;Ignore the features supplied with the Eclipse SDK, RCP Runtime and Delta Pack. Instead, define your own features to include just the plug-ins on which your application depends. It helps to factorise this into a half-dozen features that collect Eclipse plug-ins for various capabilities - e.g. the feature &lt;span style="font-weight:bold;"&gt;com.example.myproject.help.feature&lt;/span&gt; could be used to list all the plug-ins shown above that are needed to provide application help. Then if you want to include help with an application, all it has to do is list this feature in its application feature.xml as an included feature (of course you still have to write the help texts and create a help plug-in to contain them!).&lt;br /&gt;&lt;h3&gt;Version numbering&lt;/h3&gt;In product.xml and feature.xml files, it is a good idea to set the version numbers of included plug-ins and features to 0.0.0 (or a range, where applicable) to ensure that the latest version is always used during the build - the exported feature.xml files will end up containing the resolved version numbers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-5742813924307706624?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/5742813924307706624/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=5742813924307706624' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/5742813924307706624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/5742813924307706624'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/04/taking-pain-out-of-eclipse-rcp-builds.html' title='Taking the pain out of Eclipse RCP builds and exports'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-7067340540181312205</id><published>2008-03-15T16:12:00.000Z</published><updated>2008-03-15T09:12:27.240Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='ID cards'/><category scheme='http://www.blogger.com/atom/ns#' term='Big Brother'/><category scheme='http://www.blogger.com/atom/ns#' term='national identity register'/><category scheme='http://www.blogger.com/atom/ns#' term='privacy'/><category scheme='http://www.blogger.com/atom/ns#' term='no2id'/><title type='text'>BCS survey underlines laxity of Government data protection</title><content type='html'>As if more evidence were needed for the undesirability of a Government-run national identity register, &lt;a href="http://www.channel4.com/news/articles/politics/domestic_politics/government+lax+data+protection/1784947"&gt;Channel 4 News &lt;/a&gt;reported last night that a &lt;a href="http://www.bcs.org/server.php?show=nav.8082"&gt;British Computer Society&lt;/a&gt; survey had demonstrated a total absence of data accuracy audits or data correction budgets in 14 out of 14 UK Government departments.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-7067340540181312205?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/7067340540181312205/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=7067340540181312205' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/7067340540181312205'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/7067340540181312205'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/03/bcs-survey-underlines-laxity-of.html' title='BCS survey underlines laxity of Government data protection'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-614476611602277775</id><published>2008-03-10T18:12:00.000Z</published><updated>2008-03-10T11:17:08.805Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='ID cards'/><category scheme='http://www.blogger.com/atom/ns#' term='national identity register'/><category scheme='http://www.blogger.com/atom/ns#' term='privacy'/><title type='text'>Other models for identity registration</title><content type='html'>A story appeared on &lt;a href="http://yro.slashdot.org/article.pl?sid=08/03/08/2119211" target="_blank"&gt;Slashdot&lt;/a&gt; today comparing the UK and US identity database schemes with the Jukinet system that's been quietly running in Japan since 1992. Some of the responses are quite insightful and informative. People describe systems that exist in Bulgaria, Japan, Sweden, Norway and other places, each of which have some things to recommend them.&lt;br /&gt;&lt;br /&gt;For me, I think the main lesson is that yes, my personal data is already held in many different databases, both of government agencies such as the tax authorities and of private companies such as my credit card issuer. However, data protection legislation exists explicitly to prevent anyone, government or private, misusing this data by combining disparate databases to build a "profile" of me as an individual and to use that to my advantage or disadvantage. I fundamentally object to paying a huge amount of money so that this government can ride roughshod over those rights of the citizen. It isn't so much a question of privacy, more of protecting the individual against the might of the state.&lt;br /&gt;&lt;br /&gt;I quite like the idea of an identity service as something that people can subscribe to if they wish - much like the trust providers used in a &lt;a href="http://en.wikipedia.org/wiki/Public_key_infrastructure" target="_blank"&gt;Public Key Infrastructure&lt;/a&gt; (PKI). There should be a free market in personal authentication, just as there is on the Internet. This would drive down prices and encourage the development of value-added services.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-614476611602277775?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/614476611602277775/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=614476611602277775' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/614476611602277775'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/614476611602277775'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/03/other-models-for-identity-registration.html' title='Other models for identity registration'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-6038639208457406569</id><published>2008-03-07T17:20:00.000Z</published><updated>2008-03-07T09:22:00.107Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='ID cards'/><category scheme='http://www.blogger.com/atom/ns#' term='Big Brother'/><category scheme='http://www.blogger.com/atom/ns#' term='national identity register'/><category scheme='http://www.blogger.com/atom/ns#' term='no2id'/><title type='text'>Latest ID Register scam</title><content type='html'>In a desperate bid to ram through its controversial plans for a national identity register and the associated ID cards, the &lt;a href="http://www.guardian.co.uk/politics/2008/mar/07/idcards.privacy"&gt;British government has announced&lt;/a&gt; yet another defenceless section of society to be targeted: students.&lt;br /&gt;&lt;br /&gt;Not content with making university students pay over the odds for what are frequently sub-standard educational opportunities, the government now plans to "encourage" them to supply personal details including biometric data "voluntarily" in order to "help" them access educational services. Home Secretary Jacqui Smith claims that "young people who register for an ID card will find it easier to enrol on a course, apply for a student loan or open a bank account". The implication is that if they do &lt;strong&gt;not&lt;/strong&gt; agree to register, they will find it hard or impossible to enrol on a course, get a student loan or open a bank account.&lt;br /&gt;&lt;br /&gt;If that doesn't amount to coercion, I don't know what does. As a parent of two students currently at university, I feel very strongly about this. This is very reminiscent of the kind of vindictive tactics employed by the morally bankrupt East German government in the communist era. Moreover, the government expects to add me (an EU national resident and working in the UK) to its database automatically in a few years time "unless I opt out", which I certainly &lt;a href="http://www.pledgebank.com/refuse2comply"&gt;intend to do&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;A series of high-profile security breaches recently proved that &lt;a href="http://www.theregister.co.uk/2008/01/02/data_breaches_skyrocket/"&gt;governments generally&lt;/a&gt;, and &lt;a href="http://news.bbc.co.uk/2/hi/uk_news/politics/7147715.stm"&gt;this one in particular&lt;/a&gt;, cannot be trusted to handle personal information securely or to refrain from using it as a means of coercion. The sausage-slicing approach it has adopted for introducing the scheme is evidence that it knows it faces a massive revolt if it were to apply the same rules to the whole population in one go. By bringing in the scheme in this sneaky, insinuating way, the government makes me more convinced than ever that its motivation for the identity register is anything but the publicly stated one of making us "confident that other people are who they say they are" - security experts have already shown that an ID card of the current design will be relatively easy to fake, so that pretext doesn't persuade me at all.&lt;br /&gt;&lt;br /&gt;I don't normally subscribe to conspiracy theories but what else can you believe in the face of this government's announcements and actions?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-6038639208457406569?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/6038639208457406569/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=6038639208457406569' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/6038639208457406569'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/6038639208457406569'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/03/latest-id-register-scam.html' title='Latest ID Register scam'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-4737519383063309460</id><published>2008-03-06T19:23:00.000Z</published><updated>2008-03-06T11:22:26.205Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='eclipse pde'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse rcp'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><title type='text'>More on the Maven POM for PDE headless builds</title><content type='html'>It turns out that you can override almost any property in the build.properties file using an equivalent plugin configuration item within the buildProperties section.&lt;br /&gt;&lt;br /&gt;Moreover, by observing certain conventions the job is made much easier. One of these is that the PDE build takes place within a "build directory" that contains subdirectories named "features" and "plugins", and that the product's project directory (where pom.xml resides) is one of the subdirectories of "plugins". Therefore, in the Maven POM, it would be logical to define buildDirectory as "../..". Here's a possible approach:&lt;pre&gt;  &amp;lt;build&amp;gt;&lt;br /&gt;    &amp;lt;plugins&amp;gt;&lt;br /&gt;      &amp;lt;plugin&amp;gt;&lt;br /&gt;        &amp;lt;groupId&amp;gt;org.codehaus.mojo&amp;lt;/groupId&amp;gt;&lt;br /&gt;        &amp;lt;artifactId&amp;gt;pde-maven-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;        &amp;lt;version&amp;gt;1.0-alpha-2-SNAPSHOT&amp;lt;/version&amp;gt;&lt;br /&gt;        &amp;lt;extensions&amp;gt;true&amp;lt;/extensions&amp;gt;&lt;br /&gt;        &amp;lt;!-- Custom lifecycle configuration --&amp;gt;&lt;br /&gt;        &amp;lt;configuration&amp;gt;&lt;br /&gt;          &amp;lt;eclipseInstall&amp;gt;${env.M2_HOME}/../eclipse&amp;lt;/eclipseInstall&amp;gt;&lt;br /&gt;          &amp;lt;pdeProductFilename&amp;gt;prototyp.product&amp;lt;/pdeProductFilename&amp;gt;&lt;br /&gt;          &amp;lt;pdeBuildVersion&amp;gt;3.3.2.R331_v20071019&amp;lt;/pdeBuildVersion&amp;gt;&lt;br /&gt;          &amp;lt;buildProperties&amp;gt;&lt;br /&gt;             &amp;lt;base&amp;gt;${maven.work.dir}&amp;lt;/base&amp;gt;&lt;br /&gt;             &amp;lt;baseLocation&amp;gt;${maven.work.dir}/eclipse&amp;lt;/baseLocation&amp;gt;&lt;br /&gt;             &amp;lt;buildDirectory&amp;gt;${basedir}/../..&amp;lt;/buildDirectory&amp;gt;&lt;br /&gt;          &amp;lt;/buildProperties&amp;gt;&lt;br /&gt;        &amp;lt;/configuration&amp;gt;&lt;br /&gt;        &amp;lt;!-- Also bind to mvn clean --&amp;gt;&lt;br /&gt;        &amp;lt;executions&amp;gt;&lt;br /&gt;          &amp;lt;execution&amp;gt;&lt;br /&gt;            &amp;lt;id&amp;gt;clean-pde&amp;lt;/id&amp;gt;&lt;br /&gt;            &amp;lt;phase&amp;gt;clean&amp;lt;/phase&amp;gt;&lt;br /&gt;            &amp;lt;goals&amp;gt;&lt;br /&gt;              &amp;lt;goal&amp;gt;clean&amp;lt;/goal&amp;gt;&lt;br /&gt;            &amp;lt;/goals&amp;gt;&lt;br /&gt;          &amp;lt;/execution&amp;gt;&lt;br /&gt;        &amp;lt;/executions&amp;gt;&lt;br /&gt;      &amp;lt;/plugin&amp;gt;&lt;br /&gt;    &amp;lt;/plugins&amp;gt;&lt;br /&gt;  &amp;lt;/build&amp;gt;&lt;/pre&gt;Please note: we use a convention that the Maven installation is alongside the Eclipse IDE installation, hence the definition of eclipseInstall above. We also define the maven.work.dir property in the settings.xml file - this is where all the stuff goes that Maven needs, e.g. the local repository and the Eclipse PDE target platform.&lt;br /&gt;&lt;br /&gt;Currently I am working on a Maven plugin that will assemble the Eclipse PDE target platform automatically from project dependencies. I'll document this here once it's working.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-4737519383063309460?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/4737519383063309460/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=4737519383063309460' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/4737519383063309460'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/4737519383063309460'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/03/more-on-maven-pom-for-pde-headless.html' title='More on the Maven POM for PDE headless builds'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-9191366540730279337</id><published>2008-03-02T06:30:00.000Z</published><updated>2008-03-01T22:31:15.441Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='ITIL'/><category scheme='http://www.blogger.com/atom/ns#' term='SOA'/><category scheme='http://www.blogger.com/atom/ns#' term='BPTM'/><category scheme='http://www.blogger.com/atom/ns#' term='BT'/><title type='text'>Business Process Transaction Monitoring (BPTM)</title><content type='html'>I went along to a &lt;a href="http://www.bcs.org/server.php?show=ConWebDoc.17065"&gt;meeting of the BCS Kingston &amp; Croydon branch&lt;/a&gt; last Tuesday, at which a group of people from BT's Design group, who specialise in Systems and Application Monitoring and Management tools, revealed some astonishing achievements in a very low-key way, as if they had no idea how important they were.&lt;br /&gt;&lt;br /&gt;These people have distilled their dozens of years of experience of managing increasingly complex distributed systems with few staff and fewer tools into a powerful yet spare vocabulary (or ontology, to use a fancy term) that efficiently describes the universe of discourse. It includes such concepts as server, virtual machine, date, time, business process, transaction, event-type and (very important) end-to-end correlation key, which precisely locates a reported event in a specific application component. All this, logically enough, is aligned with the &lt;a href="http://en.wikipedia.org/wiki/ITIL_v3"&gt;ITIL&lt;/a&gt; standard for &lt;a href="http://www.bcs.org/server.php?show=ConWebDoc.8080"&gt;service delivery&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;But not only that, they've defined binary, textual and graphical representations of log entries or event notifications that capture all this information, and a set of libraries that implement all of this and are accessed via a very simple API, which has been implemented by a standard code library (I understand that a Java implementation is available, but there may be support for other languages too). Not least, there is a defined process for integrating an application into the service monitoring and management framework.&lt;br /&gt;&lt;br /&gt;Most applications already generate copious log information, and most commercial monitoring tools work by scanning the log files for interesting events. You have to configure patterns that allow the monitoring software to recognise different events. As a result, all large-scale monitoring infrastructures are permanently out of date with respect to the log formats and events generated by the applications, which are continually evolving. Moreover, the sheer volumes of log information generated mean that monitoring products that take this approach tend to be overwhelmed by the deluge of data and can find it difficult to react in a timely manner to real problem situations when they arise.&lt;br /&gt;&lt;br /&gt;BT's BPTM takes a different approach: the application is "instrumented" by wrapping existing calls to the system logging facility, when it's much easier to identify the meaning of the logged information in terms of the underlying data model and to add any missing properties (such as system identifier, timestamp and e2e correlation key). As a result, team boss Ian Johnston claims that an average application can be instrumented in one day (preceded by a one-day workshop to identify the requirements of managing that application, and followed by another day to roll out and test the instrumented version of the code).&lt;br /&gt;&lt;br /&gt;The BPTM library takes a "reporting by exception" approach to cut down on the amount of communication required. For example, events that are expected and that duly occur are merely logged locally by the application. This measure alone reduces the management data traffic by a factor of 20:1 on average. Then there are event correlation rules that can recognise typical failure scenarios and offer scripted diagnostic and remediation advice to support staff, many of whom are offshore.&lt;br /&gt;&lt;br /&gt;By using this combination of approaches, the design group has already equipped over 80 separate applications in the "BT Matrix" or Service Oriented Architecture to be centrally monitored and managed. Newly instrumented applications are auto-discovered by the BPTM infrastructure - they simply hook themselves into the reporting network and pop up on the monitoring console (which is of course a rich Internet application).&lt;br /&gt;&lt;br /&gt;Operators are alerted to emergency situations, such as service bottlenecks, via a variety of mechanisms. The primary user interface is a mimic diagram, which shows the flow of messages that make up an end-to-end business transaction through a series of components. The user can drill in to see both more detail and historical trend information, so that e.g. new server capacity can be brought on-stream before a bottleneck becomes critical.&lt;br /&gt;&lt;br /&gt;It's obviously in BT's interest to publicise the BPTM standard so that more suppliers will start using it and building it into their products from the outset. But I don't think that Ian and his team are going about this in the right way yet. To build up momentum, it is not enough to hold occasional talks to BCS branches, where you reach at most 20 interested individuals at a time. You need to convince the solution architects and other decision makers that this is the right way to go. The first thing to do is to publish the standard, and simultaneously or not long afterwards, make the libraries that implement it Open Source. This should create a community of interest across the industry. After all, large service-oriented architectures are becoming increasingly common, in all market sectors, not just in telecoms, so the management headache is shared by all projects. Then some judiciously targeted white papers and articles should appear in the appropriate journals, and the trade press needs to be made aware.&lt;br /&gt;&lt;br /&gt;If publicised in the right way, I can't see how this technology can fail to make waves.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-9191366540730279337?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/9191366540730279337/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=9191366540730279337' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/9191366540730279337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/9191366540730279337'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/03/business-process-transaction-monitoring.html' title='Business Process Transaction Monitoring (BPTM)'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-7839414873139308980</id><published>2008-03-02T05:30:00.000Z</published><updated>2008-03-01T21:28:38.146Z</updated><title type='text'>A British company providing first-class products</title><content type='html'>I've been very happy with my &lt;a href="http://www.dnuk.com/homepage.php"&gt;DNUK&lt;/a&gt; Linux server, which I purchased in September 2001 to provide filing services, web hosting etc. to the whole family. It has been doing duty in the cupboard under the stairs day in, day out without complaint. With the exception of some disk errors that cropped up soon after I bought the machine, and which DNUK sorted out for me very satisfactorily very quickly under the warranty, yesterday was the first time ever it went wrong.&lt;br /&gt;&lt;br /&gt;The power supply failed, basically. I managed to find a repair man locally who was able to fit a replacement in about 30 minutes. The old one had some kind of loose bits rattling around in it - probably glass from a blown fuse. Now that a new PSU has been fitted, it's back to work as usual. I fully expect to get another four years or more of use out of it.&lt;br /&gt;&lt;br /&gt;The repair man was very complimentary about the build quality of the machine and the tank-like solidity of the chassis. I too was impressed, but then I am not really a judge of these things. All I remember was the pleasure of dealing with a company that was small enough to treat its customers like real people, yet had all the snazzy web-based product selection and customisation capabilities you would expect of a major supplier. And it was excellent value for money, too.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-7839414873139308980?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/7839414873139308980/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=7839414873139308980' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/7839414873139308980'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/7839414873139308980'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/03/british-company-providing-first-class.html' title='A British company providing first-class products'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-8614307057678512403</id><published>2008-02-28T23:16:00.000Z</published><updated>2008-02-28T15:18:10.347Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='sales technique'/><category scheme='http://www.blogger.com/atom/ns#' term='droplifting'/><category scheme='http://www.blogger.com/atom/ns#' term='publishing'/><title type='text'>What is "droplifting"?</title><content type='html'>Read the highly entertaining story of how a late friend's &lt;a href="http://www.winston-11811.com/Droplift.htm"&gt;unpublished novel got to be sold&lt;/a&gt; in a high-street chain of bookstores.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-8614307057678512403?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/8614307057678512403/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=8614307057678512403' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/8614307057678512403'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/8614307057678512403'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/02/what-is-droplifting.html' title='What is &quot;droplifting&quot;?'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-4361619703131319239</id><published>2008-02-27T01:16:00.000Z</published><updated>2008-02-26T16:20:41.846Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='london mayor'/><category scheme='http://www.blogger.com/atom/ns#' term='national identity register'/><category scheme='http://www.blogger.com/atom/ns#' term='no2id'/><title type='text'>London Mayoral Candidates and the National Identity Register</title><content type='html'>In late January or early February, I canvassed the candidates of major parties for the May 2008 election of the London Mayor, asking them to come out publicly with a statement that they would not co-operate with any national identity register (ID Cards) scheme if elected. I wrote:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;I would like to know where the [your party here] candidate in the 2008 London Mayoral election stands regarding the national identity register. Will (s)he resist pressure to withhold services from people who do not have an identity card? The government intends to make the "voluntary" scheme effectively compulsory by making it impossible to get a new passport, driving licence etc. without an ID card. If London refuses to play the game, it will be doing its citizens a great service.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The Green party candidate, Siân Berry, responded with alacrity, saying that she had already signed the No2ID pledge in 2004 and was well known for her stand against the scheme (see &lt;a href="http://camden.greenparty.org.uk/news/newsidcards.html"&gt;http://camden.greenparty.org.uk/news/newsidcards.html&lt;/a&gt; and other sites). She goes on:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;"I would not allow any services for Londoners to depend on the scheme, and would urge Londoners to resist the ID system individually as well.&lt;br /&gt;&lt;br /&gt;You may also be interested in our Census Alert campaign to stop Lockheed Martin being given the contract to run the UK Census in 2011. This is a campaign I set up last year after finding out they were on the final shortlist, and there are now politicians from a wide range of parties supporting the cause. See &lt;a href="http://www.censusalert.org.uk/"&gt;www.censusalert.org.uk&lt;/a&gt;  for more details."&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So that's a result then.&lt;br /&gt;&lt;br /&gt;The Liberal Democrat party's candidate, Brian Paddick, sent me a personal letter by snail mail, which arrived today, in which he states that he is totally opposed to the ID cards. From a former police officer, this comes as a nice surprise (except to those who have been following his campaign closely) and is in line with the national party's line as represented by Nick Clegg (see &lt;a href="http://www.youtube.com/user/LibDem"&gt;http://www.youtube.com/user/LibDem&lt;/a&gt;). Nick Clegg has publicly pledged to refuse to be registered, even if it means being taken to court.&lt;br /&gt;&lt;br /&gt;Sadly, Brian Paddick did not go so far as to pledge that London would refuse to participate in any coercion by the Government to force people to join the scheme.&lt;br /&gt;&lt;br /&gt;I didn't get any response from either the Conservative or (New?) Labour candidates or their representatives.&lt;br /&gt;&lt;br /&gt;However, Conservative candidate Boris Johnson is on record as opposing the scheme - see &lt;a href="http://www.youtube.com/watch?v=kZAAzSzleWk"&gt;http://www.youtube.com/watch?v=kZAAzSzleWk&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Only Labour candidate Ken Livingstone is really letting the side down. According to an Andrew Marr interview mentioned on the NO2ID site, he actually supports the ID card scheme - see &lt;a href="http://boardreader.com/t/Articles_Publications_150279/Andrew_Marr_Show_Ken_Livingstone_Intervi_19360.html"&gt;http://boardreader.com/t/Articles_Publications_150279/Andrew_Marr_Show_Ken_Livingstone_Intervi_19360.html&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I hope this helps you when it comes to making the decision in May!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-4361619703131319239?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/4361619703131319239/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=4361619703131319239' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/4361619703131319239'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/4361619703131319239'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/02/london-mayoral-candidates-and-national.html' title='London Mayoral Candidates and the National Identity Register'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-3362413157831937216</id><published>2008-02-22T18:43:00.000Z</published><updated>2008-02-22T10:43:38.706Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='eclipse pde'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse rcp'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><title type='text'>Further background information about Maven PDE builds</title><content type='html'>I was asked in a comment to publish the settings.xml file for my Maven installation, because the correspondent was not able to build the example project successfully.&lt;br /&gt;&lt;br /&gt;Our project makes use of a local Maven proxy server to mirror the combined contents of the Maven Central repository, various snapshot repositories and the project's own built artifacts. In the Maven &lt;tt&gt;conf&lt;/tt&gt; directory, we have therefore installed the following &lt;tt&gt;settings.xml&lt;/tt&gt; file, which reflects this arrangement:&lt;br /&gt;&lt;pre&gt;&amp;lt;settings&amp;gt;&lt;br /&gt;  &amp;lt;servers&amp;gt;&lt;br /&gt;    &amp;lt;server&amp;gt;&lt;br /&gt;      &amp;lt;id&amp;gt;project-repo&amp;lt;/id&amp;gt;&lt;br /&gt;      &amp;lt;username&amp;gt;...&amp;lt;/username&amp;gt;&lt;br /&gt;      &amp;lt;password&amp;gt;...&amp;lt;/password&amp;gt;&lt;br /&gt;    &amp;lt;/server&amp;gt;&lt;br /&gt;  &amp;lt;/servers&amp;gt;&lt;br /&gt;  &amp;lt;profiles&amp;gt;&lt;br /&gt;    &amp;lt;profile&amp;gt;&lt;br /&gt;      &amp;lt;id&amp;gt;main-profile&amp;lt;/id&amp;gt;&lt;br /&gt;      &amp;lt;properties&amp;gt;&lt;br /&gt;        &amp;lt;!-- settings.localRepository is set by the USER settings.xml --&amp;gt;&lt;br /&gt;        &amp;lt;!-- Maven working directory --&amp;gt;&lt;br /&gt;        &amp;lt;maven.work.dir&amp;gt;${settings.localRepository}/..&amp;lt;/maven.work.dir&amp;gt;&lt;br /&gt;        &amp;lt;!-- Clover working directory: clover license is expected in ${clover.work.dir}/license --&amp;gt;&lt;br /&gt;        &amp;lt;clover.work.dir&amp;gt;${maven.work.dir}/clover-work&amp;lt;/clover.work.dir&amp;gt;&lt;br /&gt;        &amp;lt;!-- Additional plugin provider path for Eclipse target platform --&amp;gt;&lt;br /&gt;        &amp;lt;plugin.target.dir&amp;gt;${maven.work.dir}/plugin_target_dir&amp;lt;/plugin.target.dir&amp;gt;&lt;br /&gt;        &amp;lt;!-- project sites will be deployed to ${site.dir} with mvn site:deploy --&amp;gt;&lt;br /&gt;        &amp;lt;site.dir&amp;gt;${maven.work.dir}/maven_site&amp;lt;/site.dir&amp;gt;&lt;br /&gt;      &amp;lt;/properties&amp;gt;&lt;br /&gt;      &amp;lt;repositories&amp;gt;&lt;br /&gt;        &amp;lt;repository&amp;gt;&lt;br /&gt;          &amp;lt;id&amp;gt;central&amp;lt;/id&amp;gt;&lt;br /&gt;          &amp;lt;name&amp;gt;Internal Mirror of Central Repositories&amp;lt;/name&amp;gt;&lt;br /&gt;          &amp;lt;url&amp;gt;http://....:9999/repository/&amp;lt;/url&amp;gt;&lt;br /&gt;        &amp;lt;/repository&amp;gt;&lt;br /&gt;      &amp;lt;/repositories&amp;gt;&lt;br /&gt;      &amp;lt;pluginRepositories&amp;gt;&lt;br /&gt;        &amp;lt;pluginRepository&amp;gt;&lt;br /&gt;          &amp;lt;id&amp;gt;central&amp;lt;/id&amp;gt;&lt;br /&gt;          &amp;lt;name&amp;gt;Internal Mirror of Central Plugins Repository&amp;lt;/name&amp;gt;&lt;br /&gt;          &amp;lt;url&amp;gt;http://....:9999/repository/&amp;lt;/url&amp;gt;&lt;br /&gt;        &amp;lt;/pluginRepository&amp;gt;&lt;br /&gt;      &amp;lt;/pluginRepositories&amp;gt;  &lt;br /&gt;    &amp;lt;/profile&amp;gt;&lt;br /&gt;  &amp;lt;/profiles&amp;gt;&lt;br /&gt;  &amp;lt;activeProfiles&amp;gt;&lt;br /&gt;    &amp;lt;activeProfile&amp;gt;main-profile&amp;lt;/activeProfile&amp;gt; &lt;br /&gt;  &amp;lt;/activeProfiles&amp;gt;&lt;br /&gt;&amp;lt;/settings&amp;gt;&lt;/pre&gt;&lt;br /&gt;In the &lt;tt&gt;.m2&lt;/tt&gt; directory under the user's home directory, we install a minimal &lt;tt&gt;settings.xml&lt;/tt&gt;, which simply indicates where to find the local Maven repo on your hard disk. However, I have customised my copy so that I can do builds when not connected to the company network but with access to the Internet. This shows you where you can obtain things like the PDE Maven plugin snapshot.&lt;br /&gt;&lt;pre&gt;&amp;lt;settings&amp;gt;&lt;br /&gt;  &amp;lt;localRepository&amp;gt;C:\data\...\maven_repo&amp;lt;/localRepository&amp;gt;&lt;br /&gt;  &amp;lt;profiles&amp;gt;&lt;br /&gt;    &amp;lt;profile&amp;gt;&lt;br /&gt;      &amp;lt;id&amp;gt;publicRepos&amp;lt;/id&amp;gt;&lt;br /&gt;      &amp;lt;activation&amp;gt;&lt;br /&gt;        &amp;lt;property&amp;gt;&lt;br /&gt;     &amp;lt;name&amp;gt;searchPublicRepos&amp;lt;/name&amp;gt;&lt;br /&gt;     &amp;lt;value&amp;gt;true&amp;lt;/value&amp;gt;&lt;br /&gt;   &amp;lt;/property&amp;gt;&lt;br /&gt;      &amp;lt;/activation&amp;gt;&lt;br /&gt;      &amp;lt;repositories&amp;gt;&lt;br /&gt;        &amp;lt;repository&amp;gt;&lt;br /&gt;          &amp;lt;id&amp;gt;codehausSnapshots&amp;lt;/id&amp;gt;&lt;br /&gt;          &amp;lt;name&amp;gt;Codehaus Snapshots&amp;lt;/name&amp;gt;&lt;br /&gt;          &amp;lt;releases&amp;gt;&lt;br /&gt;            &amp;lt;enabled&amp;gt;false&amp;lt;/enabled&amp;gt;&lt;br /&gt;            &amp;lt;updatePolicy&amp;gt;always&amp;lt;/updatePolicy&amp;gt;&lt;br /&gt;            &amp;lt;checksumPolicy&amp;gt;warn&amp;lt;/checksumPolicy&amp;gt;&lt;br /&gt;          &amp;lt;/releases&amp;gt;&lt;br /&gt;          &amp;lt;snapshots&amp;gt;&lt;br /&gt;            &amp;lt;enabled&amp;gt;true&amp;lt;/enabled&amp;gt;&lt;br /&gt;            &amp;lt;updatePolicy&amp;gt;never&amp;lt;/updatePolicy&amp;gt;&lt;br /&gt;            &amp;lt;checksumPolicy&amp;gt;fail&amp;lt;/checksumPolicy&amp;gt;&lt;br /&gt;          &amp;lt;/snapshots&amp;gt;&lt;br /&gt;          &amp;lt;url&amp;gt;http://snapshots.maven.codehaus.org/maven2&amp;lt;/url&amp;gt;&lt;br /&gt;          &amp;lt;layout&amp;gt;default&amp;lt;/layout&amp;gt;&lt;br /&gt;        &amp;lt;/repository&amp;gt;&lt;br /&gt;        &amp;lt;repository&amp;gt;&lt;br /&gt;          &amp;lt;id&amp;gt;mavenCentral&amp;lt;/id&amp;gt;&lt;br /&gt;          &amp;lt;name&amp;gt;Maven Central&amp;lt;/name&amp;gt;&lt;br /&gt;          &amp;lt;releases&amp;gt;&lt;br /&gt;            &amp;lt;enabled&amp;gt;true&amp;lt;/enabled&amp;gt;&lt;br /&gt;            &amp;lt;updatePolicy&amp;gt;daily&amp;lt;/updatePolicy&amp;gt;&lt;br /&gt;            &amp;lt;checksumPolicy&amp;gt;warn&amp;lt;/checksumPolicy&amp;gt;&lt;br /&gt;          &amp;lt;/releases&amp;gt;&lt;br /&gt;          &amp;lt;snapshots&amp;gt;&lt;br /&gt;            &amp;lt;enabled&amp;gt;false&amp;lt;/enabled&amp;gt;&lt;br /&gt;            &amp;lt;updatePolicy&amp;gt;never&amp;lt;/updatePolicy&amp;gt;&lt;br /&gt;            &amp;lt;checksumPolicy&amp;gt;warn&amp;lt;/checksumPolicy&amp;gt;&lt;br /&gt;          &amp;lt;/snapshots&amp;gt;&lt;br /&gt;          &amp;lt;url&amp;gt;http://repo1.maven.org/maven2/&amp;lt;/url&amp;gt;&lt;br /&gt;          &amp;lt;layout&amp;gt;default&amp;lt;/layout&amp;gt;&lt;br /&gt;   &amp;lt;/repository&amp;gt;&lt;br /&gt;        &amp;lt;repository&amp;gt;&lt;br /&gt;          &amp;lt;id&amp;gt;mavenSnapshots&amp;lt;/id&amp;gt;&lt;br /&gt;          &amp;lt;name&amp;gt;Maven Snapshots&amp;lt;/name&amp;gt;&lt;br /&gt;          &amp;lt;releases&amp;gt;&lt;br /&gt;            &amp;lt;enabled&amp;gt;false&amp;lt;/enabled&amp;gt;&lt;br /&gt;            &amp;lt;updatePolicy&amp;gt;never&amp;lt;/updatePolicy&amp;gt;&lt;br /&gt;            &amp;lt;checksumPolicy&amp;gt;warn&amp;lt;/checksumPolicy&amp;gt;&lt;br /&gt;          &amp;lt;/releases&amp;gt;&lt;br /&gt;          &amp;lt;snapshots&amp;gt;&lt;br /&gt;            &amp;lt;enabled&amp;gt;true&amp;lt;/enabled&amp;gt;&lt;br /&gt;            &amp;lt;updatePolicy&amp;gt;daily&amp;lt;/updatePolicy&amp;gt;&lt;br /&gt;            &amp;lt;checksumPolicy&amp;gt;warn&amp;lt;/checksumPolicy&amp;gt;&lt;br /&gt;          &amp;lt;/snapshots&amp;gt;&lt;br /&gt;          &amp;lt;url&amp;gt;http://people.apache.org/repo/m2-snapshot-repository/&amp;lt;/url&amp;gt;&lt;br /&gt;          &amp;lt;layout&amp;gt;default&amp;lt;/layout&amp;gt;&lt;br /&gt;   &amp;lt;/repository&amp;gt;&lt;br /&gt;      &amp;lt;/repositories&amp;gt;&lt;br /&gt;      &amp;lt;pluginRepositories&amp;gt;&lt;br /&gt;        &amp;lt;pluginRepository&amp;gt;&lt;br /&gt;          &amp;lt;id&amp;gt;codehausSnapshots&amp;lt;/id&amp;gt;&lt;br /&gt;          &amp;lt;name&amp;gt;Codehaus Snapshots&amp;lt;/name&amp;gt;&lt;br /&gt;          &amp;lt;releases&amp;gt;&lt;br /&gt;            &amp;lt;enabled&amp;gt;false&amp;lt;/enabled&amp;gt;&lt;br /&gt;            &amp;lt;updatePolicy&amp;gt;always&amp;lt;/updatePolicy&amp;gt;&lt;br /&gt;            &amp;lt;checksumPolicy&amp;gt;warn&amp;lt;/checksumPolicy&amp;gt;&lt;br /&gt;          &amp;lt;/releases&amp;gt;&lt;br /&gt;          &amp;lt;snapshots&amp;gt;&lt;br /&gt;            &amp;lt;enabled&amp;gt;true&amp;lt;/enabled&amp;gt;&lt;br /&gt;            &amp;lt;updatePolicy&amp;gt;never&amp;lt;/updatePolicy&amp;gt;&lt;br /&gt;            &amp;lt;checksumPolicy&amp;gt;fail&amp;lt;/checksumPolicy&amp;gt;&lt;br /&gt;          &amp;lt;/snapshots&amp;gt;&lt;br /&gt;          &amp;lt;url&amp;gt;http://snapshots.maven.codehaus.org/maven2&amp;lt;/url&amp;gt;&lt;br /&gt;          &amp;lt;layout&amp;gt;default&amp;lt;/layout&amp;gt;&lt;br /&gt;        &amp;lt;/pluginRepository&amp;gt;&lt;br /&gt;        &amp;lt;pluginRepository&amp;gt;&lt;br /&gt;          &amp;lt;id&amp;gt;mavenCentral&amp;lt;/id&amp;gt;&lt;br /&gt;          &amp;lt;name&amp;gt;Maven Central&amp;lt;/name&amp;gt;&lt;br /&gt;          &amp;lt;releases&amp;gt;&lt;br /&gt;            &amp;lt;enabled&amp;gt;true&amp;lt;/enabled&amp;gt;&lt;br /&gt;            &amp;lt;updatePolicy&amp;gt;daily&amp;lt;/updatePolicy&amp;gt;&lt;br /&gt;            &amp;lt;checksumPolicy&amp;gt;warn&amp;lt;/checksumPolicy&amp;gt;&lt;br /&gt;          &amp;lt;/releases&amp;gt;&lt;br /&gt;          &amp;lt;snapshots&amp;gt;&lt;br /&gt;            &amp;lt;enabled&amp;gt;false&amp;lt;/enabled&amp;gt;&lt;br /&gt;            &amp;lt;updatePolicy&amp;gt;never&amp;lt;/updatePolicy&amp;gt;&lt;br /&gt;            &amp;lt;checksumPolicy&amp;gt;warn&amp;lt;/checksumPolicy&amp;gt;&lt;br /&gt;          &amp;lt;/snapshots&amp;gt;&lt;br /&gt;          &amp;lt;url&amp;gt;http://repo1.maven.org/maven2/&amp;lt;/url&amp;gt;&lt;br /&gt;          &amp;lt;layout&amp;gt;default&amp;lt;/layout&amp;gt;&lt;br /&gt;   &amp;lt;/pluginRepository&amp;gt;&lt;br /&gt;        &amp;lt;pluginRepository&amp;gt;&lt;br /&gt;          &amp;lt;id&amp;gt;mavenSnapshots&amp;lt;/id&amp;gt;&lt;br /&gt;          &amp;lt;name&amp;gt;Maven Snapshots&amp;lt;/name&amp;gt;&lt;br /&gt;          &amp;lt;releases&amp;gt;&lt;br /&gt;            &amp;lt;enabled&amp;gt;false&amp;lt;/enabled&amp;gt;&lt;br /&gt;            &amp;lt;updatePolicy&amp;gt;never&amp;lt;/updatePolicy&amp;gt;&lt;br /&gt;            &amp;lt;checksumPolicy&amp;gt;warn&amp;lt;/checksumPolicy&amp;gt;&lt;br /&gt;          &amp;lt;/releases&amp;gt;&lt;br /&gt;          &amp;lt;snapshots&amp;gt;&lt;br /&gt;            &amp;lt;enabled&amp;gt;true&amp;lt;/enabled&amp;gt;&lt;br /&gt;            &amp;lt;updatePolicy&amp;gt;daily&amp;lt;/updatePolicy&amp;gt;&lt;br /&gt;            &amp;lt;checksumPolicy&amp;gt;warn&amp;lt;/checksumPolicy&amp;gt;&lt;br /&gt;          &amp;lt;/snapshots&amp;gt;&lt;br /&gt;          &amp;lt;url&amp;gt;http://people.apache.org/repo/m2-snapshot-repository/&amp;lt;/url&amp;gt;&lt;br /&gt;          &amp;lt;layout&amp;gt;default&amp;lt;/layout&amp;gt;&lt;br /&gt;   &amp;lt;/pluginRepository&amp;gt;&lt;br /&gt;      &amp;lt;/pluginRepositories&amp;gt;&lt;br /&gt;    &amp;lt;/profile&amp;gt;&lt;br /&gt;  &amp;lt;/profiles&amp;gt;&lt;br /&gt;&amp;lt;/settings&amp;gt;&lt;/pre&gt;&lt;br /&gt;As I mentioned in passing in my original post, you also have to make sure that you (a) correct the version number of two dependencies in the pde-maven-plugin's POM, and (b) upload all the Eclipse plugins that the pde-maven-plugin needs to your local repository or to your project repository, using the &lt;tt&gt;eclipse:to-maven&lt;/tt&gt; goal.&lt;br /&gt;&lt;br /&gt;I have actually set up a Maven project to do upload Eclipse plugins repeatably and reliably in case we need to clean up and rebuild the project repository (e.g. after an upgrade of Eclipse). Here's the POM:&lt;br /&gt;&lt;pre&gt;&amp;lt;project xmlns=&amp;quot;http://maven.apache.org/POM/4.0.0&amp;quot;&lt;br /&gt;  xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;  xsi:schemaLocation=&amp;quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&amp;quot;&amp;gt;&lt;br /&gt;  &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;groupId&amp;gt;....&amp;lt;/groupId&amp;gt;&lt;br /&gt;  &amp;lt;artifactId&amp;gt;devclipse-to-maven&amp;lt;/artifactId&amp;gt;&lt;br /&gt;  &amp;lt;version&amp;gt;1.0-SNAPSHOT&amp;lt;/version&amp;gt;&lt;br /&gt;  &amp;lt;packaging&amp;gt;pom&amp;lt;/packaging&amp;gt;&lt;br /&gt;  &amp;lt;name&amp;gt;Eclipse plugins to Maven Artifacts converter&amp;lt;/name&amp;gt;&lt;br /&gt;  &amp;lt;url&amp;gt;....&amp;lt;/url&amp;gt;&lt;br /&gt;  &amp;lt;description&amp;gt;....&amp;lt;/description&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;!-- ******************************************************************&lt;br /&gt;    Inherit from project grandparent pom&lt;br /&gt;    ****************************************************************** --&amp;gt;&lt;br /&gt;  &amp;lt;parent&amp;gt;&lt;br /&gt;    &amp;lt;groupId&amp;gt;....&amp;lt;/groupId&amp;gt;&lt;br /&gt;    &amp;lt;artifactId&amp;gt;configuration&amp;lt;/artifactId&amp;gt;&lt;br /&gt;    &amp;lt;version&amp;gt;1.8&amp;lt;/version&amp;gt;&lt;br /&gt;  &amp;lt;/parent&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;!-- ******************************************************************&lt;br /&gt;    Environment Information&lt;br /&gt;    ****************************************************************** --&amp;gt;&lt;br /&gt;  &amp;lt;scm&amp;gt;&lt;br /&gt;    &amp;lt;connection&amp;gt;&lt;br /&gt;      scm:svn:http://..../devclipse_to_maven/&lt;br /&gt;    &amp;lt;/connection&amp;gt;&lt;br /&gt;    &amp;lt;developerConnection&amp;gt;&lt;br /&gt;      scm:svn:http://..../devclipse_to_maven/&lt;br /&gt;    &amp;lt;/developerConnection&amp;gt;&lt;br /&gt;    &amp;lt;tag&amp;gt;HEAD&amp;lt;/tag&amp;gt;&lt;br /&gt;    &amp;lt;url&amp;gt;&lt;br /&gt;      http://..../devclipse_to_maven/&lt;br /&gt;    &amp;lt;/url&amp;gt;&lt;br /&gt;  &amp;lt;/scm&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;!-- ******************************************************************&lt;br /&gt;    Build configuration&lt;br /&gt;    ****************************************************************** --&amp;gt;&lt;br /&gt;  &amp;lt;properties&amp;gt;&lt;br /&gt;    &amp;lt;eclipse.source.dir&amp;gt;${env.M2_HOME}/../eclipse&amp;lt;/eclipse.source.dir&amp;gt;&lt;br /&gt;    &amp;lt;eclipse.ext.dir&amp;gt;${env.M2_HOME}/../ext/eclipse&amp;lt;/eclipse.ext.dir&amp;gt;&lt;br /&gt;    &amp;lt;eclipse.usr.dir&amp;gt;${env.M2_HOME}/../usr/eclipse&amp;lt;/eclipse.usr.dir&amp;gt;&lt;br /&gt;    &amp;lt;eclipse.target.dir&amp;gt;${project.build.directory}/eclipse&amp;lt;/eclipse.target.dir&amp;gt;&lt;br /&gt;  &amp;lt;/properties&amp;gt;&lt;br /&gt;  &amp;lt;build&amp;gt;&lt;br /&gt;    &amp;lt;plugins&amp;gt;&lt;br /&gt;      &amp;lt;plugin&amp;gt;&lt;br /&gt;        &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;&lt;br /&gt;        &amp;lt;artifactId&amp;gt;maven-antrun-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;        &amp;lt;version&amp;gt;1.1&amp;lt;/version&amp;gt;&lt;br /&gt;        &amp;lt;executions&amp;gt;&lt;br /&gt;          &amp;lt;execution&amp;gt;&lt;br /&gt;            &amp;lt;id&amp;gt;copy-plugins-and-features&amp;lt;/id&amp;gt;&lt;br /&gt;            &amp;lt;phase&amp;gt;process-resources&amp;lt;/phase&amp;gt;&lt;br /&gt;            &amp;lt;goals&amp;gt;&lt;br /&gt;              &amp;lt;goal&amp;gt;run&amp;lt;/goal&amp;gt;&lt;br /&gt;            &amp;lt;/goals&amp;gt;&lt;br /&gt;            &amp;lt;configuration&amp;gt;&lt;br /&gt;              &amp;lt;tasks description=&amp;quot;Grab the features and plugins from&lt;br /&gt;               the Eclipse SDK that have been found empirically to&lt;br /&gt;               be required as part of the target platform. We will&lt;br /&gt;               upload them to the Maven repository in the next phase.&amp;quot;&amp;gt;&lt;br /&gt;                &amp;lt;mkdir dir=&amp;quot;${eclipse.target.dir}/plugins&amp;quot;/&amp;gt;&lt;br /&gt;                &amp;lt;copy todir=&amp;quot;${eclipse.target.dir}/plugins&amp;quot;&amp;gt;&lt;br /&gt;                  &amp;lt;fileset dir=&amp;quot;${eclipse.source.dir}/plugins&amp;quot;&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;com.ibm.icu_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.ant.core_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.compare_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.core.commands_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.core.contenttype_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.core.databinding_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.core.expressions_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.core.filebuffers_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.core.filesystem_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.core.jobs_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.core.net_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.core.resources_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.core.runtime.compatibility.auth_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.core.runtime_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.core.variables_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.debug.core_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.equinox.app_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.equinox.common_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.equinox.preferences_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.equinox.registry_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.help_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.jdt.core_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.jdt.debug_*/**/*&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.jdt.launching_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.jface.databinding_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.jface.text_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.jface_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.osgi_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.rcp.source.win32.win32.x86_*/**/*&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.swt.win32.win32.x86_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.swt_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.team.core_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.team.ui_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.text_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.ui_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.ui.console_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.ui.editors_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.ui.forms_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.ui.ide_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.ui.navigator_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.ui.navigator.resources_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.ui.views_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.ui.views.properties.tabbed_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.ui.workbench_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.ui.workbench.texteditor_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.update.configurator_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.update.core_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.eclipse.update.ui_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                  &amp;lt;/fileset&amp;gt;&lt;br /&gt;                &amp;lt;/copy&amp;gt;&lt;br /&gt;                &amp;lt;mkdir dir=&amp;quot;${eclipse.target.dir}/features&amp;quot;/&amp;gt;&lt;br /&gt;                &amp;lt;copy todir=&amp;quot;${eclipse.target.dir}/features&amp;quot;&amp;gt;&lt;br /&gt;                  &amp;lt;fileset dir=&amp;quot;${eclipse.source.dir}/features&amp;quot;&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;none_*&amp;quot;/&amp;gt;&lt;br /&gt;                  &amp;lt;/fileset&amp;gt;&lt;br /&gt;                &amp;lt;/copy&amp;gt;&lt;br /&gt;                &amp;lt;copy todir=&amp;quot;${eclipse.target.dir}/plugins&amp;quot;&lt;br /&gt;                  failonerror=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;                  &amp;lt;fileset dir=&amp;quot;${eclipse.ext.dir}/plugins&amp;quot;&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.polarion.team.svn.client.javahl.win32_*/**/*&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.polarion.team.svn*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;org.sf.easyexplore_*.jar&amp;quot;/&amp;gt;&lt;br /&gt;                  &amp;lt;/fileset&amp;gt;&lt;br /&gt;                &amp;lt;/copy&amp;gt;&lt;br /&gt;                &amp;lt;copy todir=&amp;quot;${eclipse.target.dir}/features&amp;quot;&lt;br /&gt;                  failonerror=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;                  &amp;lt;fileset dir=&amp;quot;${eclipse.ext.dir}/features&amp;quot;&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;none_*&amp;quot;/&amp;gt;&lt;br /&gt;                  &amp;lt;/fileset&amp;gt;&lt;br /&gt;                &amp;lt;/copy&amp;gt;&lt;br /&gt;                &amp;lt;copy todir=&amp;quot;${eclipse.target.dir}/plugins&amp;quot;&lt;br /&gt;                  failonerror=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;                  &amp;lt;fileset dir=&amp;quot;${eclipse.usr.dir}/plugins&amp;quot;&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;none_*&amp;quot;/&amp;gt;&lt;br /&gt;                  &amp;lt;/fileset&amp;gt;&lt;br /&gt;                &amp;lt;/copy&amp;gt;&lt;br /&gt;                &amp;lt;copy todir=&amp;quot;${eclipse.usr.dir}/features&amp;quot;&lt;br /&gt;                  failonerror=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;                  &amp;lt;fileset dir=&amp;quot;${eclipse.ext.dir}/features&amp;quot;&amp;gt;&lt;br /&gt;                    &amp;lt;include name=&amp;quot;none_*&amp;quot;/&amp;gt;&lt;br /&gt;                  &amp;lt;/fileset&amp;gt;&lt;br /&gt;                &amp;lt;/copy&amp;gt;&lt;br /&gt;              &amp;lt;/tasks&amp;gt;&lt;br /&gt;            &amp;lt;/configuration&amp;gt;&lt;br /&gt;          &amp;lt;/execution&amp;gt;&lt;br /&gt;        &amp;lt;/executions&amp;gt;&lt;br /&gt;      &amp;lt;/plugin&amp;gt;&lt;br /&gt;      &amp;lt;plugin&amp;gt;&lt;br /&gt;        &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;&lt;br /&gt;        &amp;lt;artifactId&amp;gt;maven-eclipse-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;        &amp;lt;version&amp;gt;2.4&amp;lt;/version&amp;gt;&lt;br /&gt;        &amp;lt;executions&amp;gt;&lt;br /&gt;          &amp;lt;execution&amp;gt;&lt;br /&gt;            &amp;lt;id&amp;gt;installation&amp;lt;/id&amp;gt;&lt;br /&gt;            &amp;lt;phase&amp;gt;install&amp;lt;/phase&amp;gt;&lt;br /&gt;            &amp;lt;configuration&amp;gt;&lt;br /&gt;              &amp;lt;eclipseDir&amp;gt;${eclipse.target.dir}&amp;lt;/eclipseDir&amp;gt;&lt;br /&gt;            &amp;lt;/configuration&amp;gt;&lt;br /&gt;            &amp;lt;goals&amp;gt;&lt;br /&gt;              &amp;lt;goal&amp;gt;to-maven&amp;lt;/goal&amp;gt;&lt;br /&gt;            &amp;lt;/goals&amp;gt;&lt;br /&gt;          &amp;lt;/execution&amp;gt;&lt;br /&gt;          &amp;lt;execution&amp;gt;&lt;br /&gt;            &amp;lt;id&amp;gt;deployment&amp;lt;/id&amp;gt;&lt;br /&gt;            &amp;lt;phase&amp;gt;deploy&amp;lt;/phase&amp;gt;&lt;br /&gt;            &amp;lt;configuration&amp;gt;&lt;br /&gt;              &amp;lt;eclipseDir&amp;gt;${eclipse.target.dir}&amp;lt;/eclipseDir&amp;gt;&lt;br /&gt;              &amp;lt;deployTo&amp;gt;${distributionManagement.repository.id}::default::${distributionManagement.repository.url}&amp;lt;/deployTo&amp;gt;&lt;br /&gt;            &amp;lt;/configuration&amp;gt;&lt;br /&gt;            &amp;lt;goals&amp;gt;&lt;br /&gt;              &amp;lt;goal&amp;gt;to-maven&amp;lt;/goal&amp;gt;&lt;br /&gt;            &amp;lt;/goals&amp;gt;&lt;br /&gt;          &amp;lt;/execution&amp;gt;&lt;br /&gt;        &amp;lt;/executions&amp;gt;&lt;br /&gt;      &amp;lt;/plugin&amp;gt;&lt;br /&gt;    &amp;lt;/plugins&amp;gt;&lt;br /&gt;  &amp;lt;/build&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;!-- ******************************************************************&lt;br /&gt;    Project Information&lt;br /&gt;    ****************************************************************** --&amp;gt;&lt;br /&gt;  &amp;lt;organization&amp;gt;&lt;br /&gt;    &amp;lt;name&amp;gt;....&amp;lt;/name&amp;gt;&lt;br /&gt;    &amp;lt;url&amp;gt;http://..../&amp;lt;/url&amp;gt;&lt;br /&gt;  &amp;lt;/organization&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;developers&amp;gt;&lt;br /&gt;    &amp;lt;developer&amp;gt;&lt;br /&gt;      &amp;lt;id&amp;gt;ihu&amp;lt;/id&amp;gt;&lt;br /&gt;      &amp;lt;name&amp;gt;Immo H&amp;amp;uuml;neke&amp;lt;/name&amp;gt;&lt;br /&gt;      &amp;lt;email&amp;gt;ihu@zuhlke.com&amp;lt;/email&amp;gt;&lt;br /&gt;      &amp;lt;url&amp;gt;http://aspsp.blogspot.com/&amp;lt;/url&amp;gt;&lt;br /&gt;      &amp;lt;organization&amp;gt;Z&amp;amp;uuml;hlke Engineering&amp;lt;/organization&amp;gt;&lt;br /&gt;      &amp;lt;organizationUrl&amp;gt;http://www.zuhlke.com/&amp;lt;/organizationUrl&amp;gt;&lt;br /&gt;      &amp;lt;roles&amp;gt;&lt;br /&gt;        &amp;lt;role&amp;gt;architect&amp;lt;/role&amp;gt;&lt;br /&gt;        &amp;lt;role&amp;gt;developer&amp;lt;/role&amp;gt;&lt;br /&gt;      &amp;lt;/roles&amp;gt;&lt;br /&gt;      &amp;lt;timezone&amp;gt;0&amp;lt;/timezone&amp;gt;&lt;br /&gt;      &amp;lt;properties&amp;gt;&lt;br /&gt;        &amp;lt;picUrl&amp;gt;http://www.spaconference.org/cgi-bin/wiki.pl/?mugimmohuneke.jpg&amp;lt;/picUrl&amp;gt;&lt;br /&gt;      &amp;lt;/properties&amp;gt;&lt;br /&gt;    &amp;lt;/developer&amp;gt;&lt;br /&gt;  &amp;lt;/developers&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;inceptionYear&amp;gt;2008&amp;lt;/inceptionYear&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/project&amp;gt;&lt;/pre&gt;&lt;br /&gt;Hope this helps. If you still have problems, please e-mail me your Maven output - I may be able to guess where it is going wrong.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-3362413157831937216?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/3362413157831937216/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=3362413157831937216' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/3362413157831937216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/3362413157831937216'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/02/further-background-information-about.html' title='Further background information about Maven PDE builds'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-2461572307907417191</id><published>2008-02-16T05:02:00.000Z</published><updated>2008-02-18T18:05:18.489Z</updated><title type='text'>A Maven Eclipse RCP Product build at last!</title><content type='html'>&lt;p&gt;My sincere thanks to &lt;a href="http://www.breskeby.com/240"&gt;Ren&amp;eacute; Gr&amp;ouml;schke&lt;/a&gt; and &lt;a href="http://rcpquickstart.wordpress.com/2007/06/06/getting-started-with-pde-build"&gt;Patrick Paulin&lt;/a&gt; for putting me on the right track. These notes were developed using Eclipse RCP Developer (version 3.3.1.1 "Europa").&lt;/p&gt;&lt;p&gt;Below, I have documented the required steps in some detail, based largely on Ren&amp;eacute;'s tutorial. Some gotchas to watch out for include:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Contrary to popular belief, it is not necessary to install the Maven 2 Integration feature in Eclipse - in fact we found it confusing and removed it again, preferring to invoke various Maven goals through External Tool configurations under the Run menu&lt;/li&gt;&lt;li&gt;The build.properties file is very literal in its interpretation of properties you specify. In particular, when specifying a pathname, you must use forward slashes even under Windows, you must not have spaces in the pathname and you cannot enclose it in quotation marks. And most particularly, you cannot use symbolic references to any other property or environment variable (although the template supplied with the Eclipse PDE build plug-in misleads you here by suggesting that you can use ${user.home} as part of the buildDirectory property) - otherwise you will see the dreaded error message: &lt;tt&gt;Content Provider not set for Site: "{0}".&lt;/tt&gt;&lt;/li&gt;&lt;li&gt;You must specify a target platform in the base location that has had the Eclipse RCP Delta Pack installed, otherwise you may be able to build using PDE but you won't generate an executable.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;It is recommended to download both the &lt;a href="http://download.eclipse.org/eclipse/downloads/drops/R-3.3.1.1-200710231652/#RCPRuntime"&gt;RCP Runtime&lt;/a&gt; for your expected target platform architecture(s) and the &lt;a href="http://download.eclipse.org/eclipse/downloads/drops/R-3.3.1.1-200710231652/#RCPSDK"&gt;RCP Delta Pack&lt;/a&gt;. Install each target platform RCP runtime into its own location - e.g. if you have installed Eclipse in C:\tools\eclipse, I would suggest unzipping the RCP Runtime for 32-bit Windows on Intel x86 processors to C:\tools\eclipse\win32.win32.x86\eclipse. Unzip the delta pack into each of the targets. Let it overwrite all clashing filenames. Afterwards, if you are short of space, you can go through each Eclipse target platform and safely delete any plugins or features that don't correspond to the selected target architecture.&lt;/p&gt;&lt;p&gt;Having installed the target platform(s), it is probably a good idea to set the default Eclipse workspace target platform to the one for the type of workstation you are running on - e.g. if you're using a 32-bit Windows / Intel x86 computer, select Window -&gt; Preferences -&gt; Plugin Development -&gt; Target Platform and browse to C:\tools\eclipse\win32.win32.x86\eclipse (vary this path depending on the location of your Eclipse target platform). This ensures that native Eclipse builds and product exports will correspond as closely as possible to those built by the PDE in "headless" mode.&lt;/p&gt;&lt;p&gt;Another thing you need to do is to doctor the POM of the pde-maven-plugin (snapshot) so that it doesn't depend on outdated versions of org.eclipse.pde.core and org.apache.maven.shared.maven-osgi. Here is one way to do it:&lt;/p&gt;&lt;pre&gt;    &amp;lt;dependency&amp;gt;&lt;br /&gt;      &amp;lt;groupId&amp;gt;org.eclipse.pde&amp;lt;/groupId&amp;gt;&lt;br /&gt;      &amp;lt;artifactId&amp;gt;core&amp;lt;/artifactId&amp;gt;&lt;br /&gt;      &amp;lt;version&amp;gt;[3.3.0,4.0.0)&amp;lt;/version&amp;gt;&lt;br /&gt;    &amp;lt;/dependency&amp;gt;&lt;br /&gt;    &amp;lt;dependency&amp;gt;&lt;br /&gt;      &amp;lt;groupId&amp;gt;org.apache.maven.shared&amp;lt;/groupId&amp;gt;&lt;br /&gt;      &amp;lt;artifactId&amp;gt;maven-osgi&amp;lt;/artifactId&amp;gt;&lt;br /&gt;      &amp;lt;version&amp;gt;[0.1.9,)&amp;lt;/version&amp;gt;&lt;br /&gt;    &amp;lt;/dependency&amp;gt;&lt;/pre&gt;&lt;p&gt;Make sure you catch all copies of the POM. You can do this in your local Maven repository after a first attempt to build, or more permanently on your project repository. You can use the &lt;tt&gt;eclipse:to-maven&lt;/tt&gt; goal to get Eclipse plugins from the target platform folder into your local and/or project repository.&lt;/p&gt;&lt;p&gt;Let's work through a complete though simple example of creating an Eclipse RCP application that can be built from the command line using Maven. Broadly, this has the following stages:&lt;/p&gt;&lt;ol type="A"&gt;&lt;li&gt;Create the RCP application&lt;/li&gt;&lt;li&gt;Create a product configuration file&lt;/li&gt;&lt;li&gt;Create a build.properties file&lt;/li&gt;&lt;li&gt;Make a Maven POM&lt;/li&gt;&lt;li&gt;Run it and test the result&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Steps A-C are identical to what you would do if you wanted to create a project capable of supporting headless PDE builds. The only concessions to Maven are the layout of the source and output directories and the fact that we do not specify an eclipseLocation property in the build.properties file - this is instead configured in the Maven POM as the eclipseInstall parameter.&lt;/p&gt;&lt;p&gt;Now, are you sitting comfortably in front of your Eclipse IDE? Then follow the bouncing ball...&lt;/p&gt;&lt;h3&gt;A. Create the RCP application&lt;/h3&gt;&lt;ol&gt;&lt;li&gt;Start a new project: File -&gt; New -&gt; Project -&gt; Plug-In Project&lt;/li&gt;&lt;li&gt;Set project name = "com.breskeby.tutorial.rcp.withMaven"&lt;/li&gt;&lt;li&gt;Uncheck "Default location"&lt;/li&gt;&lt;li&gt;Specify a location outside the Eclipse workspace, e.g. C:\data\eclipseProjects\plugins\com.breskeby. tutorial.rcp.withMaven&lt;/li&gt;&lt;li&gt;Set Source folder = src/main/java (following the Maven convention)&lt;/li&gt;&lt;li&gt;Set Output folder = target/classes&lt;/li&gt;&lt;li&gt;Next&lt;/li&gt;&lt;li&gt;Check "Generate an Activator" and "This plugin will contribute to the UI"&lt;/li&gt;&lt;li&gt;Check "Create an RCP Application"&lt;/li&gt;&lt;li&gt;Next&lt;/li&gt;&lt;li&gt;Select the template "Hello RCP"&lt;/li&gt;&lt;li&gt;Next&lt;/li&gt;&lt;li&gt;Change the application window title to "Hello RCP with Maven"&lt;/li&gt;&lt;li&gt;Finish&lt;/li&gt;&lt;li&gt;If asked, decide whether to open the Plugin Developer perspective (it probably is not worth it at this stage)&lt;/li&gt;&lt;li&gt;Test the new plugin by clicking "Launch an Eclipse Application"&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;B. Create a product configuration file&lt;/h3&gt;&lt;ol&gt;&lt;li&gt;File -&gt; New -&gt; Other -&gt; Product Configuration&lt;/li&gt;&lt;li&gt;Parent folder = com.breskeby.tutorial.rcp.withMaven&lt;/li&gt;&lt;li&gt;Filename = withmaven.product&lt;/li&gt;&lt;li&gt;Check "Create a configuration file"&lt;/li&gt;&lt;li&gt;Finish - the product overview is displayed&lt;/li&gt;&lt;li&gt;Set Product Name = "RCP with Maven Example"&lt;/li&gt;&lt;li&gt;Product ID: click New...&lt;/li&gt;&lt;li&gt;Accept default values except Product Application&lt;/li&gt;&lt;li&gt;Set Application = "com.breskeby.tutorial.rcp.withMaven"&lt;/li&gt;&lt;li&gt;Finish&lt;/li&gt;&lt;li&gt;Check "Product Configuration based on plug-ins"&lt;/li&gt;&lt;li&gt;Click on the Configuration tab and click "Add..."&lt;/li&gt;&lt;li&gt;Select com.breskeby.tutorial.rcp.withMaven and click OK&lt;/li&gt;&lt;li&gt;Click "Add required plug-ins"&lt;/li&gt;&lt;li&gt;Save the product configuration&lt;/li&gt;&lt;li&gt;Test by right-clicking on the withmaven.product file in the package explorer and selecting "run as..." -&gt; "Eclipse Application"&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;C. Create a build-properties file&lt;/h3&gt;&lt;ol&gt;&lt;li&gt;Right-click the project folder com.breskeby.tutorial.rcp.withMaven and select New -&gt; Folder: name the folder "buildConfiguration"&lt;/li&gt;&lt;li&gt;In Windows Explorer or equivalent, find your Eclipse installation and navigate down to eclipse/plugins/org.eclipse.pde.build_*/template/headless-build. Copy build.properties from this file to the clipboard. Paste it into your new buildConfiguration folder in Eclipse. The asterisk in the above path stands for the version number of the Eclipse PDE builder. Make a note of it, as you'll need it in step D&lt;/li&gt;&lt;li&gt;Open the build.properties copy in an Eclipse text editor and click on the build.properties tab. Change the following properties:&lt;ol type="a"&gt;&lt;li&gt;product=withmaven.product&lt;/li&gt;&lt;li&gt;archivePrefix=withMaven&lt;/li&gt;&lt;li&gt;configs=win32, win32, x86 or change depending on your desired target(s) - but René has noted that only one target architecture can be built at a time&lt;/li&gt;&lt;li&gt;buildDirectory=[project directory]/target/eclipse.build (substitute the pathname of your project directory - see step A4 above - but use forward slashes)&lt;/li&gt;&lt;li&gt;buildId=withMaven&lt;/li&gt;&lt;li&gt;base=C:/tools/eclipse/win32.win32.x86 (depends on where you installed the target platform and which configuration you specified in configs - item c above). The base directory must contain a folder called "eclipse", which contains folders named "features" and "plugins"&lt;/li&gt;&lt;li&gt;pluginPath=.&lt;/li&gt;&lt;/ol&gt;The plugin path is the list of places to be searched for features and plugins needed during the build. In this case, the current working directory (i.e. the project directory) is fine, since the product build first creates the plugin in a plugins subdirectory.&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;D. Make a Maven Project Object Model (POM)&lt;/h3&gt;&lt;ol&gt;&lt;li&gt;Right-click the project folder com.breskeby.tutorial.rcp.withMaven and select New -&gt; File: name the file "pom.xml"&lt;/li&gt;&lt;li&gt;Into the new file, copy the template XML below&lt;pre&gt;&amp;lt;project xmlns="http://maven.apache.org/POM/4.0.0"&lt;br /&gt;  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt;  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0&lt;br /&gt;  http://maven.apache.org/maven-v4_0_0.xsd"&amp;gt;&lt;br /&gt;  &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;&lt;br /&gt;  &amp;lt;groupId&amp;gt;com.breskeby.tutorials.rcp&amp;lt;/groupId&amp;gt;&lt;br /&gt;  &amp;lt;artifactId&amp;gt;withMaven&amp;lt;/artifactId&amp;gt;&lt;br /&gt;  &amp;lt;packaging&amp;gt;zip&amp;lt;/packaging&amp;gt;&lt;br /&gt;  &amp;lt;name&amp;gt;RCP With Maven Example&amp;lt;/name&amp;gt;&lt;br /&gt;  &amp;lt;version&amp;gt;1.0-SNAPSHOT&amp;lt;/version&amp;gt;&lt;br /&gt;  &amp;lt;description&amp;gt;A Simple Product PDE Example&amp;lt;/description&amp;gt;&lt;br /&gt;  &amp;lt;build&amp;gt;&lt;br /&gt;    &amp;lt;plugins&amp;gt;&lt;br /&gt;      &amp;lt;plugin&amp;gt;&lt;br /&gt;        &amp;lt;groupId&amp;gt;org.codehaus.mojo&amp;lt;/groupId&amp;gt;&lt;br /&gt;        &amp;lt;artifactId&amp;gt;pde-maven-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;        &amp;lt;version&amp;gt;1.0-alpha-2-SNAPSHOT&amp;lt;/version&amp;gt;&lt;br /&gt;        &amp;lt;extensions&amp;gt;true&amp;lt;/extensions&amp;gt;&lt;br /&gt;        &amp;lt;configuration&amp;gt;&lt;br /&gt;          &amp;lt;eclipseInstall&amp;gt;${env.M2_HOME}/../eclipse&amp;lt;/eclipseInstall&amp;gt;&lt;br /&gt;          &amp;lt;pdeProductFilename&amp;gt;withmaven.product&amp;lt;/pdeProductFilename&amp;gt;&lt;br /&gt;          &amp;lt;pdeBuildVersion&amp;gt;3.3.2.R331_v20071019&amp;lt;/pdeBuildVersion&amp;gt;&lt;br /&gt;        &amp;lt;/configuration&amp;gt;&lt;br /&gt;      &amp;lt;/plugin&amp;gt;&lt;br /&gt;    &amp;lt;/plugins&amp;gt;&lt;br /&gt;  &amp;lt;/build&amp;gt;&lt;br /&gt;&amp;lt;/project&amp;gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Modify the configuration section as follows:&lt;ol type="a"&gt;&lt;li&gt;eclipseInstall - this is the path to your Eclipse RCP Developer installation (e.g. C:\tools\eclipse in the above example). Because my current project follows a convention about installing all tools in one place, I was able to use a property for this as shown above - your mileage may vary&lt;/li&gt;&lt;li&gt;pdeBuildVersion - insert the version number copied from the pathname of the folder whose name begins "org.eclipse.pde.build_" (see step C2 above)&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;E. Run the build and test the result&lt;/h3&gt;&lt;ol&gt;&lt;li&gt;Make sure all edited files have been saved&lt;/li&gt;&lt;li&gt;Ensure that your settings.xml is configured such that the required &lt;a href="http://snapshots.maven.codehaus.org/maven2"&gt;Maven snapshot repository&lt;/a&gt; is searched for plugins&lt;/li&gt;&lt;li&gt;Select the pom.xml file in the package explorer&lt;/li&gt;&lt;li&gt;Set up and use an external tool configuration to invoke Maven or run it from a command-line in the project directory: mvn clean install&lt;/li&gt;&lt;/li&gt;The result turns up in [project directory]/../../I.withMaven/withMaven-[architecture].zip - unzip it, open the resulting folder and double-click the executable you have just built!&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;I hope that you have found this useful. If you run into snags, please check that you have followed all the above steps to the letter before contacting me (if you leave a comment on this blog I should be notified by e-mail).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-2461572307907417191?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/2461572307907417191/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=2461572307907417191' title='34 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/2461572307907417191'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/2461572307907417191'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/02/maven-eclipse-rcp-product-build-at-last.html' title='A Maven Eclipse RCP Product build at last!'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>34</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-969263608622182605</id><published>2008-02-12T17:40:00.000Z</published><updated>2008-02-12T08:41:38.856Z</updated><title type='text'>The art of designing APIs</title><content type='html'>&lt;p&gt;In the restaurant last night, I was discussing with two colleagues why open-source software efforts such as &lt;a href="http://maven.apache.org/"&gt;Maven&lt;/a&gt; sometimes go awry. One reason is that APIs get changed, which really hacks off some of their users. I mentioned that I had seen &lt;a href="http://en.wikipedia.org/wiki/Joshua_Bloch"&gt;Joshua Bloch&lt;/a&gt; give a really useful talk about the design of APIs about four years ago. If his guidelines were followed more widely, perhaps it wouldn't be necessary for APIs or their semantics to change so often.&lt;/p&gt;&lt;p&gt;You can still get hold of Joshua's presentation slides and my notes of his talk at the &lt;a href="http://www.spaconference.org/cgi-bin/wiki.pl/?HowToDesignaGoodApiAndWhyItMatters"&gt;SPA Conference web site&lt;/a&gt;. Use the local link [u1] to access the slides.&lt;/p&gt;&lt;p&gt;Joshua Bloch contributes to &lt;a href="http://googleresearch.blogspot.com/"&gt;the Official Google Research Blog&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-969263608622182605?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/969263608622182605/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=969263608622182605' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/969263608622182605'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/969263608622182605'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/02/art-of-designing-apis.html' title='The art of designing APIs'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-619253323315671264</id><published>2008-02-04T23:15:00.000Z</published><updated>2008-02-04T15:40:41.599Z</updated><title type='text'>Maven dependency version ranges are broken</title><content type='html'>&lt;p&gt;I've been tearing my hair out trying to get Maven to build Eclipse RCP products. A lot of the problems I have had, as it turns out, are to do with Maven POMs that express dependencies on Eclipse artifacts with a range of versions.&lt;/p&gt;&lt;p&gt;Because you can't always update all your Eclipse plugins at once, it might seem to make sense to express dependencies on them not as a fixed version number but as a range. The following is a typical example (/org/eclipse/jdt/launching/3.3.0-v20070510/launching-3.3.0-v20070510.pom):&lt;/p&gt;&lt;pre&gt;&amp;lt;project&amp;gt;&lt;br /&gt;  ...&lt;br /&gt;  &amp;lt;groupid&amp;gt;org.eclipse.jdt&amp;lt;/groupid&amp;gt;&lt;br /&gt;  &amp;lt;artifactid&amp;gt;launching&amp;lt;/artifactid&amp;gt;&lt;br /&gt;  &amp;lt;name&amp;gt;Java Development Tools Launching Support&amp;lt;/name&amp;gt;&lt;br /&gt;  &amp;lt;version&amp;gt;3.3.0-v20070510&amp;lt;/version&amp;gt;&lt;br /&gt;  ...&lt;br /&gt;  &amp;lt;dependencies&gt;&lt;br /&gt;    &amp;lt;dependency&gt;&lt;br /&gt;      &amp;lt;groupid&amp;gt;org.eclipse.core&amp;lt;/groupid&amp;gt;&lt;br /&gt;      &amp;lt;artifactid&amp;gt;resources&amp;lt;/artifactid&amp;gt;&lt;br /&gt;      &amp;lt;version&amp;gt;[3.3.0,4.0.0)&amp;lt;/version&amp;gt;&lt;br /&gt;    &amp;lt;/dependency&amp;gt;&lt;br /&gt;    ...&lt;br /&gt;  &amp;lt;/dependencies&amp;gt;&lt;br /&gt;  ...&lt;br /&gt;&amp;lt;/project&amp;gt;&lt;/pre&gt;&lt;p&gt;Unfortunately this only works where the version number of the actual artifact in the repository &lt;a href="http://jira.codehaus.org/browse/MNG-3010"&gt;conforms to one of two patterns&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;A.B.C-D&lt;/pre&gt;&lt;p&gt;or&lt;/p&gt;&lt;pre&gt;A.B.C-qualifier&lt;/pre&gt;&lt;p&gt;(it is unclear whether the qualifier itself is subject to any formatting rules). In all other cases, Maven compares the artifact version number to the upper and lower bound of the range as a simple string, which actually means that version 3.3.0-v20070604 sorts below 3.3.0 and thus does not match the expression in the above example.&lt;/p&gt;&lt;p&gt;I may be able to fix this for individual POMs within our project repository and get the example build running, but that is not a general-purpose solution. Before long, someone on our project will bring in a dependency on some Eclipse plugin, which is obtainable from the Maven repository at Maven Central but only with a POM that contains a version range in one of its transitive dependencies.&lt;/p&gt;&lt;p&gt;Unfortunately, the majority of Eclipse plugins are likely to be in the Maven repository with this kind of version range dependency. The reason is that they get put there using the maven-eclipse-plugin (to-maven goal), which &lt;a href="http://jira.codehaus.org/browse/MECLIPSE-267"&gt;does not resolve OSGi Require-bundle version ranges &lt;/a&gt;when converting them to Maven dependencies. The latest version is meant to honour a property "resolveVersionRanges" (default is false), but I have not been able to get this to work.&lt;/p&gt;&lt;p&gt;And &lt;a href="http://svn.apache.org/viewvc/maven/plugins/trunk/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/EclipseToMavenMojo.java?r1=595639&amp;r2=598543&amp;pathrev=618281"&gt;here's why&lt;/a&gt; - Carlos has removed the line of code that invoked the &lt;tt&gt;resolveVersionRanges&lt;/tt&gt; routine.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-619253323315671264?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/619253323315671264/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=619253323315671264' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/619253323315671264'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/619253323315671264'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/02/maven-dependency-version-ranges-are.html' title='Maven dependency version ranges are broken'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-3714569224028762762</id><published>2008-01-31T01:48:00.000Z</published><updated>2008-01-30T17:51:28.550Z</updated><title type='text'>Building Eclipse RCP applications using Maven</title><content type='html'>&lt;p&gt;Still experiencing some problems following the &lt;a href="http://mojo.codehaus.org/pde-maven-plugin/examples/getting_started.html"&gt;Codehaus tutorial&lt;/a&gt;. Downloaded the examples and unpacked them without problems into the correct directory structure in my workspace, but then found that Eclipse doesn't recognise the three examples as Java projects even after running &lt;tt&gt;mvn eclipse:eclipse&lt;/tt&gt; on them. Moreover, trying to build the plugin using &lt;tt&gt;mvn clean install site&lt;/tt&gt; produces the sad error message:&lt;/p&gt;&lt;pre&gt;...\target\eclipse\startup.jar not found.&lt;br /&gt;Have you set up your -DeclipseInstall?&lt;/pre&gt;&lt;p&gt;My first thought was that my initial assumption must have been false (that it would be unnecessary to download the RCP Runtime and Delta Pack as detailed in the Codehaus tutorial, because we had started with the Eclipse RCP Developer edition). So I downloaded and unzipped them to a nice little target/eclipse folder of their own, and adjusted the three example POMs accordingly. While this is undoubtedly a Good Thing, because it masssively reduces the size of the exported product, it didn't magically cause a startup.jar to appear.&lt;/p&gt;&lt;p&gt;Luckily, &lt;a href="http://www.breskeby.com/zur-person"&gt;René Gröschke&lt;/a&gt; has posted a &lt;a href="http://www.breskeby.com/240"&gt;commentary&lt;/a&gt; on the Codehaus tutorial, identifying where it leads the student astray. Luckily I can read German. I'll try to post here what I find out.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-3714569224028762762?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/3714569224028762762/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=3714569224028762762' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/3714569224028762762'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/3714569224028762762'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/01/building-eclipse-rcp-applications-using.html' title='Building Eclipse RCP applications using Maven'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-3723988481074969420</id><published>2008-01-25T23:55:00.000Z</published><updated>2008-01-25T15:55:55.435Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='eclipse pde'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse rcp'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><title type='text'>Where's the system bundle jar file? (cont.)</title><content type='html'>&lt;P&gt;Well, you probably won't be surprised to learn that the result is no different using the latest maven-eclipse-plugin version 1.5-SNAPSHOT, dated 30th November 2007. I had to create an entire Maven project to invoke the to-maven goal on the maven-eclipse-plugin, just so that I could specify the version I wanted to run. But this should be quite a useful asset in the long run anyway: I can now type&lt;/p&gt;&lt;pre&gt;mvn install&lt;/pre&gt;&lt;p&gt;or&lt;/p&gt;&lt;pre&gt;mvn deploy&lt;/pre&gt;&lt;p&gt;to invoke the corresponding actions. At the moment, however, there is no way to get beyond any plugin whose MANIFEST.MF specifies &lt;b&gt;system.bundle&lt;/b&gt; as a required bundle.&lt;/p&gt;&lt;p&gt;The &lt;a href="http://www2.osgi.org/Repository"&gt;OSGI Bundle Repository Browser&lt;/a&gt; confirms that &lt;b&gt;system.bundle&lt;/b&gt; does in fact refer to the org.eclipse.osgi jar file. I therefore decided to supply the missing artifact, by using &lt;b&gt;file:deploy-file&lt;/b&gt; to create it from org.eclipse.osgi...jar. I added this to the POM of my eclipse-to-maven project and linked it to the &lt;b&gt;initialize&lt;/b&gt; phase.&lt;/p&gt;&lt;p&gt;It still doesn't work. For some reason, because the Require-Bundle instruction in MANIFEST.MF does not specify a version number, the maven-eclipse-plugin cannot find the artifact I created. It tells me that it was unable to resolve the version range for version &lt;b&gt;&lt;i&gt;[0,)&lt;/i&gt;&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;So as an experiment, I altered the MANIFEST.MF of the Xerces plugin to explicitly require the actual version number of the org.eclipse.osgi bundle - and hey presto, this was resolved successfully. But we really can't go through all manifests of all Eclipse plugins every time we want to run this plugin and update the system.bundle requirement!&lt;/p&gt;&lt;p&gt;This must be a bug in the maven-eclipse-plugin (caused by a &lt;a href="http://help.eclipse.org/stable/topic/org.eclipse.platform.doc.isv/porting/3.3/incompatibilities.html"&gt;documented incompatibility&lt;/a&gt; between Eclipse 3.2 and 3.3, which has led a number of bundle committers to add "Require-bundle: system.bundle" to their manifests), so I have submitted a &lt;a href="http://jira.codehaus.org/browse/MECLIPSE-373"&gt;bug report&lt;/a&gt; about it.&lt;/p&gt;&lt;p&gt;In fact, on closer investigation it transpired that there are currently only two Eclipse plugins that fall into this category: &lt;b&gt;org.eclipse.xerces&lt;/b&gt; and &lt;b&gt;org.eclipse.xml.resolver&lt;/b&gt;. In fact it wasn't even necessary to create a &lt;b&gt;system.bundle&lt;/b&gt; artifact - I just altered the two manifests temporarily to express a dependency on the exact version of the &lt;b&gt;org.eclipse.osgi&lt;/b&gt; plugin supplied with the Eclipse installation in question. With this modification, the &lt;b&gt;&lt;i&gt;eclipse:to-maven&lt;/i&gt;&lt;/b&gt; goal was able to run successfully to completion.&lt;/p&gt;&lt;p&gt;On to the next stage! But first, there is a weekend to take care of...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-3723988481074969420?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/3723988481074969420/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=3723988481074969420' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/3723988481074969420'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/3723988481074969420'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/01/wheres-system-bundle-jar-file-cont.html' title='Where&apos;s the system bundle jar file? (cont.)'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-3243769265881191199</id><published>2008-01-25T01:43:00.000Z</published><updated>2008-01-25T17:46:32.031Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='eclipse pde'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse rcp'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><title type='text'>Where's the system bundle jar file?</title><content type='html'>&lt;p&gt;Quick update to my last posting: a number of Eclipse plugins have recently sprouted this RequireBundle attribute thanks to a published &lt;a href="http://help.eclipse.org/stable/index.jsp?topic=/org.eclipse.platform.doc.isv/porting/3.3/incompatibilities.html"&gt;incompatibility between Eclipse 3.2 and 3.3&lt;/a&gt; in the area of &lt;b&gt;Boot Delegation&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;It looks as if the System Bundle is either mapped to &lt;b&gt;org.eclipse.osgi&lt;/b&gt; or doesn't really exist as a separate jar file in its own right at all. Maybe there's a newer version of the Maven Eclipse plugin that understands this?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-3243769265881191199?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/3243769265881191199/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=3243769265881191199' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/3243769265881191199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/3243769265881191199'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/01/wheres-system-bundle-jar-file.html' title='Where&apos;s the system bundle jar file?'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-4265396166830751729</id><published>2008-01-25T01:03:00.000Z</published><updated>2008-01-25T17:45:50.515Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='eclipse pde'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse rcp'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><title type='text'>Creating Maven artifacts from Eclipse plugins</title><content type='html'>&lt;p&gt;Along the long and tortuous road of creating Maven builds for Eclipse RCP applications, one of the first steps is to take the Eclipse plugins that make up the target platform and convert them into Maven artifacts. This ensures that the Maven POM is able to refer to them by its holy triad of group ID, artifact ID and version.&lt;/p&gt;&lt;p&gt;In the &lt;a href="http://maven.apache.org/plugins/maven-eclipse-plugin/to-maven-mojo.html"&gt;Maven Eclipse Plugin&lt;/a&gt;, a goal &lt;i&gt;eclipse:to-maven&lt;/i&gt; is provided that is meant to satisfy exactly this need. Given an Eclipse installation directory, it trawls through all the plugins it can find and installs them in your local Maven repository, even generating POMs that correctly show interdependencies between plugins. If you optionally specify a &lt;i&gt;deployTo&lt;/i&gt; parameter, it will even deploy the resulting artifacts to a remote repository for everyone on your project to use.&lt;/p&gt;&lt;p&gt;When I tried this for my Eclipse RCP installation, however, it failed. There were two versions of the plugin &lt;b&gt;org.apache.xerces&lt;/b&gt; in the plugins folder, and Maven could not resolve which of them to turn into a Maven artifact. This might not have been a problem but for the fact that the version numbers of both were the same (2.0.8) apart from the timestamp - one was a folder, the other a self-contained jar file.&lt;/p&gt;&lt;p&gt;The same problem has also been encountered by others - e.g. when trying to use the slightly older but equivalent &lt;a href="http://www.mail-archive.com/users@maven.apache.org/msg73134.html"&gt;eclipse:make-artifacts&lt;/a&gt; goal.&lt;/p&gt;&lt;p&gt;Having checked in the Eclipse &lt;b&gt;Plugin View&lt;/b&gt; that there was nothing dependent on it, I removed the older of the two Xerces plugins. The to-maven goal was now able to run - but the build still didn't complete (see below).&lt;/p&gt;&lt;p&gt;I consider this to be a bug in the Eclipse RCP distribution version 3.3.1.1. Despite a &lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=29056"&gt;lengthy discussion&lt;/a&gt; in the bug tracker five years ago, nothing appears to have been done. I have accordingly lodged a new &lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=216452"&gt;bug report&lt;/a&gt; and we'll see whether this gets fixed in a future release.&lt;/p&gt;&lt;p&gt;The new problem now is the generated POM for org.apache.xerces. For some reason the Maven eclipse plugin is unable to determine the version number of some dependency (the error message doesn't make a lot of sense):&lt;/p&gt;&lt;pre&gt;[INFO] Unable to resolve version range for dependency&lt;br /&gt;Dependency {groupId=system, artifactId=bundle,&lt;br /&gt;version=[0,), type=jar} in project org.apache.xerces&lt;/pre&gt;&lt;p&gt;Inspection of the MANIFEST.MF in the Xerces plugin jar file reveals:&lt;/p&gt;&lt;pre&gt;Bundle-Version: 2.8.0.v200705301630&lt;br /&gt;Require-Bundle: system.bundle,org.apache.xml.resolver;&lt;br /&gt;visibility:=reexport&lt;/pre&gt;&lt;p&gt;So that is why Maven can't be sure what version is wanted. Luckily, this particular artifact is already in the &lt;a href="http://repo1.maven.org/eclipse/org/apache/xerces/2.8.0-v200705301630/"&gt;Maven central repository&lt;/a&gt;, so to short-circuit all this I removed the Xerces plugin jar temporarily as well and re-ran the Maven command.&lt;/p&gt;&lt;p&gt;To my surprise, the build failed this time with the following message:&lt;/p&gt;&lt;pre&gt;[INFO] Unable to resolve version range for dependency&lt;br /&gt;Dependency {groupId=org.apache, artifactId=xerces,&lt;br /&gt;version=[2.8.0,3.0.0), type=jar}&lt;br /&gt;in project org.eclipse.wst.xml.core&lt;/pre&gt;&lt;p&gt;This makes no sense, since version 2.8.0 of org.apache.xerces clearly does exist in the central repository. Maybe Maven doesn't consider 2.8.0-v200705301630 to be in the above range?&lt;/p&gt;&lt;p&gt;So I tried another tack: restore the older Xerces plugin to the Eclipse plugins folder. This time the Xerces plugin is successfully installed in the local repository, and the plugin org.eclipse.wst.xml.core likewise. Instead, the build fails a bit later with:&lt;/p&gt;&lt;pre&gt;[INFO] Unable to resolve version range for dependency&lt;br /&gt;Dependency {groupId=system, artifactId=bundle,&lt;br /&gt;version=[0,), type=jar}&lt;br /&gt;in project org.apache.xml.resolver&lt;/pre&gt;&lt;p&gt;This is exactly the problem that the Xerces plugin failed on in the first instance. So I suspect that I'm going to have to find out how to create a Maven artifact called &lt;b&gt;system.bundle&lt;/b&gt;. Watch this space.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-4265396166830751729?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/4265396166830751729/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=4265396166830751729' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/4265396166830751729'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/4265396166830751729'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/01/creating-maven-artifacts-from-eclipse.html' title='Creating Maven artifacts from Eclipse plugins'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5605173550883974775.post-8350301760865499859</id><published>2008-01-23T20:40:00.000Z</published><updated>2008-01-23T12:59:00.332Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='eclipse pde'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse rcp'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><title type='text'>Build Eclipse RCP products using Maven 2 - how hard can it be?</title><content type='html'>&lt;span style="font-family: georgia;font-size:100%;"  &gt;I am working as part of a project team developing a suite of applications that use &lt;a href="http://wiki.eclipse.org/index.php/Rich_Client_Platform"&gt;Eclipse RCP&lt;/a&gt; as their platform. We are also using &lt;a href="http://cruisecontrol.sourceforge.net/"&gt;CruiseControl&lt;/a&gt; for continuous integration and testing. We currently build Eclipse RCP products, features and fragments using &lt;a href="http://www.eclipse.org/pde/"&gt;Eclipse PDE&lt;/a&gt;, partly because of its OSGI support. We would like to move to using &lt;a href="http://maven.apache.org/"&gt;Maven 2&lt;/a&gt; in order to match the way we build all our Eclipse plugins and Java libraries. This will make it straightforward to generate comprehensive documentation on the Web, stay in control of dependencies, link into our bug tracking and progress tracking system and so on.&lt;br /&gt;&lt;br /&gt;A parallel initiative is my attempt to set up the Eclipse development environment for each team member so that Maven builds and Eclipse builds work seamlessly together on the workstation. Initially I thought that this would require the use of the &lt;a href="http://maven.apache.org/eclipse-plugin.html"&gt;Maven 2 Integration for Eclipse&lt;/a&gt; plugin. However, it turned out that even this is not nearly as closely integrated into Eclipse as Ralf Quebbemann's equivalent &lt;a href="http://plugins.intellij.net/plugin/?id=1166"&gt;Maven 2 Integration&lt;/a&gt; is integrated into IntelliJ IDEA, for example. We found it easiest to configure various Maven goals as "external tools" in Eclipse's &lt;span style="font-weight: bold; font-style: italic;"&gt;Run&lt;/span&gt; menu and to use the &lt;a href="http://maven.apache.org/plugins/maven-eclipse-plugin/"&gt;Maven eclipse plugin&lt;/a&gt; to generate or update the Eclipse classpath and project files (&lt;span style="font-size:85%;font-family: courier new;"&gt;mvn eclipse:eclipse&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;[&lt;span style="font-weight: bold;"&gt;Footnote&lt;/span&gt;: &lt;span style="font-family: courier new;font-size:85%;" &gt;mvn eclipse:configure-workspace&lt;/span&gt; works during installation, but only if the configured Maven repositories are online, which rather defeated my objective of creating a standalone developer kit installer. I found that this goal simply inserts a definition of the M2_REPO classpath variable into one of Eclipse's metadata files, so I made the installer do that directly instead. It now runs much faster too.]&lt;br /&gt;&lt;br /&gt;Despite the existence of the book &lt;a href="http://www.devzuz.com/web/guest/products/resources#BBWM"&gt;Better Builds with Maven&lt;/a&gt;, a common complaint about Maven 2 is that it is not sufficiently well documented for heavy-duty use. The book was last updated in August 2007, since when two further releases of Maven have come out. The book doesn't mention Eclipse RCP or PDE. In trying to marry the use of Maven with Eclipse, we are very much having to hoe our own furrow.&lt;br /&gt;&lt;br /&gt;I'm using this blog to record the approaches we take and how we fare. Hopefully after a few weeks (not too many!) it will be possible to summarise all the findings into a "how to" for future reference.&lt;br /&gt;&lt;br /&gt;My current understanding is that the most promising approach would be using a  combination of the &lt;a href="http://maven.apache.org/plugins/maven-eclipse-plugin/pde.html"&gt;maven-eclipse-plugin&lt;/a&gt; (with the PDE property set to  &lt;i&gt;true&lt;/i&gt;) and the &lt;a href="http://docs.codehaus.org/display/MAVENUSER/Building+Eclipse+RCP+and+RCP-based+Applications"&gt;pde-maven-plugin&lt;/a&gt;. These allow us to create the Eclipse project and classpath files slightly differently in order to permit "headless" PDE builds to take place. As I understand it, the PDE Maven plugin generates an &lt;a href="http://ant.apache.org/"&gt;Ant&lt;/a&gt; build file that can then be used to run the headless PDE build. There are a few wrinkles; for example we may have to obtain  a more recent snapshot of the pde-maven-plugin because the last official release  &lt;a href="http://jira.codehaus.org/browse/MOJO-889"&gt;doesn't appear to work with Europa&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;One project which does appear to have been successful in building RCP products using Maven is &lt;a href="http://www.jlibrary.org/repositories/jlibrary"&gt;jLibrary&lt;/a&gt;, an open source document management / content management system. Martin Perez and Ryszard Petrowski have documented their &lt;a href="http://www.jlibrary.org/repositories/jLibrary/Development/Building%20jLibrary%201.2.html"&gt;build approach for jLibrary 1.2&lt;/a&gt;. I intend to study this and learn from it. More anon!&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5605173550883974775-8350301760865499859?l=aspsp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aspsp.blogspot.com/feeds/8350301760865499859/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5605173550883974775&amp;postID=8350301760865499859' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/8350301760865499859'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5605173550883974775/posts/default/8350301760865499859'/><link rel='alternate' type='text/html' href='http://aspsp.blogspot.com/2008/01/build-eclipse-rcp-products-using-maven.html' title='Build Eclipse RCP products using Maven 2 - how hard can it be?'/><author><name>Immo Hüneke</name><uri>http://www.blogger.com/profile/17107000566759440656</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp0.blogger.com/_eJ-aAjApSE0/R5ciL8jc1DI/AAAAAAAAAo0/iUODk-kllKM/S220/scaled-200-immo.jpg'/></author><thr:total>1</thr:total></entry></feed>
