First Experiences with CruiseControl

After reading Mike Clark’s amazing book on Automation, I’ve been pumped to take a look at Continuous integration with CruiseControl. We’ve been using Anthill for our build process, so that’ll give me a benchmark to compare.

First of all, my experience with Anthill has been pretty sensational. Its got a very smick UI and seems to work pretty well as spec’d on the tin. The install is a matter of dragging the war file into your webserver, and (mostly) using the web ui to configure the rest. Little bit of commandline CVS stuff for your project by hand, but largely pretty much “just works” - so bit kudos to those guys.

CruiseControl is a little more work for your result. There are xml config files to build and edit, there are cvs commandline things to do to get your directories setup (if you don’t want to hardcode passwords, etc). But you a rewarded with abuntant power for your investment. The doco is solid, and if you follow the worked example you’ll stay mostly out of trouble.

To capture some of the dramas I had: (all of which were resolved with the latest FAQ)

Overall I’d say that, on first impressions, CC seems a lot more powerful than Anthill. The GUI definitely isn’t as nice, but the power is pretty unbelievable.

As a straight nightly build system, I’d probably go with Anthill (since it’s a snap to install and very easy to learn for developes). But for raw power, there’s something very flexible about cruisecontrol. One feature that I love is the ability to see who has done commits since the last automated build. Great for identifying “you broke the build” candidates, who, at the current site I’m at, need to put a $1 in a jar.

More impressions once we’ve given cruise a bit more of a workout, but definitely worth a look if you’ve been thinking about setting up a continuous build process.

[Read More]

My Favorite Developer Book of 2004

And it’s not about software development…. directly… but it has helped my productivity more than any other title I’ve read in my career.

It’s called Take Back Your Life and it’s a book on using Outlook to get your world it order. Don’t be put off by the Outlook thing, the ideas work in any software package that offers categorised tasks, calendar and contacts, so Evolution would work great too.

The ideas in this book have, quite honestly, changed my entire thinking about getting organised and staying organised. What gets me is that the thing is so readable, and so practical. Some of the ideas that really shifted me were:

  • To-Dos without Dependencies: Instead of putting incredibly broad items in your lists, make sure ever item has no dependencies. Don’t write “Fix lightbulb”, write “Purchase 75W Bulb at Hardware”.
  • Categorise by Place: Categorise the items in your todo list by the place where you actually do them! All my “online” stuff goes together, all my “desk” stuff goes together, all my “call people” stuff goes together. It saves stacks of time.
  • Turn off the ding: It’s not realistic to respond to all emails within 5 minutes. So turn off the popup ding. Do your email once or twice a day. If you get email after 5, and then reply at 9 the following morning, they’re waiting 16 hours already. So why not formalise and make sure that people get a response once a day. You’ll get more work done, and you’ll get more respect from them. Ditto for your phone, turn it off and give yourself some blocks of hours to get “in the zone”.* Collection points: Most of us have around 25 collection points in our life - places we keep incoming information and notes. Multiple inboxes, voicemail boxes, sticky notes, notebooks from design meeting, bits of paper that we leave on the dining room table, you name it. The biggest of all is our head. The thing about your head is that all that stuff you cram in and seem to forget about goes into your subconscious and comes back to you when there’s space. Normally at 2AM in the morning. So instead of 25 collection points narrow it a half dozen. Everything actionable in my world goes into “Categories: None” - the Outlook “catch all” category. It stays here till I categorise it (by location, you’ll recall). These days, with the PDA around me most of the time, my recall is pretty much 100%. It all get captured. And in a single place. Even emails that require action get dragged there, so my inbox is no longer my “todo” list.

I’ve been at “the program” for around 5 months and I’m still loving it. This one essential developer resource, and, for mine, the book that has most helped me improve my software delivery in 2004. Recommended.

[Read More]

The shocking truth about ejbRemove()

