Working with different JVM versions

At my company, we’ve got different application environments running on different versions of Java.We’ve recently upgraded some of our application servers to support Java 5.

This is all well and good except that many of our developers promptly converted their development systems to run and compile their code with Java 5 as well. They’ve forgotten about the one or two systems that were not upgraded.

Today I got to spend some time undoing a mess that was caused by a Java 5 binary being deployed to a Java 1.4 environment. The code, of course, failed to run, but due to the nature of the application, correcting the problem required some data cleanup and a restart of the application server.

Upon debugging, I came across the now all-to-familiar error message:

java.lang.UnsupportedClassVersionError: [Class Name Here] (Unsupported major.minor version 49.0)

which makes the problem clear.

Given that I’ve run into this issue multiple times in the 2 weeks since we upgraded our environment, I’m motivated to remind people about different JVMs and the importance of compiling to the correct version of your runtime environment.

One nice thing about Java is that every version of javac appears to support the creation of binaries that are compatible with any previous version of the JVM. Since different people use different tools to compile their code, I’ll cover a few different options.

  • Command-Line compilation with javac javac provides some a command-line argument for specifying the target JVM for your compiled code. If you are compiling in Java 5, but want a binary that will run in Java 1.4, you’ll need to add -target 1.4 to your javac command.
    javac -target 1.4 [remainder of javac params here]
  • Ant
    In ant, the javac task provides parameters that allow you to do the same thing. Just set up your javac task as follows:<javac target="1.4" srcdir="${source.java.dir}" destdir="${build.java.dir}" classpathref="project.class.path">
    <patternset>
    <include name="**/*.java" />
    </patternset>
    </javac>
  • Maven
    By default, Maven2 compiles binaries to be Java 1.3 compatable. You actually have to configure the maven-compile-plugin to support Java 5. In order to make things easier in my organization, we’ve created a parent pom for our projects that makes Java 5 the default. If you are building for a Java version other than 5, you’ll need to add the following your pom file (replacing the version numbers as appropriate):
    <build>
    <pluginManagement>
    <plugins>
    <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
    <source>1.4</source>
    <target>1.4</target>
    </configuration>
    </plugin>
    </plugins>
    </pluginManagement>
    </build>

Eclipse Tip: Task List

I was surprised to learn that most of my colleagues were not aware of the Task List feature in eclipse.

The Task List essentially creates a list of the To-Do items that you have placed in your code. It cross-links with your source files so that you can double-click on an item in the task list to jump to the TODO comment in your code.

Adding tasks is simple. Simply create a comment in your code such as:

//TODO: Do something here

Once this is done, eclipse will add “Do something here” as a task.

Here is what the task window looks like in my environment:

Sample Task List

From the Task view, you can organize the various TODO items from all files across all open projects. This makes it easy to keep up with the various reminders that you’ve placed in your files.

To enable the task view (if you’ve closed it, or if it wasn’t enabled by default), simply click on the Window menu, then Show View, then Tasks. Of course, if Tasks doesn’t appear in the Show View menu, select Other instead and find Tasks in the expanded list of views.

As you learn to use TODOs and the Task List in eclipse, you’ll find that you will be better able to keep track of the “future fixes” that you’ve thought of in your code. You’ll be able to find and clean up all the quick hacks that inevitably end up in your application.