Shorten links to be Twitter-friendly with j.mp

Any Twitter users out there will know that URLs and 140 characters don't really mix that well, especially if you actually want to talk about the link as well!  Typically you would use a URL shortening service such as the original tinyurl.com or one of the newer, shorter versions such as bit.ly.

Well there is a new kid on the block who's even shorter: j.mp

J.mp is another member of the bit.ly family just with two less letters, but it's going to be perfect for Twitter.  I use the bit.ly bookmarklet to generate my links but it appears that there is not a version for j.mp yet, so I created my own:

Drag this link to your browser toolbar to get started:    Shorten with j.mp

Technorati Tags: , , , ,

Summary of December's Manchester Spring User Group Meeting

The December Spring meeting was held on Tuesday 1st December at the same venue as previous meetings. Two talks were lined up: one on Grails by Adam Evans and one on Spring 3.0 by Rick Evans.

Guy Remond of Cake Solutions started the evening off with introductions and explained that the Spring User Group was going to be expanding to become the 'Open Source Central User Group' so as to attract a more diverse audience. He also discussed the Open Source Central website which has plans to become the 'Hub for successful Open Source Enterprise Application Development'. It's going to pull various blogs together into one central place as well as offering video and podcasts of open source technologies. We were also some of the first people to get a physical copy of the Open Source Journal, a 5,000-copy print run (sponsored by Hays IT).

Practical Grails Demonstration by Adam Evans of CTI

Adam started his presentation with a brief run through of what is Grails, what is Groovy and showed that Groovy 'can' be just standard Java code. Grails applications compile cleanly down to a WAR file so deployment in your favourite appserver is easy. It uses GSPs and Sitemesh for the view layer, GORM for the database layer and supports a plugin-based architecture allowing you to 'plugin' views, controllers, domain objects, sessions and scripts.

He then went on to demo building a Grails application on the fly using SpringSource Tool Suite (STS). Unfortunately Adam's laptop wasn't up to the job of running STS (basically Eclipse) and Powerpoint at the same time and so he had major 'not responding' issues. Despite these technical difficulties Adam battled on filling the gaps with details of Grails (Grails 1.2 supports annotated Spring beans) and had the foresight to have a slide-based version of the demo to hand (major kudos to Adam!)

Then he 'built' a demo application which uses the Twitter API to perform a search on whatever you type into the input box. An interesting point was that the Twitter results were returned in JSON and the GSP expression language allows you to parse that data as if it was a first-class object, doing things like tweet.username.

Adam has also kindly posted a copy of his slides to SlideShare.net.

Guy then stepped back in to thank the sponsors of the event: Cake Solutions, OpenCredo, Skills Matter, FDM Group, Hays IT.

Spring 3.0 :: Weapons for the war on Java complexity by Rick Evans of QFI

Rick has been working with Spring since 2004 and has delivered loads of training courses on it as well. He started his presentation with a humorous youtube clip of a mega-beast of a shotgun, and his theme was whether various Spring 3 features were potato guns or super shotguns...

He started off with a brief overview of the changes made in Spring 2.5 ('ease of use') and then moved on to the new things in Spring 3.0 - key points: embrace Java 5 and heavy use of annotations as 'declarations of intent'. Spring 3 introduces SPEL - the Spring Expression Language as the default expression language across all the modules (Webflow, Batch, etc.).

REST is nicely supported now with both server-side support in the form of additional annotations for controllers: @PathVariable & the enhanced @RequestMapping, and client-side with the use of RestTemplates. Rick also mentioned the use of HiddenHttpMethodFilter to ensure that your standard browser forms could correctly call the right type of REST operation, silently mapping POSTs to DELETEs if required.

There are some new annotations in the Controller world: @RequestParam now has a 'defaultValue' attribute and @CookieValue and @RequestHeader allow you to extract data from cookies and HTTP headers accordingly. Validation has been revisited with a smattering of new annotations to ensure objects are @NotNull, have @Max and @Min values, etc. This is all activated via a Validator - either javax.validation.Validator or the old-skool org.springframework.validation.Validator.

Rick's final words were to do with the fact that there is no 'all encompassing' spring.jar anymore, it's split up into it's component parts and you pull in what you want - if you are using Maven or Ivy then I suppose this isn't a problem, but how do you deal with it if not? He also said that loads of stuff had been deleted, cleaned up or deprecated which is always a good thing - no point carrying cruft around.

Rick has also kindly posted a copy of his slides to Box.net

Then it was over the road to The Bowling Green pub for a pint on Cake Solutions (cheers Cake!) and a catch up with some old colleagues and meet some new north west developers...

Technorati Tags: , , , , , ,

Don't miss the December Manchester Spring User Group on Tuesday 1st December

There was a little doubt recently if this event was going to take place as the main speaker had to pull out at the last minute.  We now have a new and excellent speaker Rick Evans talking about Spring 3.0 - Weapons for the War on Java Complexity".

Doors open at 6pm and the main keynote normally starts around 6:30 (a chance for coffee and a chat before hand).It's in the usual place, just don't forget to register if you plan on going!

Technorati Tags: , , , ,

Paste Email Plus - perfect for multiple text snippets in Firefox

I've found recently when commenting on various blogs that I want to add a little footer to the comment with my name and blog address. For one or two comments typing it out by hand is fine but after a while I decided to try and find an automated way to deal with this issue.

So I was looking for something that allows me to enter multiple lines of text and then very easily insert this text wherever I choose. Well I quickly found the perfect solution - a Firefox add-on called Paste Email Plus by Chuck Baker.

You simply open the Paste Email Plus options window, enter a 'Label' to help identify this text, then enter the multi-line text in the 'Pastetext' field and click 'Save changes':




You are now set up and ready to start pasting that text snippet, in any area where you would normally type text just right-click and select 'Paste Email Plus' (below 'Paste' on my system) and then choose your labelled snippet:




