JSPs in Maven

Every now & then I need to whip out a quick webapp. Normally, I would prefer to use something like freemarker or velocity. But JSP is standard, and it’s everywhere. Despite it’s inability to be secure, it is convenient. And that’s gotta count for something right?

But, I never quite managed to get everything working. So whilst looking at tclogview, I figured it out. First of all, you have to get the dependencies correct.

  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
  </dependency>
  <dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.1</version>
    <scope>provided</scope>
  </dependency>
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <scope>runtime</scope>
    <version>1.2</version>
  </dependency>

So you need to pull in both the servlet API and the JSP API. They’re both “provided” scope, which means that they have to be available when compiling, but they don’t need to be packaged as they’ll be there already. I’m not sure why you need the JSP API. When I was playing with NetBeans, it appeared to be necessary to get bits of the editor working correctly.

You also need to pull in the JSP Standard Tag Library. It’s not mandatory, but you won’t get far without it. The only trouble is that there are a gazillion different versions on the central repository with no clear clue as to which one should be used. This version appears to work OK. Importantly, it contains the taglib descriptors. Also, we set the scope to “runtime” as it’s not needed at compile time.

This gets you started. The other thing that you need is a correct web.xml. Different versions of the deployment descriptor get you different features in your JSP page. Go figure. Looking in the JSP spec right now, I can see §JSP.3.3.2:

The default mode for JSP pages in a Web Application delivered using a web.xml using the Servlet 2.3 or earlier format is to ignore EL expressions; this provides for backward compatibility.

The default mode for JSP pages in a Web Application delivered using a web.xml using the Servlet 2.4 format is to evaluate EL expressions with the ${} syntax. Expressions using the #{} are evaluated starting with JSP 2.1. See Section, “Backwards Compatibility with JSP 2.0″ for more details on the evaluation of #{} expressions.

This caught me out for a while as I was trying to use the new syntax and it wasn’t getting interpolated. I want to use JSP 2.1, so I reckon it’s easiest to use servlet 2.5. That means I need a declaration that looks like this in my web.xml.

  <?xml version="1.0" encoding="UTF-8"?>
  <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"></web-app>

Why was this a problem? Because the maven-archetype-webapp archetype generates a web.xml that looks like this.

  <!DOCTYPE web-app PUBLIC
    "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd" >
  <web-app>
    <display-name>Archetype Created Web Application</display-name>
  </web-app>

Ooops. This issue was filed as ARCHETYPE-106 over a year ago. Fixing that would have made my life a lot easier.

tclogview

I had a quick thought this morning: I’m always logging in to servers to nose around in their logs. So why not a quick webapp to view the logs? I’ve done this before, but not in Java. So, I wrote tclogview in between stuffing down goose and entertaining the sprog.

To use it, check it out and run mvn package. Then copy target/tclogview.war into a ${catalina.base}/webapps. You’ll also need to set up a user with the tclogview role. That means adding these two lines to ${catalina.base}/conf/tomcat-users.xml.

  <role rolename="tclogview"/>
  <user username="chip" password="lumberjack" roles="tclogview"/>

There’s a load of improvements that could be made to it. Some Ajax to implement tail -f behaviour (using byte ranges for preference) would be lovely. But it seems useful as is.

P.S. In case you’re not happy with git, here’s a source zip and a prebuilt war file.

Commit Messages

I’ve been using git for most of this year. It’s been a really excellent ride, and the things it enables are wonderful. But one of the things I’ve found most handy is a convention.

The commit message is treated like an email: one line of subject and then a few paragraphs of explanation. Keep the subject line short so you don’t have scroll bars when they’re displayed.

This works really well for scanning the history of a project — you can get at at a glance overview of what’s changed and then click on a single commit for more detail. I’ve tried to carry this over to subversion projects as well.

Exception Handling Whinge

I hate this.

  try {
    // … some xml parsing stuff …
  } catch (XmlException e) {
    logger.error("Can't parse XML", e);
  }

Why? Because it found a problem, and then carried on as if nothing happened. Which leads me to debugging NullPointerExceptions half a mile away when it’s quite obvious that processing should have halted right there. And as an added bonus, we now get two stack traces in the logs for the price of one.

