Skip to content

Finding Too-New Code

Occasionally you'll run into a situation where compiled source won't run on a different machine because its JVM is older than yours. Sometimes you can't upgrade the JVM on the other machine because it runs a large piece of software that doesn't support a newer JVM yet [^1]. So, given a large body of code and a relatively new version of the JDK, how can we scan the codebase to find code that won't run on an older version of Java? Simple! use the -source parameter to javac. Lets do an example:

import java.util.*;
class GenericsTest
{
        public static void main(String[] args)
        {
        ArrayList<String> stringArray = new ArrayList<String>();
        stringArray.add("Hello ");
        stringArray.add("World.");
        printStrings(stringArray);
        }
        static void printStrings(Collection<String> c) {
                for (Iterator<String> i = c.iterator(); i.hasNext(); )
                        System.out.println(i.next());
        }
}

The code above is a basic Hello World app that uses Generics--a language feature that is only available in Java 1.5 and higher. Lets suppose our code needs to run on a machine with only Java 1.4. Here is how we find the code that is "too new" for us to use:

GenericsTest.java:6: generics are not supported in -source 1.4
(try -source 1.5 to enable generics)
        ArrayList<String> stringArray = new ArrayList<String>();
                                         ^
1 error

Here the -source 1.4 parameter was used when compiling the file. It told the compiler to obey the Java Language Spec as of Java 1.4, forcing any newer syntax to fail even though the compiler could support it.

Notice that the compiler told us what was wrong (i.e. Generics aren't supported in Java 1.4), and where the error occurred. This is a really nice feature. Its like having several JVMs in one.

Also note there is a -target option as well. It causes the generated classes to be compliant with different JVM levels. Really interesting concept...being able to write source code in a higher-level JVM and having the compiler target the bytecode for a JVM running at a lower Java spec level. I'm sure there are many interesting options in this space.

[^1] like Weblogic 10, which only supports Java 1.5 even though Java 1.6 has been available for over a year, but I digress...