Archive for the ‘Java’ Category

One artifact/file per build process

Tuesday, September 20th, 2005

Building on my most recent post, another objective we have at work is that each build process (which maps to one CVS module) generates one and only one artifact (e.g. a single WAR, plain old Jar, or a Javaapp Jar). There are certainly dependencies between modules but any deployable artifact that gets built (website.war, batchjobs.jar, xmlfeeds.jar, etc…) should be self-contained and include all of its dependencies such as Spring, Hibernate, etc.

This brings me to the Javapp Jar which I'm a huge fan of. A WAR is great because it can contain class files, JSP's, jar dependencies, and what have you. When you want to deploy it into production you have one self contained file that the release engineer can move live. A Javapp Jar is basically the same thing, it's a Jar file that contains your classes and files as well as all of those of your dependencies. For non Maven users you can also do this easily with ant using the zipgroupfileset task.

This makes the job of the release engineer much easier. For example rather than having to deploy batchjobs.jar, spring.jar, hibernate.jar and 10 other dependencies to our production batch processing server, instead we have a single batchjobs.jar that gets moved to production. That single Jar file contains our batch job classes, our bizlogic jar, spring, hibernate, and everything else in a single self contained file.

One WAR for development, staging/QA, and production

Saturday, September 17th, 2005

One of our objectives at work with our build process is that whichever artifact (jar/war) gets built, that it can be exactly the same everywhere, whether it's running on your workstation, cruise-control, qa staging server, production, etc. In other words, when we go to deploy the production WAR we don't want to have to build a custom “production” version just because the log4j properties or database connection information is different between deployment environments. My feeling is that this is a very good thing because when the WAR passes QA, we can just take the WAR from the QA server and move it into production.

There are many different ways to achieve this goal. Karl Baum blogged about his approach a while back. I thought I'd share how Andy set this up at work using Spring. So far it's been working great for us.

Essentially we allow properties in the WAR or Jar to be overridden using java run-time parameters as follows: java -Dhibernate.dbhost=mysql-prod.domain.com -Dhibernate.connection.username=produser -Dhibernate.connection.password=prodpass etc…. So in each environment we we have JAVA_OPTS set so that when we run Tomcat or run our batch jobs that reside in a Javaapp Jar, we don't have to build a new artifact for each environment.

Spring comes to the rescue here with it's propertyPlaceholderConfigurer bean. Here's what it looks like:

    <bean id="propertyConfigurer"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:conf/deployment.properties</value>
                <value>classpath:conf/database.properties</value>
            </list>
        </property>
        <property name="systemPropertiesModeName">
            <!-- allow system properties to override ours -->
            <value>SYSTEM_PROPERTIES_MODE_OVERRIDE</value>
        </property>
    </bean>

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource"
        lazy-init="true">
        <property name="driverClassName">
            <value>com.mysql.jdbc.Driver</value>
        </property>
        <property name="url">
            <value>jdbc:mysql://${hibernate.dbhost}:3306/somedb?autoReconnect=true</value>
        </property>
        <property name="username">
            <value>${hibernate.connection.username}</value>
        </property>
        <property name="password">
            <value>${hibernate.connection.password}</value>
        </property>
    </bean>

So by default the WAR or Javaapp Jar will get it's properties such as database connection information from database.properties but anything in database.properties or deployment.properties can be overridden.

The major downside with this approach is that it won't work well in a hosted environment with lots of WAR files deployed on the same app server. If you've tackled this problem in a different way that works let me know how you've gone about it!

Changing a URL without changing all your HREFs

Tuesday, July 26th, 2005

When writing JSPs using Spring MVC and Struts I've found myself hard-coding URL's and it just doesn't feel right. Later when I decide to change the URL of a page I have to go through and search replace that URL in a dozen other pages… and it pains me!

Tapestry uses the PageLink to do this quite gracefully. In your Tapestry HTML files you simply put <a href=”#” jwcid=”pageX”>Click me</a&gt and then Tapestry will fill in the correct URL of pageX.

David Geary also blogged about adding this feature to Shale for JSF.

Basically, my feeling is that the actual URL of a page should only live in one place and I should be able to change it to my hearts content without having to edit all of my other JSP files to point them to the new location.

What are some best practices or ideas for JSP based apps to help me avoid hard-coding URLs in the pages?