ejbRemove() doesn’t always get called, at least on WebSphere 5.0. Well… it’s shocking truth to me, but probably to none of you guys, and I’m not sure that it even should. I don’t know why I assumed that it did, it just seemed that it would given that it’s a lifecycle method.

I’ve been using a strategy where I register a JMX object in ejbCreate() and unregister it in ejbRemove(). Seemed pretty reasonable thing to do…. until I found all these lingering JMX objects without matching EJBs. Hmmm… A little bit of googling and there you go:

_

A session bean can miss a call to ejbRemove() if there is a container crash or the bean throws a runtime exception. Source: HF-EJB 221 (HF refers to Head First EJB by Bert Bates and Kathy Sierra)

_

Bugger. Now I wrap the body of each exposed interface method with a catch block for Runtime Exceptions, release my resources, then rethrow the exception. I ain’t pretty, but it’s more reliable.

[Read More]

I've written my last Swing app... (SWT is *so* the business...)

I’ve spent the last month getting to know SWT, and I’ve gotta say that I’ve written my last Swing app. After spending far too long messing with Swing MVC pattern and writing modeller code for my damn combo boxes, that’s it. I’ve had it. I’ve come to the conclusion that I’m just not smart enough to grok Swing.

But I was still missing a decent sized SWT app that would prove me to that humans could write SWT apps and that I could model off for my own mid-sized project. Then I had a good look at the source to RSSOwl - one very funky SWT RSS Reader - and I’m really starting to get a feel for SWT. Full kudos to those guys for putting together a very spunky app with a very nice source structure. One that I can pick up after a little digging and that looks very maintainable.

Booned to know that this thing looks good in the large, and to get a feel for SWT in the small, I ported a small Swing utility app that does some crypto stuff. It’s got a combo, couple of buttons, and couple of text fields to hold the input and output text. Total port time: 1.5 hours. In the process I managed to dump the two third party libs I was using to make the thing look good (JGoodies forms and JGoodies looks).

I initially did the layout with the SWT FormsLayout, and later made the switch to a straight SWT GridLayout since the overhead of layout data for FormsLayout was starting to urg me (and the layout was a simple grid anyways, really). The app was snappier to start up (half the time of the swing app on JDK 1.4.2 on Win32), and best of all looks completely native. Ran it through exe4j to get a nice little binary launcher and I was in business.

The only dramas I had was getting the form icon to look right (there still seems to be some issues with PNG transparency and SWT on Windows, and I couldn’t really be bothered converting things to GIFs so I’m just living with it).

So my take is that I’m ditching Swing and running with SWT for all further GUI jobs. The Layout managers are great, the widgets are native (and have simple APIs that I could use mainly from autocomplete), and the doco is abundant.

More info here when my experience grows, and my mid-sized project gets the facelift that I’ve been putting off. I gotta say, though, after my first experiences of a small port, SWT just gets me excited about the desktop again!

[Read More]

Writing Maintainable Swing Apps?

In the heart of writing a moderate sided Swing app at the moment, and it’s a jungle in there. You’ve got Panels, Models, Frames, Event Handlers, Actions. It’s easy to get into trouble quickly.

All that stuff is pretty straightforward in a small forms based app. But when you add a stack of complex panels and models things start getting very busy. Has anyone read any good articles on writing maintainable swing apps? Or has worked on any moderate sized swing apps and has some good battle-tested tips to share?

My latest thinking is to explore IoC frameworks like Spring to see if I can externalise a lot of the magic to an understandable XML file (eg the Actions would becoming much cleaner rather than manually injecting their related panels/models/or whatever from some other code deeply nested inside a Panel class somewhere). Even the Panel creation logic would probably become a little cleaner.

Interested to hear ideas from people who’ve walking this scary road.

[Read More]

Versioning Jars with JReleaseInfo

You use CVS and tag your stuff every release right? But it can be a pain for your clients to get at your version info in your jar file once it’s out there in the wild.

