November 21, 2007
Return Triumphant, Or Not At All

Returning None is Evil. I agree. I've always subscribed to the Samurai Principle myself. If you allow nulls to float around you inevitably end up with NPEs. These can be hard to diagnose properly; not only do you not know if null is actually invalid, but if it is, it's often non-trivial to work out where it came from.

Posted by Simon Brunning at 10:28 AM | Permalink | Comments (3)
November 01, 2007
Coverage Tools

Julian and I have been asked to put together some unit and functional test coverage figures. We've not actually been given any time in which to do it, though, so I wouldn't hold your breath.

Looks like some work was put into using Emma to provide these figures, but it's not finished.

Over in the Python world, there's been some discussion over on c.l.py about Ned Batchelder's coverage.py, which looks like a fairly nifty module.

OTOH, I think you have to be a bit careful with metrics such as those provided by these coverage tools. Ned himself points out many of the problems with taking your coverage figures at face value (though Emma's block-level approach fixes some of them).

I'd add one more issue - gaming. People can start to see good coverage figures as an end in and of themselves. If the coverage isn't at, oh, say 80%, the tests must be crap. If they are at 100%, they must be great. It's not just that the figures can be meaningless, they can actually lead people astray.

Now, for an approach to coverage testing that actually makes sure you are testing that your code does the right thing, check out Jester & Pester.

Posted by Simon Brunning at 06:26 PM | Permalink | Comments (2)
October 30, 2007
Leopard

Leopard looks like it's got some good stuff in it - Time Machine and Spaces especially look good, and the new Terminal looks like it might replace iTerm.

But it looks like they've done the Dock no favours. The Finder changes don't sound to great either. I use Quicksilver and Path Finder, though, so I'm not too bothered about them, and I have a feeling that going forward, I'm going to have to upgrade to get any of the latest toys working.

But anyway, until they fix Java, I can't upgrade, so that's that. Early adopters around the office have found that Eclipse is totally broken on Leopard at the moment, and that's a show-stopper.

Update: Lifehacker on the new Terminal. Also, Richard and Jeff on why it doesn't matter that Java's broken on Leopard. It does matter, though - if Java won't run on Leopard, I won't upgrade to it, and I won't buy a new Mac, either. My loss, but Apple's loss too. I'm a consultant - I don't always get to choose the platform I work with, and many of my clients choose Java.

Posted by Simon Brunning at 09:51 AM | Permalink | Comments (4)
October 16, 2007
Jython 2.2.1

Jython 2.2.1 is out. It's fabulous to see Jython really making strides again. I used Jython 2.1 for years, and it worked just fine, but somehow if people don't see an OSS project making regular releases they somehow assume that they should steer clear, regardless of the quality of the existing software.

And I must say that while the missing new Python features were never a show stopper, it'll be nice to have them.

Posted by Simon Brunning at 02:09 PM | Permalink | Comments (0)
February 27, 2007
London Java meetup tonight

I'll be at Jez's London Java meetup this evening. I've not been to one for ages - not since September - so I'm really looking forward to it.

Provided, that is, that they won't talk about bloody Groovy all night. I've still yet to be convinced that Groovy has anything that Jython didn't have nearly ten years ago. Apart from closures and inelegant syntax, that is. ;-)

A new venue this time - it's at The Crown Tavern, EC1R 0EG.

Update: Seems Jython was around exactly ten years ago.

Posted by Simon Brunning at 10:10 AM | Permalink | Comments (5)
February 08, 2007
QCon London

I don't think I'll be able to make QCon, London this year - my current employer doesn't really see the point of conferences. Which is a shame, 'cos it could have been designed for us. There are an uncanny number of speakers relevant to us: Jeff Sutherland ('cos we Scrum), Gavin King ('cos we use Hibernate), Rod Johnson ('cos we use Spring), and Alex Russell ('cos we use Dojo), plus movers and shakers like Martin Fowler, Werner Vogels, Kylie, and Dave Thomas. I might be lying about one of those, though.

Never mind - there's always PyCamp!

And who knows - I might win a ticket. ;-)

Posted by Simon Brunning at 11:54 AM | Permalink | Comments (8)
October 26, 2006
Interregnum interrupted

They've shortened the interregnum - we'll be sprinting again from tomorrow. Which is a pain, 'cos I'm up to by neck in a real beauty of a bug. I'm getting a ClassCastException from one of our domain objects - but only if the back end is MySQL. Running against PostgreSQL or SQL Server, it's all fine. This is deep into the domain layer; we should have left all the database stuff far behind - and besides, we are using Hibernate, so our database engine specific code is zero.

Naturally we discovered this bug at the last minute, during the demo run-through. Our functional test box runs on SQL Server, and on my machine where it was developed I run PostgreSQL, so it all looked fine, but our demo server runs MySQL. Lucky Tulna did a demo run-through, or it would have fallen over in front of the BSDs...

Update: Got the bugger last night in the pub. It turns our that MySQL's timestamp has somewhat less resolution than the other database engines that we were using. This meant that our domain objects's compareTo() method was finding two timestamps equal, so it resorted to lower order keys - one of which was an ArrayList. Now, for some reason, ArrayLists don't implement Comparable, so when Commons Lang's CompareToBuilder tried to cast them into Comparables, we got our ClassCastException!

The fix was simple - write a little ComparableList class, sub-classing ArrayList, and use that instead. Sorted.

Posted by Simon Brunning at 03:04 PM | Permalink | Comments (1)
October 17, 2006
Java Profiling

Can anyone recommend a good tool for performance profiling Java web applications? (Hibernate, Spring, on Tomcat. you know the kind of thing.)

I've been playing with JiP, but I can't seem to get anything useful out of it. The remote control seems to do nothing at all, so I have to start up the server with it on, which takes a while - then I seem to get no output most of the time. Small runs - no problem. Big runs - which is where I get my performance issues - nothing. Irritating to get no output after waiting several hours for a big test run to complete!

Update: Or, perhaps the fact that Tomcat is still running an hour after I've asked it to shut down indicates that JiP is trying to do something? Who knows?

Posted by Simon Brunning at 03:48 PM | Permalink | Comments (8)
October 13, 2006
Merge tools

If you are going to be doing a lot of merging working with Subversion (or, I'd imagine, CVS), you are going to need good a good merge tool. And believe me, you are going to be doing a lot of merging.

Subversion itself doesn't provide a merge tool - and nor should it. It's a cross-platform command line driven tool, and besides, I suspect that most developers have their own favourite - or need to find one quickly.

If you are working on Windows, you'll probably have Tortoise installed, 'cos it's really good for simple stuff. Tortoise does come with a merge tool, but it's horrid, really nasty. Aside from just how damn ugly the thing is, it's also almost totally incomprehensible. All those colours - what do they mean?

But that's OK. There are alternatives, and they are easy enough to integrate into Tortoise. The first thing I came across was WinMerge. WinMerge is very good for showing diffs, but it doesn't (as yet) do three way merging - so that's out. Another, more powerful alternative is KDiff3. By the time I came across this, I'd already made my happy move to the Mac, so I've not used it myself, but my Windows-victim colleagues report that it works fine.

So the trick is to use the tool with diff in the name for merging, and the tool with merge in the name for diffing. ;-)