So what’s the right thing to do? Obviously it depends on the situation, but as I mentioned before, rethrowing the exception wrapped in a RuntimeException isn’t a bad default.

I could start on about how I wish people would think when writing code, but hey, I might as well bang my head against a nearby wall for some more fun instead. Happy ow! happy ow! joy ow! joy!

google talk for google apps users

I was playing with building an XMPP bot at the weekend. The trouble was my google talk account, but it’s part of google apps for your domain. Why does this matter? Take a look at my ID:

dom@gapps.mydomain.com/Work

When you feed this to an XMPP library (xmpp4r-simple in my case), it attempts to find a server located at gapps.mydomain.com. Which isn’t correct, my server is talk.google.com or somesuch.

But there’s a get-out clause in the spec (RFC3920).

Client-to-server communications MUST NOT proceed until the DNS hostname asserted by the server has been resolved. Such resolutions SHOULD first attempt to resolve the hostname using an [SRV] Service of “xmpp-client” and Proto of “tcp”, resulting in resource records such as “_xmpp-client._tcp.example.com.” (the use of the string “xmpp-client” for the service identifier is consistent with the IANA registration). If the SRV lookup fails, the fallback is a normal IPv4/IPv6 address record resolution to determine the IP address, using the “xmpp-client” port of 5222, registered with the IANA.

So, all it takes to get this working is some DNS tomfoolery. I added this to the zone file for mydomain.com1:

_xmpp-client._tcp.gapps IN SRV 5  0 5222 talk.l.google.com.
_xmpp-client._tcp.gapps IN SRV 20 0 5222 talk1.l.google.com.
_xmpp-client._tcp.gapps IN SRV 20 0 5222 talk2.l.google.com.
_xmpp-client._tcp.gapps IN SRV 20 0 5222 talk3.l.google.com.
_xmpp-client._tcp.gapps IN SRV 20 0 5222 talk4.l.google.com.

Where did I find this information from? Well, it wasn’t on google’s help, but the DNS can tell me. There’s no XMPP server on gmail.com, yet you can still use your gmail address as a JID.

  host -t srv _xmpp-client._tcp.gmail.com

Now I can sign on as dom@gapps.mydomain.com — lovely!

1 The privileges of being an ex-sysadmin. :)

maven in anger

I’ve ranted about Maven before. As it happens, I still stand by much of what I said. But, I’ve come to realise how superficial these criticisms are.

Earlier this year, one of the libraries that I have a hand in maintaining needed to be used by a maven project. Whilst I could have just written enough of a POM to specify my dependencies, I figured that it would probably be easier to just switch the build system to maven.

Plus, this particular library is meant to be used as a webapp. The existing ant build builds a war file. But really, the webapp is just for exercising the library, it’s not the main point. Switching to maven makes it ideal for splitting into two different projects.

So I went ahead, and made the change. I did it in a slightly invasive manner (moving my source directories around to fit the expectations of maven). But the end result is that I have found the project easier to work with. Previously, the dependencies of the project were very unclear. Switching to maven and running mvn dependency:analyze quickly spotted quite a few jar files we “depended” on weren’t actually used. And one of the nice things is that maven embeds the version number1 in the resulting jars (previously it had been a chore to figure out what version was in use).

This turned out reasonably well, although the main benefits were yet to be had. These are down to the huge growth in the maven tooling ecosystem, particularly this year.

  • Eclipse support has been improving by leaps and bounds. Initially I went with q4e (now IAM), but I later switched to m2eclipse as it seems to be a more fully-featured plugin right now.
  • NetBeans has pretty good maven support, even though it’s lacking a couple of useful features in m2eclipse. But it’s also very nice as NetBeans is then entirely driven by the POM — it doesn’t create a bunch of files based on the POM. The POM is the project.
  • Hudson makes it an absolute snap to get a maven project into continuous integration. Hudson is the only java project I’ve ever seen that comes close to the simplicity of a wordpress install. Way to go Kohsuke!
  • The nexus repository manager makes using maven much more practical (even for a single developer) as it vastly speeds up downloads and reduces your dependency on central. Plus, you can use it as a place to deploy your own goodies once you’ve built them.
  • Maven: The definitive guide — the maven documentation, whilst there’s a good deal of it, isn’t exactly integrated well. This book has been an enormous eye opener about how to do things “the maven way.” Plus the in-depth coverage of things like the assembly plugin was tremendously helpful.