You will now see your text chunk pasted into the text area wherever your cursor was at the time of the right-click!

Technorati Tags: , ,

JavaScript splits & matches with regular expressions (regex)

I had been developing some client-side validation code in jQuery/JavaScript and using Firefox (and the excellent Firebug) to test and debug it. I was then asked to ensure that it worked in IE6 & IE7 and that's when the problems started.

Apart from the usual "which file does that line number equate to, and why does it not tie up?" issues I found that IE doesn't like taking a regular expression as it's parameter to the JavaScript split function. Firefox will happily accept this and works fine but IE doesn't. After some searching it appears that Firefox might be the odd one out and that it's non-standard to pass in a regex.

So what do you do if you want to split up a string based on a regular expression or rather a rule that can't be simply expressed in the way that the split function wants it? Wouldn't it be nice if you could ask if a string matches a regex but then use certain matched bits of the string in your next few lines of code?

Well you can, simply use the match method, surrounding the bits of the regex that you want to use later in parenthesis '(' and ')' and then you can use the global JavaScript variable RegEx to pull them out.

So if 1234-ABC is your text, and you want the numbers as one part and the characters as another then you would use this regular expression to match on: ^([0-9]*)-([A-Z]*)$. You can then get hold of the matched numbers bit with RegEx.$1 and the letters bit with RegEx.$2.

var productCode = "1234-ABC";
productCode.match(/^([0-9]*)-([A-Z]*)$/);
var numbers = RegEx.$1;
var letters = RegEx.$2;
Technorati Tags: , ,

How to disable the auto-completion 'bell' in Cygwin (using RXVT)

If you have ever hit TAB a few times in bash (via RXVT) you will probably be greeted with the loudest 'bell' your PC can muster. After a while this gets pretty annoying so here's how to disable it if you are using RXVT inside Cygwin (this might work for other Cygwin terminals, I've just not checked)