Tortoise also provides tools for making and applying patches, but they seem to use fully-qualified path names, so you can't apply patches from one machine to another unless it happens to keep everything in the same place. So, it's best to use Subversion to make your patches with svn patch > whatever.patch to make your patches (or svn st | awk '/^\s?[MAD]/ { print $NF } ' | xargs svn diff > whatever.patch if you've made the same externals mistake that I did), and to use unxutils' patch to apply them.

In the Mac, there's a natural solution - FileMerge, part of the XCode suite. It's very nice to use, if not perfect. (A few more keyboard shortcuts would be nice, for example, Apple, Just 'cos it's GUIfied and beautiful doesn't mean I should be reaching for the mouse all the time.) Integrating it with command line Subversion would be non-trivial but for Bruno De Fraine's lovely Using FileMerge as a diff command for Subversion - he's done all the hard work for you. Thanks for that, Bruno.

Oh, SubClipse also provides a merging tool, but I've never really used it. It's nice to have SubClipse around - the fact that it decorates all your files showing you their status against the repository is nice, and I often use it to add files - quicker than an svd add if you are in the IDE already. But IDE/version control integration is far less crucial than it used to be in the bad old VSS days when you couldn't edit a file without checking it out, so I do most of my Subversion tasks from the command line.

I'd be interested to know what all you *nix types use - especially anything console based.

Have I missed anything cool?

Posted by Simon Brunning at 08:27 PM | Permalink | Comments (15)
December 14, 2005
London 2.0rc1

I was off yesterday. I was feeling a little under the weather. Can't think why. Perhaps I had a dirty glass on Monday night.

I met a lot of nice, interesting people, some for the first time, many not - more on that later.

The night ended with Chris, Edward and I at the Roadhouse. What a flea pit! I was home at four...

Posted by Simon Brunning at 10:32 AM | Permalink | Comments (1)
December 08, 2005
Brunning's 1st Law of System Hassle

All IT systems have roughly equal hassle rates. Should you improve the quality of your software (by means of thorough automated testing and so forth), other components of the system (such as the RDBMS, or the hardware) will take up the slack by failing more frequently.

Posted by Simon Brunning at 01:39 PM | Permalink | Comments (6)
November 25, 2005
Bugger

There goes our crowd for London 2.0.

Update: Just to be clear - London 2.0 isn't off by any means. It's just that I'm concerned that many of our potential attendees will go the the Backstage meetup.

Posted by Simon Brunning at 05:04 PM | Permalink | Comments (1)
November 23, 2005
London 2.0rc1

This is getting out of hand. December the 12th now appears to be a combined Python/Django/TurboGears/Ruby/Rails/Java/Spring/Hibernate/the million other things you need to build a Java web app these days/Perl/Catalyst/Maypole/Groovy/Grails Christmas party, and Jez is trying to get the Geek Girls on board too. Though that may be just wishful thinking on his part. ;-)

So, we really need another name. Jez suggested London 2.0, which is just so zeitgeist. Me, I'm more London 0.9, but I'll go with it...


Let's just hope the Perl guys don't have a punch up.

Posted by Simon Brunning at 01:14 PM | Permalink | Comments (9)
November 22, 2005
London Python/Django/Ruby/Rails/Java Christmas party

Not content with a Python/Django/Ruby/Rails meetup, Sam, Jez and I have teamed up to throw a Python/Django/Ruby/Rails/Java Christmas party this year. (For "party", read "bunch of nerdy blokes, many with beards, standing around drinking beer and chatting about computers".) It's at The Old Bank of England, Fleet Street on the evening of December the 12th.

Do leave a comment if you fancy coming - we have a room booked, and but we can change it to a bigger one if we need to. I anticipate a lot of interest, what with combining the Java crowd with the dynamic language people, and possible extra interest due to last week's London Web Frameworks Night.

Anyone want to demo TurboGears? ;-)

Update: Thanks to Dave and Dave, it's now a Python/Django/TurboGears/Ruby/Rails/Java/Perl/Catalyst/Maypole Christmas party. That has to be every web nerd in London, right?

Son of Update - This Time it's Personal: See London 2.0rc1.

Posted by Simon Brunning at 12:36 PM | Permalink | Comments (27)
November 03, 2005
I'm going to feel it in the morning...

Very good lunch at The Gulshan this lunchtime with my mate Neil. I had a couple of dishes that I'm not familiar with - a Chicken & Mushroom Rizoti, and a Badami rice - and a couple of Cobras. Very good food, clean and pleasant surroundings (once we'd been moved away from the smokers), and not too pricey. (Not as cheap as The Halal, true, but not too far off.) Recommended. I may be going there again on Monday with Jez.

Speaking of Jez, now I'm off to the London Java Meetup. Looks like a bit of a quiet one - but it's the quality that counts, not the quantity, yes? Well, OK, I'm going. But apart from that, it'll be quality, OK? I hope to see a few of you there.

And if I have to look at one more user story...

Posted by Simon Brunning at 04:50 PM | Permalink | Comments (0)
November 01, 2005
Busy Month

It's going to be a busy month for nerdy stuff.

Firstly, there's Jez's London Java meetup on Thursday. Always a good night.

Then, next Monday, we have the London Python/Django/Ruby/Rails meetup. It's looking like we might get a good turnout for that - including my Technical Director! Gulp - I'd better be on my best behavior.

Then again, naaah.

On the 17th, there's the London Web Frameworks Night. Looks fascinating - demos of many of the happening web app frameworks back to back. Given the noise and drunkeness I don't tend to take much detail in during the Python/Django/Ruby/Rails meetups, so it'll be interesting to see more formal demos. Let's hope I'm quick enough to book a seat...

And lastly, there's the Einstein vs. Newton debate at the Royal Society on the 23rd. A different kind of nerdy, but nerdy nevertheless. Not to be missed.

Update: If you want to go to the London Web Frameworks Night, sign up now.

Posted by Simon Brunning at 10:28 AM | Permalink | Comments (1)
October 12, 2005
Selenium

We've not automated our functional tests in the past - I know, I know - but we are really trying to pick up our game in our currenty project, so manual functional testing is another of our bad habits that we are consigning to the dustbin of history. With a bit of a steer from Sam, I looked at a number of functional test tools, but Selenium really stood out from the rest. It's just powerful enough, it's really simple, and it runs in your browser, so you can test browser compatability. Take a look at the demos to see how simple it all is.

In essence, your test script is just an HTML table, each line of which is either an action or an assertion. There's even a tool to record your actions to give you a hand building regression tests.

Now I just need to work out how to integrate it all with Cruise Control. Anyone done this?

Oh yes, and I need to find a way of testing our web services, too. Is there no end to the array of tools that you need to build a web application these days?

Posted by Simon Brunning at 04:59 PM | Permalink | Comments (3)
September 27, 2005
Nerd Day

Friday's Nerd Day went pretty well. Steve started the day knowing Java itself, but nothing else, and by the end of play we'd covered Ant (which we used to do all our building and deploying), Tomcat, Eclipse, Servlets, JSPs and JSTL, Postgres and JDBC, and we'd written code to display the contents of a database table on a web page. Not in a lot of detail, true, but still, that's a lot of ground for one day. Steve seems pleased, anyway.

Mark had touched most of this before, but not for a good while, so I hope it was valuable to him too.

Loads more to cover, though - I'd like to expand on what I've already covered, and put a bit more meat on the bones, and there's still Spring and Hibernate to look at. So, we'll be doing another day or two before too long. Still, both my victims test subjects pupils feel up to coming along to the next London Java meetup.

Plenty of things went wrong, mainly due to my general incompetance and lack of planning. In a funny kind of way, though, this was a good thing - it gave us a change to diagnois and fix the problems. Knowing where the logs are is often half the battle.