With all these tools in place you find the integration really starts to come to the fore. For example, I noticed that hudson had a findbugs plugin. I installed the plugin in hudson, activated the findbugs plugin in my POM (about 4 lines of XML) and got:

  • Pretty graphs of the number of bugs found in each build.
    findbugs-trend.png
  • Detailed breakdown of each findbugs report in each build, including source code views of where the problems lie.

    hudson-findbugs-fixed.png

  • Indicators showing how many bugs I had introduced into each build (or hopefully removed).
    hudson-findbugs-warn.png

In short, I got a lot of value out of a (relatively) small change. And the same technique can be applied almost identically on the next maven project. And the one after that. And so on. Consistency has been one of the great virtues of maven for us.

The end result is that now most of our projects are maven projects at work (and I’m also using maven at home).

Of course, it’s not all plain sailing. I’m still seeing something weird to do with m2eclipse and WTP. But I’m confident that I’ll figure it out and it’ll be fixed.

Overall, I reckon that maven is something you should be taking a look at if you’re building Java projects. I know some people had taken a look at Maven 1 and come away with a sour taste. Now’s the time to check back and see what’s changed.

1 Even though I later had to change how this was done.

NetBeans Correction

I’ve just been reading Top Java Developers Offer Advice to Students and noticed something Tor said, which addressed one of my issues about NetBeans. Thanks, Tor!

For example, in NetBeans, you don’t have to write the left-hand side in assignments when you’re calling a method. Just write this:

	"foo".indexOf("o");

Move the caret inside indexOf, the method name, and type Alt-Enter. Assuming you’re calling a method that has a return value, and you’re not already reading the return value, NetBeans will generate the left-hand side of the assignment — including the type declaration — for you:

	String indexOf = "foo".indexOf("o");

Advice to students? I got a lot out of it. ;-)

Removing CAPS LOCK on OS X

This has been bugging me for a while, but I’ve just gotten around to doing anything about it. I hate the caps lock key. I never use it and I’m always triggering it by accident. Thankfully, it’s fairly simple to disable. First go into System Preferences and choose “Keyboard & Mouse”.

System Preferences: Keyboard & Mouse

Now on the “Keyboard” tab, there’s a button in the bottom left that I’d managed to miss entirely, “modifier keys”:

System Preferences: Keyboard

This pops up a little dialog pane that lets you choose the behaviour of the caps lock key.

System Preferences: Modifier Keys

I chose control, as it’s not entirely useless. In fact, on my macbook, it’s a damned sight more useful than the hobbled control key which has been displayed by an “Fn” button.

NetBeans 6.5

Today NetBeans 6.5 got released. Congratulations, guys! I’m primarily an Eclipse user1, but I keep hearing about NetBeans through the Java Posse and heck, I even subscribe to the NetBeans podcast to try and keep an eye on what’s up. Every time a new release comes out, I give it a whirl.

So this time, now I’m looking at 6.5. And it’s really nice on a lot of fronts. Most of the improvements in 6.5 aren’t directly relevant to me — they’re related to scripting languages I don’t use. What I’m particularly interested in is the core Java SE support. And NetBeans is really very good. It’s just not quite as good as Eclipse. Or (more likely) I can’t figure out a way to make it do what I want.

There are a couple of things I do all the time in Eclipse. First, ⌘-T, which shows type hierarchies. But that’s putting it simply. If you pop it over a class, it shows the subtype hierarchy. Press it again and it shows the supertype hierarchy. What’s neat is that if you do it over a method, it greys out those classes that don’t have an implementation of that method.

⌘-T in Eclipse

But what makes it particularly useful is that it doesn’t pop up a proper window, just a little floater (I have no idea what it’s really meant to be called). As soon as you click somewhere, it disappears. This makes it incredibly fast to navigate code.

As far as I can see, the closest that NetBeans has is “File Hierarchy” on ^⇧F12. But this pops up a big old clunky dialog box.

