Friday, 18 January 2008

Database testdata

Whenever I try out a new framework, library or tool that uses a database, I need some data to run it on. Nothing too big, but not too small either. I've been thinking about how to create some useful testdata for ages. Yesterday I had the idea of using artist/album/song data from freedb. I downloaded a few updates to avoid a huge download of the whole database, selected a few artists and wrote a Python parser to create SQL insert statements. The resulting database is here for anyone who might find it useful. It contains 18 artists, 49 albums and 529 songs.

album-data-h2.jar.gz -- about 20k, a gzipped tar file containing an H2 database.

The individual SQL files are available if you want to use the data to populate something other than H2. You may need to modify the files to suite your database's SQL dialect.

album-sql.tar.gz -- about 11k, a gzipped tar file containing the schema creation and database population SQL. You will need to load the tables in the proper order to prevent foreign key violations: genres, artists, albums and finally tracks.

Use these at your own risk -- no guarantee implied or offered.

The freedb data is licensed under the GPL.

Friday, 11 January 2008

Add a jar file to Java load path at run time

Sometimes it is necessary to amend the class load path at run time. For example, dynamically adding jar files containing user-configurable JDBC data sources. The way this is done is truly monstrous -- the URL Path format was only revealed when a colleague looked into the Java library sources. Here is a simple example of how this is done jar-loader-src-0.1.jar which, as usual, has an ant build file: just type "ant run" at the shell prompt to compile and run it. You need ant and JDK >= 1.5 for this.

Checking if a JEditorPane has been edited (changed)

While I was looking for a way to check if a JEditorPane's text had been changed since the last save, I found a site that actually wanted me to pay for the answer. Bloody cheek. It isn't that tough, but it took a bit of reading. All that is needed is to install a DocumentListener into the editor pane's document. You can download a complete example swing-editor-src-0.1.jar which includes an ant build file. Just type "ant run" at the shell prompt to run it. You will need ant and JDK >= 1.5 (it may work in older JDKs, but I used 1.5 so I can't be sure).

The document can't tell when your program has saved the document (ie, it is no longer "dirty"), so you need to call setDirty(false) after a save.

Very short book review: JPA 101 Java Persistence Explained

This is the third JPA book I tried and the first which actually told me what I wanted to know quickly and clearly. If, like me, you are impatient and want to know how to use the excellent Java Persistence API, I highly recommend this book. It can be downloaded from SourceBeat. You can also order an on-demand printed copy. Being impatient, I went for the download version although I still think technology has a very long way to go before it can replace dead trees as the best way to delivery reading material.

Java Swing JButton keyboard shortcuts

It took ages to work out how to do this, so I decided to post it here in the hope someone else will benefit. Here's how to install a keyboard shortcut to a a Swing JButton so the button behaves as though it was clicked when the key is pressed:

JButton saveButton = new JButton(new SaveAction());
InputMap inputMap = saveButton.getInputMap(JButton.WHEN_IN_FOCUSED_WINDOW);
KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
inputMap.put(enter, "ENTER");
saveButton.getActionMap().put("ENTER", new ClickAction(saveButton));

...

public class ClickAction extends AbstractAction {
private JButton button;

public ClickAction(JButton button) {
this.button = button;
}

public void actionPerformed(ActionEvent e) {
button.doClick();
}
}

A complete example is in shortcut-buttons-src-0.1.jar. The download includes an ant build file. To compile and run, just type "ant run" at the shell prompt. You will need ant and a JDK >= 1.5 installed.

Monday, 3 September 2007

xmlbeans for the impatient

I've been looking at xmlbeans today. There is a fairly steep initial learning curve, then it gets very easy and amazingly impressive. It really is a very wonderful library which will save you a lot of time and code if you every read and write XML files.

There is an introduction at Apache which is either buggy or out of date. Luckily, a colleague who knows the library well was on hand to point me in the right direction. I have packaged up a modified and extended version of the Apache introduction and put the jar here for anyone who want to get started with no reading whatsoever. The jar includes an ant build file. The default ant target will compile everything and run the 'print' example. There are also targets 'add-item' and 'save-order' run two more examples.

After extracting the jar, you will need to cd into the xmlbeans directory, make the 'lib' directory and copy these files into it:

asm.jar
jsr_api.jar
resolver.jar
saxon8.jar
xbean.jar
xbean_xpath.jar
xmlbeans-qname-2.3.0.jar
xmlpublic.jar

You will need to read the xmlbeans install guide to find these files.

Monday, 13 August 2007

Managing ant dependencies

We tried several packages to manage ant build dependencies. Antlion looked useful, but the documentation was dreadful and we never worked out if it would do what we wanted or not. Ivy looked useful at first, but it didn't really do the dependency management we wanted. We even looked at Maven. Stone me that is complicated, and even in version 2, too full of bugs to be useful. I wasted two days on that before giving up in despair and returning to ant.

My colleague Jon Siddle decided to write his own ant dependency manager which he has called decorum. It does just enough dependency management -- it doesn't download stuff from ibiblio, but it does know about other ant projects in the same file system and will build them if their targets are out of date. I works very well in a project with many sibling sub-projects. It also builds the path refs for the compile and test targets. And it handles external jars (which we don't usually build) nicely as well.

Here's a simple example: say my project needs log4j. All I need to do it put these lines in my build.xml:

<taskdef name="dependencies" classname="org.trapdoor.decorum.Decorum">
<classpath location="${lib.dir}/decorum-0.2.jar" />
</taskdef>

This tells ant to add Decorum's task definition. Now I can add dependencies entries to my build.xml:
<dependencies id="main" libdir="${lib.dir}" excludes="clean">
<dependency name="log4j" />
</dependencies>
When I use the generated path in my compile target, it will find the most recent version of log4j in the library directory:
<target name="compile" depends="init">
<javac srcdir="${src.dir}/main/java" destdir="${build.dir}/main/classes"
includes="**/*.java" classpathref="path.main">
In this example "path.main" refers back to the id I gave my dependencies.

Here is a complete [FILE REMOVED -- I no longer use decorum] example with minimal decorum dependencies. In my next post I will illustrate some of the more advanced features like version and building.