Posted by Simon Brunning at 05:17 PM | Permalink | Comments (1)
September 22, 2005
Nerd Day

Right. I'm off to Haslemere to meet Steve to drink beer. Then, tomorrow is the long planned Nerd Day, during which I'll be showing Steve how to build a web application in Java. Mark will be coming down for it too; I gather that he's a bit sick of VB now.

I'm a rubbish trainer, so wish me (and them) luck. No need to worry about this evening, though; I'm good at drinking beer.

Posted by Simon Brunning at 04:38 PM | Permalink | Comments (5)
September 07, 2005
Java/Flickr Meetup

Last night's Java Meetup was great fun.

El Presidente was a little disappointed - he'd come along hoping to talk to some people about XP. (We are adopting it at work, bit by bit, and while we can all see the problems inherent in Big Design Up Front, we are also having difficulty working out how to do without it.) There are usually a few ThoughtWorkers around, but not this time, and no one else had any real XP experience. They'd all read the book, though. ;-)

It wasn't a total waste for him, though - He, Tulna and Darren formed a mini digital photography and Flickr sub-meetup. There were some good photos taken: (See here, if the permalink gets fixed, or find them from here otherwise. Darren also posted some of them to his blog, and set up a London Java Meetup Flickr group.) Darren had a particularly nice lens - even I managed to take a decent photo with it.

El P and Tulna were pleasantly surprised by the absence of wierdos, I think, but they both left fairly early.

Late in the evening I had a conversation about the lovely Spring framework with Rob Harrop and Rick Evans. This is most unusual - Jez has specified Spring as the topic of the month, and I never talk about Jez's topic.

Anyway, thanks to Jez for another good night. It would be rather churlish to blame him for my hangover, wouldn't it?

Posted by Simon Brunning at 03:29 PM | Permalink | Comments (6)
Google London

The big news from last night's Java Meetup is that Google is settting up a London office. It's to be focused on mobile devices, and new Google employee Ian Sharp was there to spread the news. They will be looking for people with Java skills, so have a go if you think you are hard enough.

Posted by Simon Brunning at 02:53 PM | Permalink | Comments (4)
August 31, 2005
Roadkill

I've been getting on fairly well with Roadkill, my nice new Powerbook, but it's been a bit of a learning curve. The pretty Mac front end stuff is a piece of cake on the whole, with one major exception - undo, cut, copy and paste are Apple-z, x, c, and v respectivly, instead of Ctrl-z, x, c, and v as they are on Windows. I've been using those shortcuts for so long now that they are embedded in muscle memory. I've hit the wrong shortcut before my brain (such as it is) has had a chance to overrule them. Getting over that is going to take a while.

Getting some of the command line driven stuff - Ant, Subversion and Tomcat - working was a bit more of a challenge. Easy once you know how, but you keep being tripped up by things that I didn't know about.

I had installed Java 1.5, but the installer didn't tell me where it had been put, so I had to go and look for it. I found it in /System/Library/Frameworks/JavaVM.framework/Versions/1.5/ in the end.

There was already a version of Ant installed in /Developer/Java/Ant, probably as part of the XCode tools install, but it was the wrong version, and in any case I wasn't able to add 3rd party tasks to it, so I needed to use my own version.

Both of these problems involved setting environment variables, and I gather that it's recommended that you don't muck about with global environment variables, so I set up some shell scripts to start and stop tomcat and to run ant scripts with the environment variables set correctly. I was even smart enough to put the shebang line at the top (though finding the bloody '#' key took a while) and to mark them as executable wwith chmod. But I still couldn't run the bloody scripts. The shell was claiming that tey wen't there, though I could see them with ls.

It turns out that your current working directory isn't on your path by default. Arrrgh! That one took me hours, literally. Prefixing the script names with ./ does the trick there.

I still can't resolve any of the other boxes on my network by name, only by IP address. Irritating, but no show stopper. I can always add them to /etc/hosts, but for the moment I'm just using the IP addresses.

Still, I managed to get past all that, and my current web application is building and running on Roadkill happily enough now, after fixing a couple of minor Windows-isms in our build file. ;-)

Next on my list; installing PostgreSQL, and getting my app to work with it, and working out this whole multiple Python versions on one machine thing, and working out where the insert and delete keys are...

One other thing - what do you, uh, we Mac users use to read Usenet? Entourage seems to have trouble getting at Gmane - this fix, uh, doesn't.

Posted by Simon Brunning at 01:52 PM | Permalink | Comments (17)
Java Meetup next week

Pop along to next week's London Java Meetup on Tuesday the 6th. I'll be there - and I'm bringing Tulna and El Presidente with me this time. Perhaps Steve, too.

This month's topic is Spring, but as usual, off topic nerdyness of any kind seems to be welcome. For instance, I happen to know that Tulna (nerd in denial) will be interrogating Darren about shooting RAW, since she has a shiny new Nikon D70s.

I've dropped the ball a little recently with the Python meetups, but I'll probably organise one for October. I can't afford one this month - I spent over £100 last time!

First post from roadkill!

Posted by Simon Brunning at 01:05 PM | Permalink | Comments (4)
July 14, 2005
Spring: Bold as Love

I am having trouble getting Spring and Axis to play nicely together.

I've been getting along famously with Spring. We are using Spring's MVC framework, and everything was fitting together as smooth as silk. Our DAO's are coded using HibernateDaoSupport, instantiated as beans wrapped in HibernateTransactionManagers, and injected into our actions and controllers. With this lot set up, Spring and Hibernate between them do all the heavy lifting in terms of database work, and our code needs to know almost nothing about it. And using jMock in our unit tests to mock the DAO, we had close to 100% coverage.

Then I was asked to introduce web services. Axis looked to me to be the de-facto standard, so that was what I've been using so far. In most ways, it's a thing of beauty - I particularly like happyaxis.jsp - but I can't work out how to get it to play happily with Spring. Spring isn't instantiating the service objects, so it doesn't get an opportunity to inject the DAOs.

In order to unit test at all, I've created given the service objects setters and getters for the DAOs they need. The getters lazily initialize the DAOs from Spring in required. In our unit tests, we just call the setter with a mock object, so the lazy initialization never gets used.

public CurrencyDAO getCurrencyDAO() {
 
    // Lazy initialisation. If the DAO hasn't yet been set, we'll get it
    // from Spring. I doubt we'll be able to cover this in testing.
    if (this.currencyDAO == null) {
        this.logger.debug("Lazy initialisation of currencyDAO");
        final ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext());
        setCurrencyDAO((CurrencyDAO) applicationContext.getBean("currencyDAO"));
    }
    return this.currencyDAO;
}
 
public void setCurrencyDAO(final CurrencyDAO currencyDAO) {
    // This will probably ony be needed for test purposes.
    this.currencyDAO = currencyDAO;
    this.logger.debug("currencyDAO set to " + String.valueOf(currencyDAO));
}

(How do I get the servletContext? In the real code, I grab hold of it with a ServletContextListener, and keep it in a Borg.)

This works, but it feels inelegant. Worse, much of the getter is impossible to unit test. Is there a way to get Spring to instantiate my Axis service objects? Is there a cleaner way of getting beans from Spring? Is there another web service framework that plays nicer with Spring?

Posted by Simon Brunning at 04:52 PM | Permalink | Comments (3)
June 23, 2005
Instant Messaging

Mum is looking to do a spot of Instant Messaging with her Amida Buddhism chums. (My, look at all those blogs! All down to Mum's example.)

I've been looking at IRC recently, and it's really nice for techies. I've been using Bersirc as a client and Freenode as a server, and it's dead good. I've had some really useful help with Spring on #spring, and #python is cool too. (Say "Hi" if you are around there - I'm on as "small_values".)