I’ve tried a couple of ways. You can use jar manifest entries for Implementation-Version or you can call your jar myjar-1.2.3.jar. The former is not very accessible for clients to get to, the later can be a pain for clients since they can’t just drop in the new jar as a replacement cause their IDE may barf. I’ve found neither is ideal.

I’ve recently come across JReleaseInfo which seems to be a nice little solution. This little bad boy runs as an Ant task, and embeds your specified version info along with a tiny Swing viewer right inside your jar. Add a Main-Class entry to your jar Manifest, and you’ve got yourself a self-executing jar that displays a nice GUI deal with all your vital signs. Check out the grab on their site.

Looks like holding a lot of promise. Doesn’t support commandline output at the moment (which would be nice for Unix boxes that you’ve only got ssh to), but I’ve submitted a feature request and the boys think it could be doable. Check out the screen grabs. It’s pretty impressive, and clients just love double clicking on stuff. Elegant.

[Read More]

UML for Java Programmers

Been putting together some UML for developer docs and I’ve gotta say that UML For Java Programmers is one very cool book. I’ve never really grokked UML, so it’s been pretty hard work going at any of the more hardcore texts.

The neat thing about this book is that it lets you reverse engineer. It gives you some simple sample Java code using some common coding idiom, like classes which contain a Collection of some other class, and gives you the diagram that matches the code.

The other thing I really like about this book is its “real worldliness”. Plenty of solid advice on when NOT to diagram (eg. cause you feel guilty for not using UML is NOT a good reason! If the pic doesn’t add value to anyone, why are you doing it?)

It remains the only UML book that I continue to open. Great stuff.

Can I add one more plug for Aussie company Sparx Systems who put out one kickin UML tool for very sane dollars. Enterprise Architect is my tool of choice for UML these days, and it’s the only tool I’ve used that I don’t have to spend hours with getting the lines to layout properly. Great stuff, guys!

[Read More]

First Pocket PC SWT App

After having a good read of A Small Cup of SWT, I’ve decided to test out one of the sample apps to see what’s doable. The good news is that it’s all very doable! Look at the nativeness of this:

My First SWT Pocket PC app

After paying my $US5.99, and downloading 80Mb IBM’s J9 Runtime from Handago I was in business. Setup Eclipse to use the J9 as it’s runtime so I could check I was only using the right subset of java.*, downloading the pocket pc SWT from the Eclipse site (I used the J2SE version of the Pocket PC stuff to get maximum capability).

