Categories
Uncategorized

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.

  
    javax.servlet
    servlet-api
    2.5
    provided
  
  
    javax.servlet.jsp
    jsp-api
    2.1
    provided
  
  
    javax.servlet
    jstl
    runtime
    1.2
  

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.

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

  
  
    Archetype Created Web Application
  

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

Categories
Uncategorized

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.

  
  

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.

Categories
Uncategorized

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.

Categories
Uncategorized

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!

Categories
Uncategorized

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. 🙂

Categories
Uncategorized

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.

Categories
Uncategorized

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. 😉