But is it good for non-techies? If not, what should I recommend to her instead? Trillian? Miranda? Using what protocol? ICQ? (Anyone mentioning MSN can bugger off. These people are Buddhists, and need to keep their souls pure.)

Posted by Simon Brunning at 01:03 PM | Permalink | Comments (15)
June 09, 2005
Signing off

I'm off to CenterParcs with the kids, and my Mum, sister, brother in law and nieces next week, so Small Values will be even quieter than usual.

Blogging has been sporadic at best recently 'cos I've been so busy, mainly with a new Java web-app that we've been working on, using Spring and Hibernate running over a legacy database. It's been hard work, but I think we are over the hump now.

The other thing that's been keeping be busy is doing the Python URL. It's hard work - but it seems to be going down well. If there's one next week, though, it probably won't come from me...

Anyway, have a good week all. I might possibly post next week if there's a 'net café around, but don't count on it. I should have loads of photos by the 20th.

Posted by Simon Brunning at 01:24 PM | Permalink | Comments (4)
June 02, 2005
Doh!

Note to self - when copying files with Ant, never apply a filter to JAR files. They break.

If you do do this, try not to spend ten bloody hours working out what's gone wrong.

On a similar note, jMock is lovley, but don't get too carried away and mock the object that you are actually trying to test. You won't find any bugs, and your EMMA stats will suffer.

Posted by Simon Brunning at 01:56 PM | Permalink | Comments (2)
May 24, 2005
Hibernate Support

I take it all back. Hibernate support isn't as great as all that after all. After a very good start, I've had no help whatsoever on several issues. One I managed to work out for myself - One-to-many relations with composite natural keys.

I'm still having problems with a couple of issues, though. Firstly, I can't work out how to do data cleansing with Hibernate. It falls over on the first dodgy data it sees. I want to get a list of all the problematic data, and I can't work out how to do it.

The other problem that I'm having or with a complex relationship between a couple of entities; both one to many and one to one. I've got company definitions and currency definitions with a bog standard parent-child relationship - one company has a number of currencies defined for it. But the company also has a reporting currency - a foreign key back to the currency file. I can see that this relationship is slightly problematical in relational terms, but it makes perfect sense in business terms. Anyone have any idea how to write this relationship in Hibernate? (In fact, I can think of two workarounds. I could make the reporting currency code available as a property rather than relating back to the current table directly. Retrieving the currency object would then be the client code's job. Or, perhaps I could try building the company to currency link as a one to many. I'm not even sure that that would work. Besides, I really want to fix this problem properly, for one and for all. I'll probably come across a lot of this kind of relationship as I map more of my legacy database.)

I wonder if the problem is that Hibernate uses a forum rather than a mailing list? It's much easier to ignore forum threads that it is to ignore emails in your inbox.

Whatever the issue, I do know that questions like mine do get some kind of answer on c.l.py, Just about any inquiry gets some kind of response, even if it's just a request for more info, or a URL to follow up.

Posted by Simon Brunning at 10:01 AM | Permalink | Comments (2)
May 11, 2005
Hibernate and my legacy database

Before I start, a big thank you to Max over at the Hibernate User forum for helping me out. The quality of the code is only ever half the reason why open source tools are the best way to go. The other half of the reason is Max, and people like him, ready to help out a complete stranger. Thanks, Max. ;-)

Anyway, what I've been busy with over the last few days is building some mappings from Hibernate to an existing legacy, err, sorry, I mean a vintage database. Hibernate is lovely. Lovely lovely lovely. But I think it's fair to say that there's a lot more work involved in mapping to an existing database than there is if you are able to just let Hibernate get on with its thing and create its own schema.

The, err, vintage database is a quarter of a century old, most of it. It's not in bad shape - I've worked with a whole lot worse - but obviously it's not put together with modern best practices in mind. Loads of natural composite keys. Sigh. Also, the data types available at the time the system was first build were quite limited. There were no booleans or datetimes available, for instance, so these are stored as CHAR(1) and DECIMAL(7,0) columns respectively, so I've had to put together my own custom user types for these. Just to make life that little bit more painful, not are the only are the dates stored as seven digit numbers (in CYYMMDD format, where a C value of 0 is for last century, 1 for this - common practice on a '400), but they can also hold all zeros or all nines!

It's an iSeries (a.k.a AS/400) DB2 database, which Hibernate supports up to a point, but what I'm going to do when I come up against platform specific things like multi-member files I don't know. I'm sure I'll think of something.

There are also a few tables with no unique keys. That's really no unique keys - it's valid for there to be multiple identical records. I'm pretty sure I'll have to go back to plain old JDBC for those tables. Thankfully, this isn't common. Even twenty five years ago it was obvious that that was a bad idea!

I'm off to work out how to do a one-to-many relation where both sides have composite keys...

Posted by Simon Brunning at 02:01 PM | Permalink | Comments (7)
April 29, 2005
Passwords and Ant

A number of Ant tasks require passwords - server deployment, verson control, that kind of thing. How do you deal with them? I'm not happy about keeping them in properties files - not too secure - but I can't find any way of persuading Ant to prompt for them. Obviously, this problem has been solved long since, but I can't seem to track down the solution.

Posted by Simon Brunning at 05:44 PM | Permalink | Comments (4)
April 13, 2005
A rather unfortunate decision

Tonight's London Python Meetup at The Stage Door will be the last one organised via meetup.com, due to a rather unfortunate decision of theirs. If you want to be informed of future London Python meetings, you'll need to join the Python UK mailing list - or just subscribe to this blog.

It occurs to me that a moin page would do everything that we need - new events could be entered there, and people could subscribe to the page to be kept up to date. Perhaps I'll install a moin instance here on SVoC - or perhaps I could just add a page to the Python Wiki?

Oh, and don't forget the London Java meetup on April the 20th. I'll be there!

Posted by Simon Brunning at 11:02 AM | Permalink | Comments (3)
April 06, 2005
JSR Groovy

It's still not showing any signs of tempting me away from Python/Jython, but congratulations to James, Jez et al on getting the Groovy JSR 01 release out of the door.

Posted by Simon Brunning at 10:35 AM | Permalink | Comments (2)
March 18, 2005
Jolt 2005 awards

Congratulations to the Jolt 2005 award winners (PDF). I've read, used or will use a number of the winners:

But where's Spring?

Posted by Simon Brunning at 09:39 AM | Permalink | Comments (0)
March 17, 2005
Books

Oooh, a nice big pile of books has just arrived:

The first two are mine, but I managed to convince the company to spring for the rest. ;-)

Posted by Simon Brunning at 04:05 PM | Permalink | Comments (3)
March 07, 2005
Spring or Struts?

My company is deciding on the toolset that we'll be using for our next generation of web applications. Java was a shoe-in after my Python suggestion was shot down early in the discussion. :-(

But deciding upon Java is only the first step - you need a whole bunch of stuff to go along with it. One of our recent projects was intended to be a pilot, and I was fairly happy with the toolset that we used for that, so mostly we'll be updating that list.

In the end, though, we ended up not using Hibernate and not using Struts - we wrote our own. This time, I'd like to use frameworks for these layers rather than building our own workable but time consuming and frankly far inferior versions.

Hibernate looks by far the front runner for the persistence layer, but selecting the MVC framework isn't so easy. Struts is certainly the de facto standard here, but I'd like to be using Spring for other things in any case, and I gather that its MVC component is really good, so I lean towards using that too.