Compiled up my sample class (HelloSWT.class) on the PC, then copied the .class file to my device. The only magic required was to create the Hello.lnk file per the FAQ. The spaces in the paths needed some sorting, so I ended up with some interesting quoting (and what’s the leading 68# for? A filetype thingy?):

68#"Program FilesJ9PPRO10binj9w.exe" -jcl:ppro10
   -cp "My DocumentsJavaswt.jar;My DocumentsJava"
   HelloSWT

and I was in business. Haven’t worked out how to change the icon yet to something non-IBM, but still, it’s working!

Big thanks to Vik for tipping me off on J9.

BTW, if you need a free Screen Capture app for Pocket PC, I can recommend Pocket Screen Capture v1.0 from cetoolbox.com. Good stuff - you just need to make sure you can set up your screen grab in the five seconds they give you to get ready!

[Read More]

PocketPC JVM Options

In my endless quest for some kinda JVM for my Ipaq 1940, I’ve come across two new contenders (and found out more about a third):

  • Creme - which I’ve downloaded and successfully installed an eval of (I’m waiting to here back pricing); and
  • Jeode for Dell Axim - which, despite what the Handago page says, apparently runs on PocketPC 2003s of most varieties. Retails for around $50. Apparently Sun have some licence agreement with Esmertec that stops them selling their VM to anyone but Device OEMs, hence the work around
  • Websphere Studio Device Developer - which, after endless browsing on the IBM site, appears to retail for around $600. Which is pretty hefty to just get a JVM (it’s bundled with a whole WSAD Style IDE, hence the big ticket).

Anyone running any of these bad boys on their own Ipaq’s? Be interested to hear your experienced. Now that I’ve started playing with SWT, I’m keen to run an SWT app on my PocketPC. How cool would that be!!

[Read More]

Starting to learn SWT

I’ve started reading The Definitive Guide to SWT and JFace in an effort to get a feel for SWT programming. The first impressions have been pretty good. The widget set is awesome, can’t wait to get me some CoolBar action!

It’s kinda weird seeing a main routine with a standard Windows-like message pump. Takes me back to my Win32 days. And the need to free non-contained resources is a probably going to be a bit of a pain. But the payback is a true native look and feel, and the option to use GCJ to generate a native binary. Baby!

Anyways, the book is definitely a good read. Seems to have pretty comprehensive coverage of the libraries and a good helping of practical advice. I’ve just finished the chapter on layout managers, and I’m missing JGoodies Forms already. Fortunately, there’s an SWT Port of Forms. Gotta check it out. I love that layout manager.

[Read More]

Running Jetty on Linux

Old news to hard-core Jetty users, but I’ve only just discovered /bin/jetty.sh in the jetty-all distro. This neat little shell script lets you manage all sorts of Jetty goodness straight from the command line including start, stop, restart and check (jar paths, home dirs, etc).

I’ve previously been doing dodgy stuff with:

    java -jar start.jar &

from the command line and have been having all sorts of unexpected results over time. I’m hoping this slick little script is going to help me out.

In another hot tip, I found that creating a “work” directory in my $JETTY_HOME will tell Jetty to put temp files there rather than in /tmp. The problem with /tmp is that it may get swept by cron jobs every so often - causing your web apps to crash and burn. It’s in the FAQ, but I hadn’t come across it before.

In yet other news, today’s outage was due to a botched upgrade to Jetty 5. Having all sorts of problems running Pebble on 5 (some related to commons logging clashes, but others related to straight page compilation). I’m going to do some more testing on my local PC before attempting another deploy. For now, I’m sticking with 4.2.x (I know, where’s my sense of adventure?).

[Read More]

JMX Console Recommendations?

I’ve been playing with mc4j to see if I can get a decent JMX console that works with Websphere 5.1, and it’s a great little app. I’ve been playing with beta 5 (apparently 6 is out), and the version I’m playing with certainly has some negs, so I’m keen for when this one gets out of beta. My issues so far:

  • Custom installer (I’d much rather just unzip)
  • Mega-buggy GUI (slow, and keeps crashing)
  • Binary config file (if it was XML or text I could fix the classpath entries required to get to my app server working cause the GUI crashes if you try and change them after completing the “New Connection” wizard.)
  • Did I mention it’s very slow?

But all that said it’s got a cool little GUI with nice grouping of attributes and some cool dynamic refresh options. Overall, but for the tricky config, it’s a very handle little tool!

So, anyone got any other recommendations for JMX consoles they have had success with? I’d love to get one hosted as a WSAD/Eclipse plugin, but whatever.

[Read More]

JMX + JBoss + Commons Modeler = Baby!

Ok. I’m extremely pumped. I’ve just used commons modeler to deploy an MBean to JBoss and it’s actually working! Commons Modeler makes JMX so incredibly simple compared to doing this stuff by hand, that I had to see the thing running before I believed it.

Now, JBoss has its own way of deploying MBeans via a declaritive XML mechanism, which is cool, but I’m after something that I can play with on JBoss then deploy on Websphere, so portable APIs work for me.

I’ve been playing around with Commons Modeler after reading the early review copy of Manning’s Jakarta Commons In Action (top book!), but the examples show creating your own Http Adaptor. I knew JBoss had a nice Html Adaptor out of the box, but was wondering how I could registerer my MBean with it.

Well here’s some sample JMX, JBoss and Commons Modeler action:

    void register() {
        URL url =
            this.getClass().getResource(
                "/MyCoolServiceStatistics.xml");
        if (url == null) {
            log.error("Bugger. Couldn't find config file. JMX disabled.");
            return;
        }

        try {

            Registry registry = Registry.getRegistry(null, null);

            /* Details of this procedure on http://www.jboss.org/wiki/Wiki.jsp?page=FindMBeanServer */
            MBeanServer server =
                (MBeanServer) MBeanServerFactory.findMBeanServer(null).get(0);

            registry.setMBeanServer(server);

            registry.loadMetadata(url);

            statsAppName =
                new ObjectName("MyCoolService:name=statistics");

            registry.registerComponent(
                this,
                statsAppName,
                "au.com.bytecode.ejb.MyCoolServiceStatistics");

        } catch (Exception e) {
            log.error("Errors registering component", e);
            throw new RuntimeException(e);
        }
    }

I create my little Stats object when the App Server creates the related EJB, and then make some calls to it when methods are invoked on the EJB to keep track of useful stats. The magic sauce was the findMBeanServer() gear which I nicked off the JBoss Wiki here. Basically once you add it to the MBean server, it appears in the Http Adaptor that JBoss gives you out of the box. Sensational!

Not sure if it works on Websphere, I’ll give it a go tomorrow. Not even sure Websphere 5.1 has a Http Adaptor for JMX. I had a quick look in the Admin console and only saw Soap and RMI adaptors, but it all looks pluggable, so I should be able to slot one in.

[Read More]

(P)Reviewing Jakarta Commons in Action

I’m doing a review of a new Manning Book called “Jakarta Commons in Action” and it is one sensational piece of work. This is the ultimate missing manual to the Commons suite, and there is stacks to learn here, even if you’ve used a few of the commons suite in your projects.

What I love about this book is not just the content but also the writing style. All of the examples I’ve seen are first class - the way they deal with JMX and Commons-Modeller would be worth the price of the book for me. I finally have some sense of how Dynamic MBeans work!

There’s plenty of reference tables in there, but the book’s not about that. It really is an “In Action” title, with a style that tells you about the concepts, then how it’s implemented, and then here’s some ways you can use it.

I’ve only reviewed about five chapters so far, but if the rest of this title is the same standard (and so far it’s been remarkably consistent across the board), then this will be title you’ll want to add to your collection when it eventually hits the shelves. Great stuff!

[Read More]

ehcache is one funky cache

I’ve started exploring some of the available cache software out there, and kicked things off with ehcache. I’ve gotta say that first experiences have been excellent!

It’s been very easy to learn, (create a CacheManager, create a Cache, add the Cache to the CacheManager, presto!), and it’s a very tight implementations (50Kb). Persists itself to disk. Handles expiry of elements from the Cache. It’s battle tested (looks like the guys from Wotif.com have opened it to the world), and very accessible. Hey, it’s even used in Hibernate and Gavin is a committer!

It’s not JSR 107 compliant, and it doesn’t support distributed cache work out of the box. But it’s fast, it works, it’s small, and I was productive in 10 minutes. The doco is good, and the API has had no surprises so far. An all-round excellent piece of work. Kudos to the lads at Wotif!

[Read More]

Supressing XDoclet tags in Javadoc (from Ant)

If your project uses XDoclet and you’re sick of seeing those warnings like:

warning - @web.servlet is an unknown tag.

then what you’re after is the new Ant 1.6

<tag> element of the <javadoc> task. You can use this bad boy by embedding something like:

   <tag name="web.servlet" scope="all" **enabled="false"**/>

in your source. Be warned, though, if you’re trying to ignore a hyphen separated tag, (say web.servlet-mapping), you’re out of luck. It will interpret it without the hyphen. This is apparently a known bug with javadoc on JDK 1.4.

I’m thinking that this tag is just a wrapper of the -tag commandline arg (more info) of the javadoc executable, and that javadoc.exe internally has issues with parsing it’s own commandline. Those pesky embedded hyphens… ;-)