That’s one more thing about NetBeans — the key bindings are weird. And I speak as a long time emacs user. Now I’ll learn them (as it’s annoying to carry my customisations everywhere). But they conflict badly with a lot of Mac keyboards, because they’re extremely function-key heavy, and the mac likes to take over the function keys for itself.

The other Eclipse feature I use the whole damn time is “assign to local variable”. Yes, you can curse me for being damned lazy. But, I want to be able to type new PhoneImpl("01273", "123456"); then hit a key and get it assigned to a variable. In Eclipse, that’s ⌘-T L. I couldn’t find a way to do it in NetBeans. The compiler knows what type it’s going to be. Why should I have to remember? Otherwise I’d be back in Emacs.

There are a couple of missing refactorings I use a lot: “Extract to local variable” and “inline local variable”. Both are easily replaced with cut’n'paste 90% of the time.

One particular feature that Eclipse and NetBeans both share is terrible defaults for exceptions. Here’s Eclipse’s default:

  try {
      new URI("http://example.com/");
  } catch (URISyntaxException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
  }

And here’s NetBeans.

  try {
      new URI("http://example.com/");
  } catch (URISyntaxException ex) {
      Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
  }

Both of these are fundamentally broken, and going to catch out dozens of unwitting programmers who don’t know any better. Yes, you can change the defaults, but most people don’t.

Anyway I don’t want you to think that I’m totally down on NetBeans. The new release maintains what I first saw in 6.1: a very fast, full featured IDE. It’s dead easy to get going, and there is loads of documentation. I find the project view to be much more useful and better organised than the eclipse view of the same.

NetBeans Project View

I suspect that most of the problems I’ve been having are down to the fact I’ve been using Eclipse for 3 years, and NetBeans for a few hours at best.

One thing I did like very much is that there’s builtin Maven support. I downloaded the Java SE installation2, went to the plugins window and selected “maven”. About a minute later I had a working installation. And I can create new projects with archetypes really simply. And it’s dead simple to add new libraries as needed (I’m guessing it uses the nexus indexer to look stuff up). The only missing thing is the dependency viewer, but I can always run dependency:tree and dependency:analyze manually.

Funnily enough, where I think NetBeans really wins is the dynamic languages support. I’ve been following Tor’s blog for a little while and I’m incredibly impressed with what has been achieved in the Ruby support. For developing Ruby code, I head straight for NetBeans. Most of the issues I’ve outlined above are really specific to statically typed languages. For dynamic languages like Ruby (and now PHP and Python), what NetBeans gives you is a big win over the standard text editor.

Heck, the JavaScript support is pretty decent too. The first thing I did today was open up jslint4java and jump into fulljslint.java. That’s some pretty scary code. But NetBeans handled it with no issues at all. And it even pointed out a warning that’s easy to overlook (a duplicate hash key).

So, the big question is — am I going to use NetBeans? For any Ruby stuff, there’s no question. For Java stuff, I’m going to give it a try. After spending enough time with it to write this, I’ve already figured out enough stuff to use it a bit more successfully.

1 Apart from Emacs, Vim and TextMate. ☺

2 I didn’t like the look of the Java EE version — I don’t really need 3 application servers bundled, do I?

The best subversion client

The best subversion client I’ve used to date? git. It’s so script-friendly! This morning somebody asked me for a complete history of a project in CSV format. Using my nicely cloned repository, it was a simple matter of giving the correct format to git log.

  ⇒ git log --pretty='format:%h,%ai,%an,%s' | head -5
  f584913,2008-09-26 21:58:02 +0000,Dominic Mitchell,Pull out a base class for OptionInstances.
  803a32a,2008-09-26 21:57:38 +0000,Dominic Mitchell,Organise imports.
  1cb0132,2008-09-26 21:57:17 +0000,Dominic Mitchell,Switch from a Set of OptionInstance to a Map from Option to OptionInstance.
  a0c1efd,2008-09-26 21:56:56 +0000,Dominic Mitchell,Introduce OptionInstance.
  a211ae3,2008-09-26 21:55:59 +0000,Dominic Mitchell,Use standard idiom for emptying a Set

I love how git embodies the Unix toolkit approach.