Good idea? Bad idea?

There are a few other additions to the original toolset:

  • Log4j
  • We'll be using JSP (and JSTL) for our View layer. Unfashionable, I know, but since JSTL came along and removed the need for virtually all of those nasty scriptlets, I find JSP to be rather nice.
  • EMMA for unit test code coverage reporting
  • iText if we need any PDFs generated
  • Joda Time
  • jMock
  • displaytag

Anyone think that we shouldn't be using any of this stuff? Anything essential that I'm missing?

Posted by Simon Brunning at 10:45 AM | Permalink | Comments (21)
March 01, 2005
Yesterday's London Java Meetup

Coming in to work on a badly overcrowded and very slow running tube with a nasty hangover is no fun, I can tell you.

But last night was a good one.

It looked like it might get a bit nasty at one point. We used a back room that had been booked by a bunch of performance poets. Java nerds versus poets - what a rumble that would have been.

In fact, we just moved to the front of the pub, where I remained undefeated on the pool table.

Oh, and don't forget the Python meet up next week...

Posted by Simon Brunning at 04:54 PM | Permalink | Comments (0)
February 28, 2005
London Java Meetup tonight

Turnas out that I can make the London Java Meetup this evening. But since I still can't see Haloscan, I can't tell Jez about it...

Anyway, see you there.

Posted by Simon Brunning at 01:48 PM | Permalink | Comments (1)
February 23, 2005
The real problem with Java

I've realised what the real problem with Java is, for me. It's not the fact that my productivity is much lower with Java than it is with Python. After all, it's my management that decide that I should be using Java, and if they want to make me less productive than I could be, it's their prerogative.

And it's not the vast raft of tools, libraries and frameworks that a modern Java application uses that bothers me. It's a problem for a lot of people - c.f. Bruce Tate's superb Better, Faster, Lighter Java (on which more later), but I like learning new stuff, so I'm happy.

No, the problem is that Java coding is just no fun...

Posted by Simon Brunning at 12:54 PM | Permalink | Comments (32)
February 10, 2005
Weird Eclipse error

I've come across the error message "The import somepackage cannot be resolved" loads of times - I'm sure that we all have. It usually means that you are missing a JAR file from your project's build path. But I'm getting it under strange circumstances this time...

The package that Eclipse is objecting to at the moment is in the current project! If I remove the import, and do an "Organise imports", Eclipse will replace the import, then claim not to be able to find it. If I hit F3 on the import, Eclipse takes me straight to the correct class.

Anyone got any ideas as to why Eclipse is claiming not to be able to resolve the import?

I have this problem running Eclipse version 3.1M4 and version 3.0.1, all on Windows 2000, with Java 1.4.2_1.

(I've also posted this to the eclipse.tools.jdt newsgroup - see Import cannot be resolved - for a class in my project!. You'll need a password before accessing this newsgroup.

Thanks in advance for all your recommendations that I switch to IntelliJ IDEA. ;-)

Posted by Simon Brunning at 01:17 PM | Permalink | Comments (35)
February 02, 2005
You are in a maze of twisty classes, all alike

Steve Rose is a very bad man. Vodka and Baileys is no drink for a man, but if (much against your will) you do drink it, you get very pissed indeed.

Anyway, we had a look at his code. He's fallen afowl of Java's laberynthine java.io. Now, I need a FileInputStream, an InputStreamReader and a BufferedReader to read a file, right? Or is that a FileReader and a BufferedReader? I've done this loads of times, and I still can't remember. It's hardly surprising that Steve can't work it all out. There really ought to be an openTheGoddamFileAlready() method somewhere...

Update: Here's how you do it in Python. Less is more.

Posted by Simon Brunning at 11:10 AM | Permalink | Comments (3)
January 28, 2005
Putting it all together

Tell me what to do, please.

I've most often come across this issue building Java web applications. There are just so many pieces to stitch together, and to find places to put; your your build script, your business objects, your tests, your JSPs (or whatever), all your 3rd party JARs, your persistence stuff, your MVC stuff, your IoC stuff, about a gazillion configuration files to make all this lot work together, it just goes on and on. It takes a while, and if you get it wrong, well, everything still works, mostly, but you'll have maintenance nightmares for life.

In fact, it got so out of control that Matt Raible came up with the wonderful AppFuse. Appfuse is great - it builds a project structure for you, using your choice of frameworks, so you can hit the ground running. I only hope that Matt learns to slow down a little!

Perhaps that's what Python needs - not Rails, but AppFuse.

Update: Matt's site seems to be down at the moment. But do try later - AppFuse really is worth a look

Posted by Simon Brunning at 02:24 PM | Permalink | Comments (9)
January 20, 2005
Special Cases

Very interesting London Java Meetup last night. It was nice to see Darren and Steve along for the first time, and I had a very interesting chat with James about Sun's new interest in dynamic languages, and Groovy, his baby. (Jez is also working hard on Groovy at the moment.)

It's interesting to see the differences and similarities between the philosophies of Groovy and Python. One thing that James and (channelling) Guido agree on is that simplicity is good. They disagree on what constitutes simplicity, though.

Take functions for a moment. In both Python and Groovy, functions and methods are 'first class', which means that they are objects in their own right, and can be passed around like any other object. They differ in how that's done, though.

In Python, a function is called by putting parenthesises after its name:

>>> def spam():
...  print "spam's been called!"
... 
>>> spam()
spam's been called!

If you want to refer the function object, you just leave the parenthesises off:

>>> spam
<function spam at 0x0117CDB0>

This makes it easy to pass the function around:

>>> eggs = spam
>>> eggs()
spam's been called!
>>> def chips(a_function):
...  a_function()
... 
>>> chips(spam)
spam's been called!

To me, that's nice and simple. No special cases. As Tim put it, "special cases aren't special enough to break the rules". A function is an object, names are bound to objects, using the base name refers to the bound object.

"Ah!", says James, "but 99% of the time when a newbie leaves the parenthesises off, it's a mistake. That want to call the function." This is probably true. So in Groovy, if the function takes no arguments, you can call it without parenthesises. If you want to refer to the function object, there's a special syntax for that. (Perhaps James or Jez would care to give an example here?) The 'normal' case gets the normal syntax, and the unusual case gets the special syntax. So, is this simpler?

Another example - self. Python requires all methods to take an explicit self argument. After all, a method is just a function belonging to an instance really, and it's simpler to pass that instance explicitly. No black magic, and it makes injecting new methods into classes and instances at runtime simpler. But you always need a reference to the instance, though, so in Groovy it's is available implicitly. It's not like you need to dynamically add methods that often, is it?

To me, having all this implicit stuff is more complex than doing everything explicitly. But to James, keeping the common case simple to write is simpler. Who's right? Who knows. I like Python's approach myself, but it's not obvious to me that James is wrong.

I'm also sad to say that James is starting to understand what it must be like to be Guido, attacked every time you propose a change. Bloody nice chaps, both of them, so this is a real shame.

Oh and where were you, Sam?

Posted by Simon Brunning at 01:52 PM | Permalink | Comments (12)
January 14, 2005
London Java Meetup

The next London Java Meetup is next Wednesday, the 19th. Nerds of all persuasions and ranks welcome.

Predicted topics of conversation: Jez and James will tell you that Groovy is the future, I will be unconvinced, Sam will tell us all about build pipelines until our brains fall out, then we'll either talk about how cool the Huygens probe was, or, should it go tits up, how sad it all was. Everyone will show off their cool iBooks, and I'll be jealous.