[Read More]

Commercial-friendly Embedded Db Options

For our little spam filter app, we’ve been evaluating embedded storage options. For commercial apps, the options are surprisingly few. HSQL and McKoi are nice but neither sports a commercial-friendly license. Axion shows a lot more promise (but it’s dependent on an older version of commons-collection).

Of the commercial options, you’ve got Daffodil and ObjectDb which both look very good, but have prohibitivly high per seat licensing options - which is no good for a desktop app. Ditto for JDataStore. And Pointbase seems to have their download links broken. I’ve filled out their forms numerous times, but it still won’t let me download an Eval copy. So they’re out too. If that’s their download approach, their support is probably going to be big trouble.

One left-field option is InfinityDb which is a non-relational BTree-based API that Matt recommended. Unusual API, but it’s got a decent royalty-free price. It stores it’s data compressed. It’s incorruptable. The schema is dynamically updatable (so no version probs). And the support is just wonderful. I just received a two-page reply from their support giving numerous options for my implementation problem.

So, anyone out there using an Embedded DB in their commercial app? What have you had good experience with?

[Read More]

Migrating from Tomcat to Jetty

I’ve been having ongoing hassles with Tomcat 5 on my 64Mb Linode - and it’s the only software on that box that’s been unreliable.

After getting sick of killing the thing off, I've made the jump to [Jetty](http://jetty.mortbay.org/jetty/index.html). It's smaller, faster, and hopefully more robust. Configuration is a snack - once you workout that the XML format just mirrors the API calls it support. My subdomains are working just great, but now I just need to work out how to configure the root context. BTW Jetty starts in around 4 seconds. Nuff said.