Navigate to your home directory (normally just by typing cd and either edit or create a file called .inputrc

Add the following lines to the .inputrc file:

# Disable the annoying bell
set bell-style none
Save the file, close the terminal and reopen - you should now be bell-less!

Technorati Tags: , ,

How to get Scala working with the RXVT terminal on Cygwin

Out of the box Scala support Cygwin, but this is only with the Windows command prompt-based bash terminal. If you have opted for the more UNIX-like terminal of RXVT then you will find that although the interactive Scala interpreter runs, you can't get it to do anything!

This has been raised as a bug (Ticket #2097) against the Scala project and graehl even posted a patch to changed the generation of the scala runtime scripts.  As my Scala install was based on the downloaded Windows binaries (scala-2.7.6.final.zip) I couldn't directly use this patch, but I could examine it to see what graehl's fix was.

It appears that the key bit was to add the following Java command line option to the java statement that starts the scala interactive interpreter:

-Djline.terminal=jline.UnixTerminal
So the last line of my bin/scala file is:
exec "${JAVACMD:=java}" $JAVA_OPTS -cp "$TOOL_CLASSPATH" -Dscala.home="$SCALA_HOME" -Denv.classpath="$CLASSPATH" -Denv.emacs="$EMACS" -Djline.terminal=jline.UnixTerminal scala.tools.nsc.MainGenericRunner  "$@"
This appears to work, my interactive environment is now interactive!

Technorati Tags: , , ,

Tommy Emmanuel being VERY creative with an acoustic guitar and some clever delay

I don't often post about guitar stuff as I really want to keep this blog focused on the tech side of my life but I couldn't help but pass this YouTube link on:

Delay (& Creative Uses for It)

I started to watch it and was soon completely captivated by it, hope you like it too!

Technorati Tags: , ,

The next Manchester Spring User Group meetup is 13th October

Details of the next Manchester Spring User Group meeting are now available, as a taster for what it could be like I blogged about the last meeting. It looks like the main talk is going be from Jonas Partner on Spring Integration.

It's a 6pm start in the usual place (there's a lovely space-age building where the building site is on Google maps...) Remember there's free parking if you pull up to the barrier and mention the Spring User Group.

Hope to see you there - if you see a skinhead with glasses please come over and say hello! Oh and make sure you register to be guaranteed entry!

Technorati Tags: , , , , ,

Use Pidgin? Send screenshots with this great new plugin!

I've been a big fan of Pidgin (formerly Gaim) for the past few years and one feature that I've always wanted was an easy way to send a screenshot to a buddy.

Well Raoul Berger obviously wanted it too and he's gone and developed the excellent 'send screenshot' plugin. Download and install it and make sure you have enabled it:


Then you can right-click and buddy in your buddy list and choose 'Send screen capture...' - your screen then darkens and you have a crosshair with which to select the region that you would like to send to you 'buddy':


You can also send a screenshot within a existing conversation by choosing the 'Convesation' -> 'More' -> 'Send screen capture...' option:



Another and fast, better way is to ensure that you have 'Show detailed information' selected in the 'Conversations' tab of the preferences and then you can simply right-click on the person's banner and select the option:


Also, after an email conversation with the send screenshot plugin author he's mentioned that he's looking to add a keyboard shortcut in the next release, which will make the whole process even slicker!

This is a great plugin and thanks to Raoul for taking the time to develop it (for a number of platforms I may add).

Technorati Tags: , , , ,

You NEED an X-mini II speaker for your MP3 player or iPod

My wife was looking around for an external speaker for her MP3 player and in our searching we came across the XMI X-Mini speaker on Amazon. This little mono speaker has 105 five star reviews (out of 115) on Amazon and at the time was £20 (it's now £16.96 - was £15 for a short time).

It's an absolutely cracking speaker - the internal (rechargeable) battery lasts for hours and this thing can really pump it out - with the bass expansion chamber opened up it sounds amazing. We have used it as a speaker for an MP3 player as well as an output speaker for a guitar headphone amp - true rock guitar sound on the move!

If you are on the look out for a mini speaker for your MP3 player you will not be disappointed with an X-Mini!

Technorati Tags: , , , , ,

Summary of August's Manchester Spring User Group Meeting

The August Spring meeting was held on Tuesday 11th August at the same venue as June's meeting. The location was the the excellent University of Manchester Core Technology Facility which has free parking immediately outside the building, just press the buzzer and mention the Spring User Group and they let you in. The evening was introduced by Guy Remond of Cake Solutions who laid out the agenda.

The first talk was by Cornel Foltea of Cake Solutions entitled:

Hello World! (OSGi debugging in IDEA)

Cornel started out by giving a little overview of OSGi including a walk-through of the layered approach that the Open Service Gateway Initiative takes. He pointed out that it's key objectives were:

  • modularization
  • versioning
  • services
  • access control
The key component of any OSGi system is a 'bundle' which get deployed into an OSGi container. A bundle can then be dynamically installed, started, stopped, updated and uninstalled. They are modular in nature 'assuming nothing' - they are a JAR file, with it's contents protected from access unless it explicitly exports it's services and declares that it needs to import services offered by other bundles. Multiple versions of the same bundle can exist in the application server without conflicting with each other. OSGi also provides a Service Registry so that bundles can register (export) their services for use by other bundles.

Then Cornel went on to talk about what OSGi features IntelliJ's IDEA currently offers (a MANIFEST.MF editor and OSGi facet detection) and how to create a "Hello World!" application OSGi-style. The heart of this is the BundleActivator interface that you need implement to provide start and stop methods called by the OSGi application server (make sure you have downloaded the OSGi framework jar and add it to your classpath first):
package com.cake.dmsd.primer;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

public class HelloWorldActivator implements BundleActivator {

public void start(BundleContext context) throws Exception {
System.out.println("Hello, World.");
}

public void stop(BundleContext context) throws Exception {
System.out.println("Goodbye World.");
}
}
Then you need to create the jar's MANIFEST.MF file to look like the following:
Manifest-Version: 1.0
Bundle-Name: Helloworld Bundle
Bundle-Activator: com.cake.dmsd.primer.HelloWorldActivator
Import-Package: org.osgi.framework;version="1.4.0"
Bundle-ManifestVersion: 2
Bundle-SymbolicName: helloworld
Bundle-Version: 1.0.0
Next he talked a little about setting up a remote server 'Debug Configuration' to allow IDEA to connect to the debug port of the dmServer (think this picture paints a thousand words!) - note the port number of 5005 and the fact that one of the parameters is -Xdebug:


Then he showed screenshots of shelled out to a console to start up the dmServer in debug mode by running:
./startup.sh -debug 5005
Once that was running the next step was to telnet to the dmServer running on the local machine and install the previously created bundle:
telnet localhost 2401
install
This step gives us a bundle ID (111 in Cornel's example) which refers to the specific instance of the bundle that we have just installed. This ID means that we can start and stop the bundle in the future using start 111 and stop 111 from the dmServer telnet console.

After Cornel's talk there was a little break which contained a mention of the Manchester Spring User Group sponsors: UMIC, Hays IT, Skills Matter, SpringSource & Cake Solutions and the new sponsor of the event: Keith Dauris of FDM Group (and it's associated FDM Academy).

The next talk was by Dave Syer and his talk was:

Spring 3.0 and Spring Batch Quick Tour

The first half of Dave's presentation was on the new features of Spring 3.0 and it was an excellent way to quickly get an idea of the type of stuff that's coming very soon. Spring 3.0 is the first version of Spring to only work on Java 5 and above, meaning that even more annotation support can be included. It's also introducing the Spring Expression Language (influenced by Unified EL++), full REST support and declarative scheduling & background task execution.

The Object <-> XML Mapping (OXM) has been revised to offer better support for REST stateless mappers and SQL XML access. The JDK PropertyEditors are being superceded by a revised binding & type conversion infrastructure. If you don't like writing your Spring bean configuration in XML then you are in luck with Spring 3.0 - you can now write it in Java (although I thought the idea of the config _not_ in Java was that you could change it without recompile? Maybe it would have been better to offer non-XML config via something like Groovy?)

Full REST support is now available (with a custom filter to help support PUT & DELETE) which includes annotations to be able to extract values from within the URL:
@RequestMapping(value="/rewards/{id}", method="GET")
public Reward reward(@PathVariable("id") long id) {
...
}
By using multiple @PathVariable annotations you will be able to offer some pretty 'deep' URLs, meaning that you won't be held back by the normal servlet mappings. Dave mentioned that someone was using some shell scripts consisting of wget/curl and pipes to create some pretty complex business logic. Non-HTML representations are also offered 'out of the box' so it's very easy to offer JSON, XML, ATOM, etc. without using complex URLs or query strings.

Scheduling has been given a complete overhaul in Spring 3.0, with enhanced java.util.concurrent support and a new TaskScheduler with triggers (a little like a simplified Quartz). There is a new @Async annotation (indicating that this method should be run in the background) along with an @Scheduled annotation for CRON-triggered methods.

Commons Attributes has now been removed along with traditional TopLink and Struts 1.x (subclass-style). Traditional MVC controllers are now marked as deprecated along with JUnit 3.8 support (as why would you not want to use JUnit the annotated way?) and several other outdated helper classes.

Expect a GA release of Spring 3.0 sometime after August, and a 3.1 release in Q4 2009.


Dave's second presentation was on Spring Batch, which he has been the project leader on for the past three years (version 2.0 was released back in April). He started with an overview of the architecture, saying that the Batch Infrastructure layer contains reusable low level stuff: flat files, XML, database configuration. The Batch Core layer contains the quality of service (QoS), audibility and management information and the Application is your business logic.

He said that in it's most basic form it was a "glorified state management system" and then proceeded to describe some of the key objects that make up the heart of Spring Batch (item oriented processing, the Step, Job & JobLauncher classes). The Quality of Service features are interesting as they allow you to detect job and item failures and then deal with them in one of three ways: try it again (transient), ignore it and maybe retry it later (Skippable), or mark it as needing manual intervention (Fatal).

Dave then gave a brief overview of a number of different strategies in which you can introduce multi-threaded behaviour to get your jobs done faster, these included:
  • Sequential Execution
  • Multi-threaded Step
  • Parallel Execution
  • Remote Chunking
  • Partitioning
Note: Please refer to Dave's slides for details regarding any of the above points...

Dave then gave us a little teaser with a run through of a rather useful-looking Spring Batch Administration interface, allowing you to view and manage your 'jobs' and the 'executions' of those jobs providing full details all the way down to stacktraces if the execution failed. This really did look like an extremely useful tool and one that will make Spring Batch much easier to 'sell' to management. Here are a few screenshots (kindly provided by Dave himself):




That was the official end to the evening, but SpringSource were buying the first round in the Bowling Green pub afterwards, so the majority of attendees carried on the discussions there (thanks for the beer SpringSource!).

Note: Both Cornel's and Dave's presentations can be found over on the Cake Solutions Blog.

Technorati Tags: , , , , , , , ,

Don't forget the next Manchester Spring User Group meeting!

Just to reiterate my blog post from a few weeks ago:

The next Manchester Spring User Group meetup is 11th August


I'll be there, come over and say "Hi" if you see a skinhead with glasses... ;)

Technorati Tags: , , ,

Installing Ubuntu inside Windows XP using VirtualBox

Since moving companies over a year ago I've missed my Ubuntu desktop having moved back to development on Windows. I've had a few comments that some of my old Ubuntu blog posts are now out of date and I've wanted a way to ensure that they remain 'correct'.

After discussing virtualisation with a friend I opted to install VirtualBox - an open source virtualization tool which is free and easy to get going. This blog post contains my installation notes from installing VirtualBox and then creating an Ubuntu9 virtual machine...

First I downloaded the latest version of VirtualBox (version 3.0.0) and selected the "VirtualBox 3.0.0 for Windows hosts". Then I downloaded the latest version of the Ubuntu Desktop edition.

After both of these were fully downloaded I double-clicked the VirtualBox installer and choose to install everything.

  • When the "not passed Windows Logo testing" alerts pop-up choose to "Continue anyway" then register if you wish.

  • Once it's all installed run VirtualBox and click "New" to create a new virtual machine.

  • On the "VM Name and OS Type" page I entered "Ubuntu9" as the name, and for the operating System I chose "Linux" and "Ubuntu" as the version. On the "Memory" page I chose the default option, same for the "Virtual Hard Disk" setup.

  • Within the "New Disk Wizard" I chose "dynamically expanding storage" for the "Hard Disk Storage Type".
This will have just created a new virtual server called "Ubuntu9" in a "powered off" state.
  • Right-click "Ubuntu9" and choose "Settings...":


  • Click "CD/DVD-ROM" on the left-handside, then click "Mount CD/DVD Drive", choose "ISO Image File" and click the folder icon to the right-handside:


  • The Virtual Media Manager windows appears.
    Click "Add" and browse to where the downloaded Ubuntu ISO image was saved and click "Open". Then click "Select".


  • You will now be back at the Settings window, just click "Ok"

  • Now select "Ubuntu9" and then click the "Start" button
The virtual server now starts with the Ubuntu disk image auto-mounted and boots from this image. Use the cursor keys to select your default language and then choose "Install Ubuntu".

Ubuntu will start to install and load up the Gnome based installation wizard.
  • Select your language, timezone and keyboard layout when prompted.

  • You will now be presented with the disk formatting screen - choose "SCSI1 (0,0,0) (sda) 8.6GB ATA VBOX HARDDISK"


  • Enter some user information and login details and then click the "Install" button - this was a little scary as the host box is my main PC and although I'm running the installation via the VirtualBox it's still felt strange thinking that I might be clicking to reformat my main drive with Linux...
Ubuntu will automatically install after the disk formatting is complete, this can take a while. If it gets stucks at the "checking mirrors" stage then you might have some issues with the networking setup - the Ubuntu setup wants to be able to connect to the internet. I had to change my network settings from "NAT" to "Bridged" to get it working on my system.


If everything went ok you should now now be able to un-mount the Ubuntu disk image (via the Settings option) and start up your new Ubuntu machine:


That's it you can now use Ubuntu as if it was installed as your primary OS!

Technorati Tags: , , , , ,

A great answer to the "What is Agile?" question

My friend David Draper has just posted a great response that he gave to a potential client recently in answer to the dreaded question "what, in a nutshell, does agile mean?"

Check out David's blog for his answer.

Technorati Tags: , ,

Better Java Dates, Times & Calendars with Joda-Time

Anyone who has used Java to manipulate Dates will know that it's one of the most frustrating parts of the core APIs - it should just be so easy!

As an example, here is one way to create a 'date of birth' Date - in this object we want the time part of the Date to be all zeros (midnight):

import java.util.Calendar;
import java.util.Date;

Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(2004, Calendar.JULY, 10);
Date dob = calendar.getTime();
There are a few gotchas to be aware of here, first is that you can't specify the month value as just "7" or "07" as that would give the month as August (as month 0 = January!) and the other is that without the call to clear() the time part will be set to the time when the Calendar.getInstance() was called.

Now compare this to creating a 'date of birth' Date object using Joda-Time:
import org.joda.time.DateMidnight;

Date dob = new DateMidnight(2004, 07, 10).toDate();
The DateMidnight class indicates that the time part will be zeros (more explicit than the "clear()" method) and you don't have to use any constants to build up the months.

The Joda-Time package is rammed full of useful bits like this, including instants, periods, intervals, durations, etc. as well as full calendar support and the ability to 'freeze time' (very useful for unit testing).

It's a fantastic package and should be considered a replacement for the cumbersome java.util.Calendar class.

Technorati Tags: , , , ,

The next Manchester Spring User Group meetup is 11th August

Following on from an excellent gathering in June, Guy Remond (MD of Cake Solutions) has announced the details of August's meeting:

"Introducing Spring Batch 2.0 plus Spring Framework 3.0 update" by Dave Syer:

Well known as lead committer to the Spring Batch project as well as having a major influence throughout SpringSource, Dave will be sharing insight into the use of Spring Batch, showing some demonstrations and unveiling enhancements (scalability, XML config, Java 5…) within Spring Batch 2.0. In addition he has promised some interesting thoughts on the long awaited Spring Framework 3.0.
There was a brief mention of Spring Batch at the last SUG meeting so I'm looking forward to finding out more...

Oh, don't forget to register for the August meeting over on the Spring User Group website.

Technorati Tags: , , , , ,

Supporting the Oracle XMLTYPE datatype via JPA (Spring, Hibernate & JDBC)

On a recent project I was tasked with developing two domain objects which mapped via JPA to a couple of tables. This would have been easy apart from one table used the the Oracle-specific XMLTYPE data type:

create table PERSON
(
P_ID number not null,
P_NAME varchar2(50),
P_UPDATED date,
P_XML xmltype
);
The XMLTYPE datatype is not supported by JPA (or any Hibernate-specific annotations) and so I had to use a different approach. I created the JPA-based Person class as normal, adding @Column annotations to the class, ignoring the P_XML column. I then added the following bit of code to be a placeholder for the XML:
@Transient
// required so that JPA doesn't try to persist it, we need JDBC for that
private String xml;
I then developed the JpaPersonDao as normal, using the getJpaTemplate() methods to select, insert and update the database. This handles all the columns except the XMLTYPE one - you need to use JDBC for that one due to the way in which Oracle expects the column to be filled and read.

My approach was to use the JPA-based DAO to perform most of the work loading and saving the rows, but hook in a JDBC-based DAO behind the scenes to handle the XMLTYPE column. By hiding it in the DAO, the users of the PersonDao will not have to worry about the special nature of the XMLTYPE column.

This is the JdbcPersonDao performing access to the XMLTYPE-based column only:
public class JdbcPersonDao extends JdbcDaoSupport {

private static final String SELECT_XML_SQL = "select p.P_XML.getClobVal() from PERSON p where P_ID = ?";
private static final String UPDATE_XML_SQL = "update PERSON set P_XML = xmltype(?) where P_ID = ?";

public String getXml(Integer id) {
Object[] args = { new Integer(id) };
int[] argTypes = new int[] { Types.INTEGER };
return (String) getJdbcTemplate().queryForObject(SELECT_XML_SQL, args, argTypes, String.class);
}

public void setXml(Integer id, String xml) {
OracleLobHandler lobHandler = new OracleLobHandler();
lobHandler.setNativeJdbcExtractor(new CommonsDbcpNativeJdbcExtractor());

Object[] args = { new SqlLobValue(xml, lobHandler), new Integer(id) };
int[] argTypes = new int[] { Types.CLOB, Types.INTEGER };
getJdbcTemplate().update(UPDATE_XML_SQL, args, argTypes);
}
}
And here are the important bits of the JpaPersonDao hooking into the JDBC-based one to ensure that the data stays consistent, both accesses to the database are within the same transaction and so are atomic:
public class JpaPersonDao extends JpaDaoSupport implements PersonDao {

@Autowired
private JdbcPersonDao jdbcPersonDao; // deals with the xmltype clob

public Person getPersonById(Integer id) {
Person person = getJpaTemplate().find(Person.class, id);

if (person != null) {
person.setXml(jdbcPersonDao.getXml(id));
}

return person;
}

public void savePerson(Person person) {
getJpaTemplate().persist(person);
getJpaTemplate().flush(); // forces the generation of an ID, required in the saveXml call
saveXml(person);
}

public Person updatePerson(Person person) {
// put the xml to one side as the merge clears out the transient field
String xml = person.getXml();
Person updatedPerson = getJpaTemplate().merge(person);
updatedPerson.setXml(xml);
saveXml(updatedPerson);

return updatedPerson;
}

private void saveXml(Person person) {
if (person.getXml() != null) {
jdbcPersonDao.setXml(person.getId(), person.getXml());
}
}
}
Not the most elegant solution, but at least with the use of the @Autowired JDBC-based DAO the mess is hidden from the caller...

Technorati Tags: , , , , , , ,

MP3 purchase comparison between Amazon.co.uk & Play.com

My first foray into purchasing MP3 was from Amazon.co.uk some months back. It was a smooth experience much like buying anything else from Amazon and it's quirky MP3 downloader popped the nicely named MP3 files into my music folder in the normal directory structure of Artist name/Album name/track number & name.

This week I purchased an album from Play.com's MP3 catalogue due to it being a little cheap than Amazon. It's download format was a large zip file that had to be saved to the desktop, it's content was just the tracks - no artist/album directory structure, no track numbers. Because I don't have an iPod I had to look up the track listing on the net and rename the files just to put them in the right album order!

Next time I want to buy some music online I think I will be skipping Play.com's offering completely and paying the little more that Amazon.co.uk was charging - it will be worth it to just have my music just download straight into the right place rather than messing around with zip file and renames...

Technorati Tags: , , ,

A new way to label in GMail (and the end of Right-Sided Labels)

Back in March I blogged about my favourite GMail labs. One of them has died today - Right-side Labels.

Google are grouping labels together with Inbox, Drafts, Chats and other system labels, and so putting the labels over on the right-hand side doesn't make sense anymore.

The problem is, my GMail's not been updated yet so I can't play with the new features! :)

Technorati Tags: , , ,

Be careful writing hashCode() methods when using HashCodeBuilder

I've blogged in the past about using the Apache Commons EqualsBuilder and HashCodeBuilder to write simpler equals() & hashCode() methods.

My colleague recently blogged about a potential pitfall when using this approach, I'll summarise his findings here:

Be VERY careful when you ask the HashCodeBuilder to generate the resulting hashcode value:

Make sure you call builder.toHashCode() rather than builder.hashCode()

The first correctly generates a hashcode value based on the objects that you have added to the builder, the second gives you the hashcode of the builder object itself - definitely not the value you would be expecting (and would be a sure fire way to lose your objects in a Collection)...

Technorati Tags: , , , ,

How to escape text when pasting into Eclipse (including XML)

When you paste text into Eclipse it does just that - places where the cursor is in it's full un-altered original form. This is fine most of the time apart from when you might want to copy a chunk of XML (or a similar large body of text). What you end up with in this case is the text pasted in with red lines everywhere because the text hasn't been properly escaped for Java code.

To enable escaping of pasted text open the Preferences panel ('Window' menu -> 'Preferences...' option), then choose: 'Java' -> 'Editor' -> 'Typing' and tick the box which says "Escape text when pasting in a string literal":


Now whenever you post in text which is broken over multiple lines, Eclipse will insert the relevant quotes of Java to make Eclipse happy.

Technorati Tags: , , , , ,

Summary of June's Manchester Spring User Group Meeting

I missed the first Manchester Spring User Group meeting back in April which I heard was excellent so I made sure I didn't miss June's meeting.

The sessions (based at the University of Manchester Core Technology Facility - cool building BTW) were organised by Cake Solutions (in particular their MD Guy Remond) and it was Guy that introduced the evening and laid out the agenda. Just a quick note about the venue, it's a very new tidy building, the room was an excellent size (seating for 50+ people) and coffee (and cake!) were provided. Parking was free and immediately outside the building, just press the buzzer and mention the Spring User Group...

The first talk was by Paul Sweby (of CapGemini) entitled:

Spring in Government - Improving System & Personal Performance

Paul works on the HM Revenue & Customs website and started his talk by providing some pretty impressive statistics: around 40 million tax payers use the HMRC web site for various purposes. The software is developed by CapGemini, the systems integration provided by Fujitsu, with BT providing the network connectivity.

Previous versions were composed of a mixture of COBOL, Java and .Net, and since 2000 it was predominately Java with stateless sessions beans and the facade pattern.

Since then this has been ripped out and replaced with Spring. It's now made up of the following software technologies: Spring 2.0, Hibernate 3.2, Apache Commons, Drools 4, and the following supporting components: F5 BigIP, Apache, WebLogic, Oracle 10g (with RAC)

Here are the notes that I was able to capture as Paul described some of the key points to being able to build such a large scale application:

  • Minimal use of JavaScript to ensure widest reach and browser compatibility
  • Uses REST extensively - will be migrating to Spring 3.0's REST support
  • Strictly one business call per request
  • The HTTP session is bad, difficult & expensive to replicate, compromises the compliance of the browsers navigation features (back button)
  • Minimal shared user data is maintained (around 2k) this is passed around between servers either via the database or sometimes as hidden fields on the page
  • Because of the above the pages are all bookmarkable
  • Careful planning of the URLs is important due to the use of REST and the exposure of data and services as 'resources'
  • Using CruiseControl (and possibly Hudson) for continuous integration
  • The used agile 'by stealth', test first development and 'barely enough' modelling
Future plans include:
  • Increased use of Spring Batch
  • Migration from Spring 2 to Spring 3 (remove the concrete inheritance of the controllers)
  • Add support for 'Web 2.0' components
The Spring-based system described above was able to deal with 400,000 filings on the last allowed day (Jan 30th) with 40,000 submissions filed in the last hour alone! For the tax year of 2008/2009 over 5.8 million tax returns were filed, with a saving to the government of £20 million. Pretty impressive stuff!

There was a little break which contained a mention of the Manchester Spring User Group sponsors: UMIC, Hays IT, Skills Matter, SpringSource & Cake Solutions and a mention about a new open source portal/forum/community site called OpenSource-Central.

The next talk was by Russ Miles (author and MD of OpenCredo amongst other things) and his talk was:

Grails Eye for the Spring Guy

Grails is an "open-source web application framework that leverages the Groovy language and complements Java Web development". It aims to make you more productive by providing a natural process from idea to concrete solution. It follows the 'convention over configuration' approach giving you an opinionated 'right way' of doing things - this is helpful in that fact that if you follow it's way of doing things you end up doing your work in less time, it's taken care of a lot of the mundane and background tasks for you.

After Russ explained some of the core ideas behind Grails, he then proceeded for the rest of the presentation to build a simple web application from scratch using Grails. He started by asking Grails to create the basic project structure: grails create-app and then followed by explaining some of the directory structure.

Without writing any code he then started his web application: grails run-app and navigated to a simple start page in his browser - the basic guts of getting a running application was done for you. He then created a domain class using the built-in Groovy scripts to create various types of artefacts, this auto-created an appropriate controller and a number of views suitable for simple CRUD operations. The controller doesn't have normal methods for the CRUD operations, it has 'closures' - methods which are assigned to properties and so can be passed around like variables.
Without writing any database code he re-ran the web app and added a new domain object which was then displayed in a resulting list - Grails had created a development database using HSQLDB and mapped the domain object to a backing table created when the web-application started up.

Grails plugins were mentioned next, it appears that most non-core functionality will be released as plugins which can cover the full technology stack from raw Spring access all the way up through controllers and domain objects up to the views. It's with the use of plugins that new 'conventions' can be introduced enriching the Grails world - one example of this was the quartz plugin - this provided some new commands including grails create-job. Other useful plugins included jsecurity, springws and yui.

He also dived a little into the world of Groovy showing that it's a smooth learning curve from Java to Groovy - you can write normal Java in a .groovy file and the Groovy interpreter/compiler understands it. Groovy also follows the same path as some of the other dynamic languages in that it has a 'metaobject protocol' (MOP) allowing the application to add functionality to objects and classes at runtime.

From my point of view, having done some Ruby and Rails development in the past, was that Grails appears to be a port of Rails to the Groovy language, taking the same ethos that 'convention of configuration' and simplicity are best. That's not to say that I don't see vast benefit in Grails just that I didn't see any new 'magic' being presented. One great advantage of Grails is the fact that it's underlying language (Groovy) is Java-based and runs (and compiles down to) standard Java which runs in the JVM. This allows a much smoother transition for Java developers to migration to something like Grails rather than learn Ruby and then figure out how to deploy Rails - quite different than dropping WAR files into Tomcat...

Guy concluded the evening with a little prize draw and then it was off to the local pub for some beers provided by Arie Chapman of SpringSource, cheers Arie!

UPDATE: Russ Miles has kindly uploaded his slides to his blog

Technorati Tags: , , , , , , , , , , , ,

Improving slow wifi bandwidth performance on an Acer Aspire One

We've noticed over the past few days that it was taking a long time to download stuff on our Acer Aspire One. Tonight I found out that it was only slow when it was unplugged from the mains - so it's a power-saving 'feature'. I couldn't find any options within the power saving section of Windows control panel, so it was off to google for some help.

Within seconds I found the perfect solution explained very clearly over on Peve's Blog. I'm not going to repeat his instructions as he explains it great already so head over there to read his post entitled Acer Aspire One Slow Wifi - Thanks Peve!

Technorati Tags: , , , ,

How to copy recorded TV programmes off your PVR (Humax 9200T)

We have had a Humax 9200T PVR for quite some time now and occasionally we have wanted a more portable copy (think DVD) of a particular programme that we have recorded.


If you flip down the right-hand panel you will notice an unlabelled standard USB B socket. It's by the use of this socket that you can stream recorded programmes off the Humax and onto a PC ready for converting to a DVD (or just watching on the PC).


Here's how you do it:

Visit Humax's support site and download & install their rather old and flaky Media E-Linker software (Click the "Media E-Linker software (Version 2.5) download link).

Get a regular USB lead with an 'A' type plug on one end, and a 'B' type plug on the other. Plug the 'B' end into the Humax, and the 'A' into any USB socket on your PC. Your PC should now 'find' the Humax and request to install the drivers, I let mine 'auto-search' and it found and installed the drivers just fine (I think they also might be packaged in the Humax E-Linker software installation).

Once the Humax is correctly attached, run the E-Linker software and choose to 'connect'. If everything is successful you be given a file listing on the righthand side - probably giving you options of Pictures & MP3. Change the drive letter in the drop-down box on the top-right and you should now see a listing of all your recorded programs.

Select the one that you want to transfer and click the button in the middle with an arrow pointing from right to left. Now the tricky part: wait, and wait, and wait, etc. On my rather old laptop (with USB1.1 I might add) it took over 24 hours to transfer a two hour program. It may be quicker with a USB2.0 PC but I had problems getting our Acer Aspire One to connect to the Humax correctly.

Once the transfer has completed you will be left with the program as a ".ts" file - this is an MPEG2 file but with "transport stream" encoding, exactly the same format as the file came over the air to your Humax in the first place. Many players and DVD burning software know how to deal with this format, but if not you can simply convert it to a regular MPEG2 video file with something like HDTVtoMPEG2


Technorati Tags: , ,

The Spring User Group comes back to Manchester on June 15th

Back in March I blogged about the first North West Spring User Group meeting. Well on the 15th June they are coming back to Manchester. I wasn't able to attend the last one but an old colleague Bill Comer attended the session.

June's session is on "Grails eye for the Spring guy" by Russ Miles (MD of OpenCredo). Russ has also blogged about the future talk over on his blog. It sounds good and I'm planning on attending this time so if you see me there come over and say hi!

Technorati Tags: , , , , , ,

Replace your broadband provider's DNS servers with OpenDNS ones for more reliable service

I had an 'internet issue' last week when around 10am my connection to the internet was lost. Well not completely lost - my work PC (a remote box accessed via VPN) was still working fine so I still had a connection (at an IP level), but I couldn't visit any websites. The problem was that Pipex's DNS servers were offline (I couldn't ping them) and it wasn't planned maintenance.

So I replace them with settings for the free OpenDNS servers. These DNS servers are used by millions of people around the world, I suppose I've not migrated to them before because I've not had an issue until now. The migration couldn't have been easier - I logged into my router, accessed the 'internet settings' menu option, and selected 'DNS'. Then I unticked the "Automatic from ISP" box and entered the OpenDNS server details in the IP address boxes:


The OpenDNS DNS server IP addresses are:

Primary   DNS Server: 208.67.222.222
Secondary DNS Server: 208.67.220.220
Once my router had restarted itself with these DNS settings I was back online again...

More detailed setup instructions can be found on the OpenDNS site.

Technorati Tags: , , , ,

JSTL date comparisons with the current time (now) in JSPs

When you are coding JSPs and using the JSTL tags you will often be presenting information captured in a domain object, using the JavaBean-style getters to pull out the values within the JSP page.

What do you do if you need to show some text if the date stored within the domain object is before (or after) the current time?

There are many wrong or messy solutions - polluting the domain object by adding a method to 'get' the text to display, do the comparison in the controller and add the text to display to the request, etc.

One clean way is to use the jsp:useBean tag to create a page-scoped variable containing the current date/time and then use normal JSTL to compare the objects.

First create the page-scoped java.util.Date object (using jsp:useBean), then use ${now} to reference the current date/time. This is a regular JSP object now and so the normal JSTL operators work with this variable:

<jsp:useBean id="now" class="java.util.Date"/>

<c:if test="${someEvent.startDate lt now}">
It's history!
</c:if>
Technorati Tags: , , , , ,

Acer Aspire One: Backing up the hidden Windows XP factory image partition

My wife recently got the Windows XP 160GB version of the amazing popular Acer Aspire One (this seems to be the only netbook people ever have!).

I'd heard from a friend that we should save off the backup image which is preloaded onto a hidden partition (called PQSERVICE). But how do you gain access to the partition in order to save it off?

After much research I came up with the following options:

  • Install Linux on a USB pendrive, boot from that, then save the partition using Linux tools
  • Hack the master boot record to remove the 'hidden' attribute of the partition, then save it somehow
  • Numerous other tough/dangerous/involved methods
  • Follow my method below which is easy, safe and free!
Here are the steps you need to follow to be able to save off a backup image of the factory install of your Acer Aspire One as well as save a copy of your Master Boot Record (MBR) incase your hard drive dies...

Saving your hidden PQSERVICE partition

Download the free version of Macrium Reflect and install it

Run Macrium Reflect, let it analyse your drive and then right-click on the listed PQSERVICE partition (it's not hidden to this tool!):


Choose the "Create Image of '1 - PQSERVICE'" option

Save the partition to wherever is suitable, I place mine directly on my NAS storage box (I selected the "Intelligent Copy" option rather than the sector by sector copy, but I've not restored the image so please don't rely on that advice for a safe copy...).

An image of your hidden WinXP partition will now be saved:


Saving your Master Boot Record (MBR)

You will also probably want to save off the master boot record of the Acer's drive so that in the case of a complete drive failure you can set it up in a similar manner to the factory settings to be able to restore it correctly.

Download the free MBRWizard and extract the archive

Open a DOS box, navigate to where you extracted MBRWiz.exe and run the following command:
MBRWiz /Save=C:\acer_aspire_one.mbr
Copy the acer_aspire_one.mbr file in your C drive to somewhere safe (I put mine in the same place on the NAS box as the above PQSERVICE partition image file.

That's it!

Note: I've not restored this partition or master boot record, and I don't expect to, but at least you have a copy without messing about with your new netbook too much!

All this information was gleamed from The Importance of Backing Up EISA Hidden PQSERVICE Partition and MBR on a New Laptop (includes details on how to view the contents of the backed up image) and 5 Free Tools to Backup and Restore Master Boot Record (MBR) from the fantastic Raymond.cc blog. They go into much more detail and I would recommend that you give them both a good read.

UPDATE: This blog post looks like a good source of information if you want to Restore XP from the Acer Aspire One Hidden Partition.

Technorati Tags: , , , , , , , , ,

Easy, collaborative web UI mockups with Balsamiq

Every now and again you come across a tool that is so easy to understand, so fast to use and so effective at conveying it's ideas that you just have to tell people about it. One such tool is Mockups by Balsamic.

It's a web page mockup drawing tool written using Adobe Air which provides a palette of HTML widgets with which to 'draw' your screens. It has a querky 'freehand' style which lends itself to conveying the components and ideas that a web page should have without forcing the designer to code it up in HTML (or for the customer to think that because the HTML is done, the app must nearly be ready...).

Here is a very simple web page for search and listing users which I 'mocked up' in less than 10 minutes:
As you can see it's got a number of standard HTML widgets on it as well as a very useful 'post it' note allowing you to add distinctive notes and comments to the mockups themselves. So this in itself is enough to warrant using it to create all the screenshots that you might need which trying to show a customer what their site might look like, but...

The best feature about this tool is that it's so easy to understand and control that people are happy to start adding and editing stuff within five minutes of seeing the tool:

I used it recently during a teleconference to try and show a couple of remote attendees what my ideas were about our new project. We were each sat at our desks (in different offices) with headsets on (talking to each other) and other two people 'remote desktop'ed (via VNC) to my machine. I was then able to show them my ideas and also start to perform live edits to the mockups as the meeting progressed.

After about five minutes one attendee said "here, let me try..." and that was it, for the rest of the hour-long meeting all three of us were taking it in turns to control the mouse and keyboard and refine the mockups.
It was one of the most collaborative remote sessions I have ever done - because Balsamiq Mockups is so intuitive to use it was a doddle to get people to start to use it. Also because you can directly export the mockups to images it's easy to include them in just about any type of document or system that you have.

This is an excellent tool, and cheap as well!

Oh, and if the standard widgets contained in Balsamiq Mockups aren't enough, there is an ever-growing collection of user-contributed widgets over on the Mockups To Go site, a great example packed with widgets is Various Web Page Widgets.

Technorati Tags: , , , , ,

JSTL 'forEach' looping tricks using varStatus

Do you have a JSTL forEach loop in your JSP page displaying a list of results? Have you ever wanted to do something different for each row, or maybe do something for all but the last row?

varStatus is what you want!

You declare a new variable within the main forEach JSP block which will allow you to access the internal loop counter of the for-each loop. Then you can call a number of methods on that object to be able to do conditional processing.

The code example below will display a horizontal rule under each item apart from the very last one:

<c:forEach var="thing" items="${things}" varStatus="status">

<a href="${thing.link}">${thing.description}</a>

${not status.last ? '<hr/>' : ''}

</c:forEach>
The important bits of the above snippet are the varStatus="status" and status.last. The first one defines a 'status' variable, and the second one accesses it to ask if this row is the 'last'.

The status object has a number of useful methods:

current, index, count, first, last, begin, step, end

Technorati Tags: , , ,