Shall we try and talk Jez into going to The Poet again? It's much quieter than Smiths of Smithfield...

I've ordered some Ubuntu release disks, both x86 and PowerPC flavours. With luck, I'll have them in time to give them out.

Oh, and don't forget the 20th and 27th...

Posted by Simon Brunning at 01:24 PM | Permalink | Comments (1)
December 09, 2004
Dynamic Languages Summit at Sun

Dynamic Languages Summit at Sun, involving Guido, Samuele Pedroni, Larry Wall and James Strachan, to name but a few. Cool!

Jez was telling me about this at last night's Java Meet, but he asked me to keep it under my hat. But I suppose that if Tim Bray is blogging it, it's pretty squarely in the public domain!

Update: Ted Leung - Dynamic language support on the JVM - cross your fingers!

Posted by Simon Brunning at 12:05 PM | Permalink | Comments (1)
December 08, 2004
London Java Xmas Party This Evening

Don't forget The London Java Xmas Party this evening. Nerds of any stripe welcome.

Posted by Simon Brunning at 11:14 AM | Permalink | Comments (1)
November 24, 2004
Ho Ho Ho

London Java Xmas Party. Be there, or be square. Or, as empirical evidence shows to be not uncommon, both.

Posted by Simon Brunning at 01:29 PM | Permalink | Comments (0)
November 11, 2004
Nerd Pride

Orpington, day three. Sigh. Still, I'm writing some kick-ass SQL. All standard stuff, too - none of your nasty vendor extensions here.

Anyway, I do hope to be able to make tonight's London Java Meetup. Do try and get along, London based nerds.

Posted by Simon Brunning at 09:53 AM | Permalink | Comments (2)
October 12, 2004
The Good, The Bad, and the Nerdy

London Java Meetup - 18 Oct 2004.

Posted by Simon Brunning at 04:03 PM | Permalink | Comments (0)
September 28, 2004
Nice People

Are Python people really nicer than Java people? Hmm, well, it seems to be that case that c.l.py is unusually good natured. But I have to say that I've found Java people to be really nice too. People are ridiculously helpful over on the iText mailing list. And last night's nerd-crawl was a pleasure as always.

Posted by Simon Brunning at 01:16 PM | Permalink | Comments (0)
September 27, 2004
Night of the Crawling Nerds

The inaugural London Java pub-crawl is tonight. Not the last, I hope. Nerds of all ranks and persuasions welcome.

Posted by Simon Brunning at 01:10 PM | Permalink | Comments (0)
September 23, 2004
iText in Anger

Well, I've knocked up some stuff for real using iText now. The rose-tinted glasses are off for sure, but I have to say, it's a good solution.

Writing a long complex report with a lot of formatting is pretty dull, it must be said. But that's the nature of the beast, really - northing's going to make report generation exciting. iText does at least make it relatively easy to get exactly the result you need.

The mailing list, as I usually find in the open source world, pisses all over the "support" that you'll get from the proprietary world. So, a big thank you to Bruno Lowagie and Paulo Soares, not only for writing iText in the first place, but for their time over on itext-questions.

The code that you have to write is pretty ugly, I must say. It's really procedural, and it's long. There are a lot of repetitious sections that look like they could be refactored into methods to avoid code duplication, but that you find are different enough that you can't - at least, not without making the code really complex. And while the report generation code is long, it's also very simple; add a paragraph, add a table cell, add another table cell, and so on, and so on.

One thing I would like to be able to work out how to do is unit test. I already know that my domain objects work - they have their own unit test. So I really just need to make sure that the PDFs are generated correctly, and I can only do that by eye. Anyone have any good suggestions here?

Anyway, in short, I wouldn't hesitate to recommend iText over StyleReport or the like to anyone who can code.

Posted by Simon Brunning at 01:23 PM | Permalink | Comments (9)
September 16, 2004
iText

iText - it's just so easy! I may be seeing it through rise tinted spectacles, scared as I am by my recent run in with StyleReport, but I'm just loving using this. I've finished the tutorial, and I'll get started on the real deal tomorrow.

Posted by Simon Brunning at 04:56 PM | Permalink | Comments (3)
September 13, 2004
Result!

Goodbye StyleReport, goodbye Inetsoft. I have the go-ahead to rewrite our PDF reports in iText.

:-)

Posted by Simon Brunning at 01:31 PM | Permalink | Comments (7)
September 10, 2004
Rotten Statics

We had rather an obscure issue today.

Rather against my advice, we have a class to keep all our string constants in - Constants.java. I wanted to keep these strings either in the classes to which that naturally belong, or in a configuration file if they were likely to change.

What can I say? I was outvoted. ;-)

Anyway, Constants.java consists of nothing but a bunch of lines like this:

public static final String PRINCIPAL_SESSION_ATTRIBUTE = "principal";

At the last minute before going live, the value of one of these strings changed. We ran our dist target, and installed.

One of our classes, let's call it Skippy.java, refers to this string - and we were finding that it was picking up the old value. We were, to say the least, perplexed. We removed the web application completely from Tomcat, and deleted WARs and classes from all over the shop before reinstalling the app. No dice - it still picked up the old value. We bounced Tomcat, which didn't help. We rebooted the server, ditto.

We even decompiled Constants.class. It contained the new value.

In the end, I tried decompiling Skippy.class. Lo and behold, there it was - the old value. WTF was it doing in there? It should have referred to the value in Constants.class, shouldn't it? Why did it have its own copy? And if Skippy.class was supposed to have its own copy of the literal, why didn't Ant recompile it for us?

Anyway, we only had to run ant clean dist, and install the WAR file we got from that, and all was well.

Lessons learned today:

  • Really don't use a bloody constants class.
  • Make your dist target dependent on your clean target.
  • Nobody likes it when you tell them "I told you so". ;-)

Posted by Simon Brunning at 04:40 PM | Permalink | Comments (10)
Bend Over...

From an ongoing dialogue with one of our suppliers:

> From: [Name deleted to protect the, uh, whatever.]
> 
> Simon,
> 
> My name is [Name deleted] and I am an account manager at Inetsoft. My 
> records show that
> your maintenance expired on May 1, 2004. To get support at 
> this point, you
> would renew maintenance as usual, but also would need to pay 
> a $100 penalty
> for the breach in maintenance (This should have been indicated on the
> original quote). As you were operating on the complementary 60-day
> maintenance, a 1-year extended maintenance would be traced 
> back to the date
> of purchase (Mar 2, 2004), giving a renewal date of Mar 1, 2005.
So, as I read this, in order to get serious defects in your product repaired, you want to charge me a year's fee for six month's support, plus a hundred dollar fine on top?
This doesn't sound too reasonable to me...
Cheers, Simon Brunning.

Update: They got back to me:

Please understand without these terms, many customers would decline initial
maintenance, and come back to the sales department and purchase maintenance
only when they run into a problem. This causes problems for our customers,
as they need to produce the funds and process the order all the while
development is on hold because of a bug or issue in the software that does
not allow them to continue their efforts. Comparatively speaking, the
penalty is a small amount and is primarily in place to discourage this
activity.

Ah, so these terms are for our benefit! It all makes sense now!

iText it is, then.

Posted by Simon Brunning at 08:48 AM | Permalink | Comments (8)
September 03, 2004
Mad Hungarian

One for Mark: Hungarian notation: an outdated concept. See, Mark, there's almost nobody left who still thinks that Hungarian doesn't suck.