Pebble even ships with instructions on how to configure Jetty for Pebble use.

And best of all, it’s a Aussie product. Aussie, Aussie, Aussie, Oi, Oi, Oi!!!

[Read More]

Pebble 1.5.1 - Slick and smooth

Upgraded from Pebble 1.4 to the slick new Pebble 1.5.1. If you’re in the market for some nice Java blogging software, I can recommend Pebble very highly. Easy to install, great interface, and you can manage the whole thing via the web. Great stuff, Simon!

For those looking to upgrade, things went fairly smoothly. Some of the entries previously in web.xml seem to have migrated to a properties file in WEB-INF/classes, but that probably only affects you if you run in multiuser mode.

I had enormous performance hits on my 64Mb Linode the first time I hit any page (must the JSPs compiling for the first time). By serious I mean: type a URL, wait 90 seconds, get a page. But once that’s done once everything’s working just great. I love the slick new colour scheme, and the new stats page is much nicer (showing Google hits as the terms rather than the raw URL, ditto for the RSS hits).

Worth the upgrade. Can’t wait for the new Swing authoring app that’s coming with 1.6, that’ll be a blast!

[Read More]

Cool Plugin: JAR Class Finder

I’ve been wanting one of these for ages! You know the name of the class, but not which jar it lives it (I’ve always had problems finding the jar containing the JNDI naming provider for Websphere 4/5 - especially with about 6 different IBM JDKs on my PC!)

This Jar Class Finder plugin is just what I was looking for! Search in a given directory (and subdirectories) for Jars/Zips/properties files containing the given Class. Integrates with a nice little toolbar button, and a nice tabular view of the matching files.

Sensational piece of work. This is going to be a standard part of my toolkit forever! Great find.

[Read More]

Why is there no J2ME stack for PocketPC?

Every few months I Google for a J2ME stack for Pocket PC. Palm has one, why has no other vendor (Sun included) committed to the bigger handheld market? Apparently they had an early version of the stack for WinCE, but later support was dropped. Maybe licensing issues?