Update: so far I've received one good suggestion of using a resource bundle to store the actual URLs and using a taglib to fill in the values.

Update 2: one other point I neglected to mention is that having your application resolve the URLs for you has the added benefit that when there is a bad link you should get a page compilation error. Tapestry does this through the PageLink component which means you won't get a page in production that has a bad application internal URL. Whereas with Struts and SpringMVC it's much easier to get a bad URL into production because it either requires a QA person to try clicking on each link in the page, or you need an automated link validation test.

Search Engine Friendly URLs in Java

Saturday, July 16th, 2005

At work I’ve been looking into doing search engine friendly URL’s in Java. For those not in the know, a search engine friendly URL is of the form http://www.domain.com/foo/value1/value2 as opposed to the more typical approach of http://www.domain.com/foo?param1=value1&param2=value2.

In my research so far there seem to be several approaches commonly used to solve this problem.

1. The most common seems to be URL rewriting using Apache’s mod_rewrite. In Java there’s also a servlet filter called the UrlRewriteFilter. I think if you’re going to do this for Java backed pages then using a servlet filter is definitely advantageous over using Apache to handle it so that it works in a plain old tomcat dev environment also.

2. Wildcard servlet mapping is another possibility (without using a servlet filter). By mapping something like /* to your dispatcher servlet, you could use the path info in the MVC controller to pull out the parameters. I’m not crazy about this approach because it requires your MVC controllers to be smart and therefor use a non-standard approach to get request parameters.

3. The last option I’ve heard about is just writing your own servlet filter. For example if you know that your search engine friendly urls will always be of the format /foo/param1/value1/param2/value2/etc… then you could simply write a custom servlet filter that disected the uri and filled in the request parameters. You could probably just do this with a regex using option 1 as well.

So far I’m liking options 1 and 3 the most because they take a nice AOP style interception approach that allows you to code MVC controllers expecting regular request parameters. Anyhow, if you’ve heard of how other folks have solved this problem or have suggestions or ideas, I’d be curious to hear about it!

Two additional Ruby features I wish were in Java

Wednesday, July 13th, 2005

I’ve been tinkering with Ruby a little, mainly so I know what I’m missing since a lot of people really seem to dig it. Ruby has a lot of nice features that I like including mixins, closures, Rails scaffolding, active record ORM, etc…

The things I don’t like about Ruby are that it’s weakly typed which I’ve written about before and has a very terse syntax that makes it hard to understand at times if you don’t “know” Ruby. For example when I first started looking at Ruby code these constructs left me wondering: variable, :variable, *variable, @variable, |variable|, and @@variable.

While playing with Ruby over the weekend I found two more language features that Ruby has that I really wish we had in Java:

1. Immutability: you can freeze objects so that any attempt to change an immutable object will result in TypeError exception reporting “can’t modify frozen TYPE”. I would love to have this in Java.

2. Native getter/setter support: declaring a list of variables as attr_reader or attr_writer allows getter/setter functionality of a variable without writing/maintaining any redundant getter/setter code, yet if necessary, you can override the default getter/setter behaviour without affecting the API. In Java it drives me crazy that we waste time and clutter our classes unnecessarily with hundreds of lines of getter/setter methods that all do the same thing. Java really needs a construct for default getter/setter behaviour on selected variables that can be overriden when necessary.

The only other feature that neither Ruby nor Java have that I’ve written about before is language support to guarantee that a method variable cannot be passed as null such as public boolean doSomething(notnull Object foo)

What features do you wish you had in Java that you’ve seen in other languages?

Only crazy people redeploy a webapp after editing a class or JSP

Wednesday, June 29th, 2005

I tell ya, one of the things I love about Ruby, Python, Perl, etc… is that when you make a change to a the code or presentation layer, all you do is hit refresh in your browser.

With java and servlet containers it's a bit more difficult but can be almost as elegant if you know how to setup your dev environment properly. I'm often surprised by how many Java developers rebuild and redeploy the whole webapp for every change they make to say the domain model, a controller, or even simple JSP pages. Imagine changing a JSP, then sitting around for 15 seconds to a minute while it redeploys to make the change and then do that 100 times. It's a little too reminiscent of walking a stack of punchcards down the hall and quite frankly it's crazy, because as many know, there's a better way.

Here's how I like to address this issue is as follows.

1. Make sure you can build an exploded war and that when you rebuild, only updated classes, JSP files, etc… are copied into the exploded war. As a Maven user I do this with maven war:webapp, you can also do it with Ant or even better, through your IDE.
2. Make sure your servlet container knows to automatically check for and reload classes when they are updated in the exploded war. If you're a Tomcat user like me set the reloadable attribute in your Context to true. Never set reloadable to true in production!
3. Fire up Tomcat and mount the exploded WAR directory in Tomcat thought the manager application.

Now, make a change to class or JSP and run whatever command updates that class or JSP into the exploded WAR (e.g. ant, maven, or best of all setup your IDE to do it when you hit save). Hit refresh, Tomcat will detect the new class or JSP file and you'll see your results immediately.

Bottom line, even in Java you can update a class or view and see the results immediately by hitting refresh in your browser. It's just a bit more of a PITA to get setup initially!

You can use XMLUnit without subclassing

Tuesday, June 28th, 2005

I had almost written off XMLUnit because I assumed it required subclassing XMLTestCase and I already have my own JUnit TestCase sublass that I like to use. However, to my delight I discovered they have refactored out an XMLAssert class full of static assert methods so that you can call them anywhere.

If you've never heard of XMLUnit it's a nice library that lets you compare XML documents for equality or subsets thereof using XPath. Very nice for creating unit tests to verify that the XML your classes are returning is what you expect without worrying about linebreaks, whitespace, and other pesky formatting details if you were trying to do it with String.equals or String.indexOf.

It's still too soon to upgrade to J2SE 5.0

Friday, May 27th, 2005

We're a small enough company that we can make the move to J2SE 5.0 whenever we want but we're holding off right now for 3 main reasons:

1. I'm not interested in being an early adopter unless the gain will give us some major competitive or efficiency advantage. While I'm looking forward to autoboxing, generics, annotations, enumerations and such I don't think they'll really give us major gains in either of those areas.
2. While IDE support for J2SE 5.0 is improving I don't know anyone that's tried it that hasn't run into some issues. Same goes for library support.
3. It's still relatively new to the 247 production world and since we fall into that category I want to be very confident in the stability of the JVM.

So when's the right time to make the switch for me?

1. When friends start asking me “why are you still running 1.4?”.
2. When I hear friends talking about their companies upgrading production servers to 5.
3. When the libraries and app-servers we use start requiring 5.

In summary, I think the right time to move is after the early adopters have gone through most of the pain and moving to J2SE 5 starts to become mainstream. All of that said the time is right to start playing with 5, setting up your continuous integration server to build and run unit tests with both 1.4 and 5, and so on.

Tired of checking for null arguments in the method body

Saturday, May 7th, 2005

One thing I find annoying at times is adding in null checks in a method body to throw an IllegalArgumentException for method arguments that shouldn't ever be null.

Most of the time as programmers we skip it and rely on the fact that a null pointer will get thrown somewhere further down in the method body. That's not ideal though, especially in a non-transactional system where you can't rollback easily (e.g. writing data to a file or network). I also find myself looking at API's sometimes wondering if a certain field is optional and then going to the javadoc only to find no mention of what happens if I pass in a null for a seemingly optional field.

Ensuring that a method argument is non-null is so cookie cutter that I feel like it should be part of Java. We can declare objects as final so they can only be assigned once, why not be able to declare them as required or notnull so that they can never be assigned null? For example I would like to write a method that looks like this:

public Foo doSomething (final required Bar bar) {
	// Passing in null would throw an IllegalArgumentException
	// or a brand new RequiredArgumentException

rather than what we currently have to do if we want to guarantee that a non-primitive is not null:

public Foo doSomething (final Bar bar) {
	if (bar == null) {
		throw new IllegalArgumentException("bar is required");
	}
	// Now that we've established bar is not null we can start doing
	// non-transactional stuff like writing to a file or network

I also find the former more readable than the latter since even without good javadoc I know it's expecting a non-null value based on the method signature.

Code coverage from within the IDE followup

Tuesday, April 19th, 2005

Two weeks ago I wrote about code coverage from within Eclipse using djUnit. Since discovering djUnit I've become a huge fan of code coverage in the IDE to improve the TDD process. Since we're going to be using Idea at my current company I looked around and discovered that Clover (commercial software) has both Idea and Eclipse plugins which is what we'll be using. Another really nice coverage tool that is open-source is Emma and as it turns out Emma has an Idea plugin.