Posted by Simon Brunning at 01:48 PM | Permalink | Comments (4)
August 18, 2004
Pro Plus for Eclipse

Eclipse rocks - when it's awake. But using it on Windows, I've found that it has a tendency to drop off - if I've not used it for a while, or especially if I've minimised it, it often takes a good twenty or more seconds to start moving again, and even than it takes a long time before it starts to respond snappily.

The KeepResident Eclipse plug-in seems to fix this. It works for me, anyway.

"Windows has a tendency to preemptively swap Java processes out of physical memory, even when there is still plenty of physical memory available." Hmmm. You could almost think that this was deliberate, couldn't you? No, it's not possible - Microsoft would never behave in an underhanded fashion like that, would they.

Posted by Simon Brunning at 05:56 PM | Permalink | Comments (5)
July 29, 2004
Mocking a URL

Tulna's having a bit of trouble with some unit testing at the moment. The lovely Emma has pointed out a few holes in our test coverage, and Tulna is endeavouring to fill them.

She's currently working on building tests for our configuration classes. We use Digester to pull in all our configuration from XML. In real life, it's all as sweet as a nut, but obviously we still want unit tests to ensure that any future breakage is discovered PDQ.

We run digester in a ServletContextListener's contextInitialized(). After setting up our digester, after all that addObjectCreate(), addBeanPropertySetter() shenanigans, the code which actually does the digesting looks like this:

URL configFileURL = context.getResource("/WEB-INF/config.xml");
InputStream configFileStream = configFileURL.openStream();
config = (Config) digester.parse(configFileStream);

Question is, how do we get our test data into configFileStream? The context object is a mock, so we can do anything we like there - but how do we mock URL? It's a final class, so we can't sub-class it...

Posted by Simon Brunning at 05:12 PM | Permalink | Comments (6)
July 28, 2004
IBM's new Eclipse toys

IBM has released some cool looking new Eclipse plug-ins: Eclipse Web Tooling Platform Contribution - IBM. I particularly like the look of the Data Tools, the Server Tools and the Structured Source Editing.

Posted by Simon Brunning at 02:38 PM | Permalink | Comments (0)
Soft-coding the class's name

Ever since I started using log4j, it's irritated me that I'veneed to hard-code the package name in my Category log = Category.getInstance("package.name.here") statements, once in every class. Well, it turns out I don't; Pretty Log4J shows how to avoid hard-coding. ClassName.java lets me do Category log = Category.getInstance(ClassName.getPackageName()) - much nicer.

Posted by Simon Brunning at 02:18 PM | Permalink | Comments (4)
July 20, 2004
EMMA

Sam pointed me at EMMA, (a Java test coverage tool,) and I've recently found the time to implement it.

Well, it was either that, or struggle with StyleReport Pro. What you you rather do? ;-)

Anyway, EMMA's output is really rather nice. It's structured and informative - you get a good high level overview, but you can you can drill down to reports on individual line coverage. Getting it running with our existing test suite took me a couple of hours of fiddling - but perhaps that's another post...

Posted by Simon Brunning at 01:50 PM | Permalink | Comments (0)
Taking the back off the radio

Inetseft's StyleReport Pro is the bane of my life at the moment. We need to point our reports at different data sources and even different servers under certain circumstances. StyleReport offers no way of soft-coding these values, so the suggestion is that we have a separate instance of each report definition for each combination of server and data source that we might want to use. Yuck.

But... the report definitions are stored as XML files. Editable XML files. Mwahahahahaha!

Now, StyleReport insists that these report definitions live in the file system. This breaks our J2EE application to a certain extent, because J2EE does not guarantee the availability of a file system. In practise, we are OK; we are deploying to Tomcat, which does give you a file system. We need to keep the application's home directory in a configuration file, which is nasty, but which works. Had we needed to deploy to a sterner J2EE server, though, such as WebSphere, we'd have been buggered.

I wonder how many supposedly J2EE applications need access to the filesystem? Quite a few, I'll be bound. So, does this mean that IBM is being a bit over-strict with WebSphere? Well, no; WebSphere runs on platforms with totally non-standard file systems; the AS/400, no, sorry, iSeries, no, sorry, i5.

Anthony points out that with a bit of work, you can give a J2EE application a file system using Commons VFS. Cool stuff.

Posted by Simon Brunning at 01:05 PM | Permalink | Comments (6)
July 16, 2004
StyleReport

I've spent the last couple of days with Tulna, building PDF reports with Inetseft's StyleReport Pro. It's a piece of shit. My brain is numb.

Posted by Simon Brunning at 04:47 PM | Permalink | Comments (12)
July 14, 2004
Scary Hacks

Hats off to David Shay for Unfinalizer. Light the blue touch-paper, and retire to a safe distance.

Via talios, via Erik.

Posted by Simon Brunning at 02:36 PM | Permalink | Comments (0)
Eclipse: Mark Occurrences

My favorite feature of the new Eclipse release, by far, is something that isn't turned on by default, and took me a long time to discover: Mark Occurrences. This is just so useful...

Give it a bash, if you haven't already; it's great! Basically, it highlights whichever element your cursor is on. This element is highlighted throughout the Java editor, both in the edit area and in the right-hand margin where errors and warnings are shown. (What is that called, by the way?)

And there's more. Put your cursor over a method's return type, and it'll highlight all the method's exit points. Put it over an exception in a method's throws clause, and it'll show you all the places in your method where that exception can be thrown.

Posted by Simon Brunning at 02:17 PM | Permalink | Comments (4)
July 12, 2004
London Java Meetup Tonight

Ooooh, it's going to be an exciting London Java Meetup tonight!

Firstly, we've got Hani versus James and the Groovy boys arguing about Groovy. Despite what Sam says, I'm not against Groovy as such, but I have my own favorite, and with religious wars, you often get a with-us-or-against-us kind of thing going on. ;-)

Then, for the 2nd act, you'll have the Thoughtworkers having a full and frank exchange of views with Hani, who's been dissing them and their Guru.

Should be fun.

Posted by Simon Brunning at 02:11 PM | Permalink | Comments (2)
Test Coverage: JXCL

Our unit test suite isn't all that it could be. For one thing, it wasn't run at all while I was away - that's two months! Sigh. Naturally, running Ant's test target resulted in a smoking ruin...

Still, we've got all but a couple of the tests working again, usually by changing the tests to reflect changed functionality, but often by fixing the bugs that the tests should have been making plain.

Now I'd like to see what our test coverage is; I'm sure that it's far below 100%, and I'd like to start moving it in the right direction. Has anyone used JXCL and UCovered? Any good? Or is there something else I should be looking at?

Aside from "run your bloody unit tests", there's one other lesson learned; some of the code breakage resulted from changes to our database definitions, which for some reason were never kept under source control, so it's not possible to establish who made a change, when, and most importantly, why. The database change might have been made for a good reason, so you just can't remove it - especially if your unit tests are spotty.

I gather that keeping your database definitions under source control isn't trivial when you are using SQL Server, but it must be possible. We'll do it next time; if I can't manage to convince the team to move away from SQL Server, we'll just have to work it out.

Posted by Simon Brunning at 01:42 PM | Permalink | Comments (10)
July 08, 2004
About Time

Via Managability's Top Ten Truly Obscure But Useful Java Projects, I find the suddenly essential Joda Time. Not quite mxDateTime for Java, but almost.

Some other interesting recent Java links:

Posted by Simon Brunning at 02:03 PM | Permalink | Comments (0)
July 05, 2004
So Long Angel