I know that phones are definitely the ultimate mass market, but PDAs offer such a rich GUI, it screams to be taken advantage of. I know there’s always Superwaba, which I may yet have a play with since it seems to really be coming along. The early versions I played with had a horrible GUI, and couldn’t use integrated handwriting/keyboard inputs, but I’ve heard things are pumping in that community, so I’m still tempted.

IBM have some kind of Websphere product for Pocket PC too, so I might suss that out as well. I know there’s a commercial offering out there too, but why develop an app that you can’t share with anyone unless they purchase their own Runtime? Superwaba is looking inviting.

[Read More]

Database caching in Struts apps

In a JSP, it’s easy enough to implement a caching strategy, since there’s a wealth of cool caching taglibs that will help you out. But what about Struts apps?

In a struts app, all your database logic is accessed via the action (or more typically via a DAO type pattern in the action, but you get my gist). So, how do you implement caching in the action?

I guess you could roll your own by keeping a private Date field of the last time you did a lookup (even keep that in your base action class), but it’s not that clean.

I’ve heard good things about JCache - that it can help with this sort of stuff. So I’ll be having a look over the next week or so. Anyone else have any good pointers for this type of scenario?

[Read More]

Exceptions crossing Tiers (and using ResourceBundles with Exceptions)

Well, I’ve been doing tons of reading on exception handling to try and develop a standard set of practices. I’ve got two immediate problems that I need to address and haven’t found much advice on:

1. Exceptions Crossing Tier Boundaries: Many of our systems are n-Tier and exceptions visible in the most remote layers aren’t necessarily available in the presentation tier. What to do?

I want to preserve the stack trace if at all possible, so I’m thinking of wrapping just the stack trace in another (presentation-tier-visible) exception and passing that on.

Alternatively, I can just log the exception (and stack trace), then rethrow a brand new exception to the client (with some sort of user-meaningful error message).

2. Externalising Error Codes and Messages: From a helpdesk point of view, it would be nice to be able to associate a numeric id with each exception. Then a client can report “Error 67: Internal Data Store Problems” appears on my screen, but the helpdesk knows that error 67 actually relates to incorrect database credentials, or whatever.

My initial thoughts are maybe to use something like a ResourceBundle, but maybe some custom descendant like a JDBCResourceBundle - where I could keep all my messages in a database (except for if the database fails ;-). My code could then pass a constant like DB_CREDENTIAL_FAILURE to the bundle and retrieve a nice-ish message like “Internal Data Store problems have been encountered talking to server {0}.” And do some nice MessageFormat calls to tidy things up.

Anyways, I’m interested to hear what you guys are doing with Cross-Tier exceptions and externalising Error strings. All ideas welcome.

[Read More]

Relative URI can not be resolved without a document URI

This post is just a placeholder so I can google for this SAX error later and remember how I fixed it.

You get one of these errors from SAX when you have an XML document that uses a relative reference to its DTD. So, say you’ve got a filter-config.xml which contains something like:

    <!DOCTYPE security PUBLIC "-//Bytecode Pty Ltd//Spam Filtering Components//EN"
        **"filter-config.dtd"** >

And you’ve put filter-config.dtd in the same directory as filter-config.xml. Fair enough. The only problem is that when you try and feed it to SAX, you get shafted with an error like:

    org.xml.sax.SAXParseException: Relative URI "yourfile.dtd"; can not be resolved
        without a document URI.

Which wasn’t really what you had in mind. The problem here is that you are trying to access the file like this:

    xmlReader.parse(new InputSource(new FileReader(configFile)));

Which SAX thinks is unreasonable since it can’t work out where exactly things are supposed to be loaded from (in network terms).

What you want to do is to feed a URL to your InputSource, with something like this:

    URL configUrl = new File(configFile).toURL();
    InputSource is = new InputSource(configUrl.toString());
    xmlReader.parse(is);
[Read More]