Also in my hectic social calendar in the next couple of weeks, So Long Angel, the thinking man's pub blues band, will be at The National Theatre on Wendesday the 14th. They are well worth a listen; they are better at music than they are at web site design, trust me. ;-)

And don't forget the London Java Meetup next Monday, now featuring A-list Java blogger Hani.

Posted by Simon Brunning at 04:04 PM | Permalink | Comments (0)
I Rule!

Robocode is a blast, but I've been having trouble getting a robot which does even the simplest things. I wanted to code up, just to give myself a starting point, a 'bot which can circle around a given point, but my trigonometry wasn't up to it. :-(

Besides, I'm more into strategy games than I am into shoot-'em-ups, so perhaps CodeRuler will be more my speed...

See Conquer medieval kingdoms with CodeRuler.

Posted by Simon Brunning at 03:51 PM | Permalink | Comments (1)
Fail Fast

This one's for the team: Null is bad.

Null is bad because it allows errors to float around the system for quite some time before you get any symptoms (like bloody logging code falling over), and well behaved code fails fast, near the source of the problem. Mike gives some other nice examples of fail-fast code, like building stub test cases containing a single Assert.fail("Test not yet implemeted."), so you can't forget to build the test case, and having unimplemented methods in your mock objects throw runtime exceptions, so it's obvious if they get called.

Posted by Simon Brunning at 03:21 PM | Permalink | Comments (2)
July 01, 2004
JSTL and instanceof

I'm working on a JSP page. I'm using JSTL's c:forEach to iterate through a collection, and I want to display each item.

Thing is, the collection is heterogeneous; that is to say, it contains objects of different types. Each object might be a String, in which case I want to show it as-is. It night be a Date, in which case I want to use JSTL's fmt:formatDate tag to format it for me. Lastly, it might be a BigDecimal which again I'll want to format, this time using fmt:formatNumber.

The question is, how can I tell what type of object I have? JSTL's EL seems to lack an instanceof operator. Will I have to write my own taglib for this?

Posted by Simon Brunning at 02:33 PM | Permalink | Comments (6)
June 28, 2004
A Groovey Java meetup

London Java Meetup - 12 July 2004. This meetup's topic is Groovy, James Strachan's dynamic language for the JVM. I've had my say on this before - what does it have that Jython doesn't have? The main answer seems to be that Groovy has a Java-like syntax. Since I prefer Python's syntax, this isn't a big win for me. ;-)

Groovy's other big plus points are either shared with Jython (transparent access to the Java API, ability to create real Java classes) or pretty minor (Groovy has closures).

Python offers me the advantage that I can use (pretty much) the same language for COM scripting, Windows API madness, you name it. Can't do these with Groovy!

Anyway, as I said last time, I like the people, and we never manage to stay on-topic anyway, so I'll be there.

Oh, and a big thanks to Jez for organising these.

Posted by Simon Brunning at 10:50 AM | Permalink | Comments (2)
June 23, 2004
JSP 2.0

ONJava is running a nice series of articles on JSP 2.0 (as supported by Tomcat 5.x): JSP 2.0: The New Deal, Part 1, Part 2, Part 3 and Part 4.

We are still on Tomcat 4.1.x at my shop, and hence on JSP 1.2. But there's a new project coming up soon. I fancy adding AppFuse, Spring, Hibernate, XDoclet and JSP 2.0 to our toolkit this time around....

Also: get shot of your web.xml taglib directives.

Update: Oh yes, I'd like to use the display tag library, too.

Posted by Simon Brunning at 01:42 PM | Permalink | Comments (0)
June 22, 2004
JDBC Drivers for SQL Server

We are using Microsoft's own JDBC Driver for SQL Server. It seemed like the natural thing to do. It's not given us any trouble so far.

If it does, I'll bear jTDS in mind: jTDS is 100% JDBC 2.1 compatible, supporting forward-only and scrollable/updateable ResultSets, multiple concurrent (completely independent) Statements per Connection and implementing all of the DatabaseMetaData and ResultSetMetaData methods. A number of JDBC 3.0 features (such as retrieval of generated keys) are also implemented. It also claims to be the most stable and fastest available complete JDBC driver for SQL Server.

(About using SQL Server in the first place; yes, yes, I know. Not my decision. I registered my dissent, but it was out of my hands.)

Posted by Simon Brunning at 04:40 PM | Permalink | Comments (7)
June 14, 2004
I could really use a beer

And as luck would have it...

Posted by Simon Brunning at 01:38 PM | Permalink | Comments (0)
June 09, 2004
BeanUtils type conversion

Six Sides To A Box - BeanUtils, Digester, and Type Conversion. Useful stuff.

Posted by Simon Brunning at 05:54 PM | Permalink | Comments (1)
5250 fans aren't Luddites

Well, not all of them, anyway. ;-)

One of our biggest recent projects was a new Java front end to an old 5250 green screen application of ours. The majority of users were more than happy with the pretty new front end, but some were not. These users were finding that the GUI slowed them down.

Mouse considered harmful: "Have you ever watched an experineced heads down data entry clerk do thier job? With a green screen system they rarely look at the keyboard and in most cases ignore the screen. They are responding to audible feed back (key press clicks, console beeps, etc) with thier eyes focused on the data to be input. They remember key sequences (press 1, A, down arrow 2 times, F2 to save) to navigate. A mental model of the screens become engrained in thier head. They "SEE" the application in thier head and that vision is updated realtime. They know the system because it's predictable."

What's more, if the 5250 user gets ahead of the system, it doesn't matter - the 'dumb' terminal will just buffer their keystrokes, and play them back when the application is ready for them. So, they can enter data as fast as they can hit the keys.

I heard a story, probably apocryphal, about a salesman trying to sell what IBM calls a 'refacing' tool, and what the rest of the industry calls either a screen-scraper or a 'lipstick-on-a-pig' tool. He demonstrated how easy it was to slap a new front end on the 5250 app. The head of the data entry department then snipped off his mouse with a pair of scissors, and asked him to enter some data. "It costs us a penny every time one of our data entry people takes their hand off the keyboard," he explained.

Anyway, I've implemented a keystroke buffer for a Java app once before, and I know it's pretty much top of our to-do list for our pretty new front end. Perhaps then we can wean the last of our 5250 users onto it...

Via James Robertson.

Posted by Simon Brunning at 01:45 PM | Permalink | Comments (2)
June 07, 2004
A Glimpse of Light

I was back in the office on Friday, and I got to fix a Java bug! (Someone who should have known better had put a bunch of logging code into the application, and he used toString() all over the place, so we were getting superflous NullPointerExceptions.

I'm back on site wading through RPG again today. :-(

Posted by Simon Brunning at 04:52 PM | Permalink | Comments (1)
June 02, 2004
Night of the Living Geeks

London Java Meetup - 14 June 2004.

Since I seem to be turning into a full time RPG programmer these days, I wonder if they'll stop letting me come?

The notional subject for discussion this time is J2EE meets .NET. This isn't especially interesting to me, but since I like the people, and we never manage to stay on-topic for more than a few minutes anyway, I'll not let this put me off. ;-)

Update: Sam might be demoing Naked Objects. Naked Objects looks fairly interesting; it's in its early days, but it might just turn into a Synon/2 for the 21st century.

Update June 14th: It looks like Sam's objects will be remaining fully clothed, unfortunately.

Posted by Simon Brunning at 03:23 PM | Permalink | Comments (0)
Omniscient Debugging

Omniscient Debugging. I find it hard to believe that you can do this - it's just plain black magic so far as I'm concerned. Cool beyond words, though.

Via