Search code examples
javaantjava-7java-6

How to enforce Java 1.6 standard during compilation in Ant?


I use JDK 7. But, there is a class I want to compile to Java 6 standard (means, it must be able to run on JRE 6). My Ant compilation command is as following:

<target name="myAntTarget">
        <javac srcdir="${mysrc.dir}"
            destdir="${mydest.dir}"
            source="1.6"
            target="1.6"
            deprecation="on"
            debug="on"
            classpathref="mypath"
            includeAntRuntime="false"
        >
            <include name="com/mypackage/MyClassName.java" />
        </javac>        
</target>

Strangely, the Java 6 standard is not consistently enforced.

When I wrote

ProcessBuilder.Redirect xxx = ProcessBuilder.Redirect.INHERIT;
System.out.println(xxx.toString());

The code is successfully compiled (unexpected), even though ProcessBuilder.Redirect has been included in Java only since Java 7 (http://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.Redirect.html). So certainly it can't run properly in Java 6.

However, when I wrote

try (BufferedReader br =
        new BufferedReader(new FileReader("C:/myrandomfile.pdf"))) {
    final String sss = br.readLine();
    System.out.println(sss);
}   

The code fails to compile. The error message (from Ant) is

error: try-with-resources is not supported in -source 1.6

This time, the compiler can detect the problem.

How to ensure that Ant consistently fails to compile (and throw appropriate error message) whenever the java file it compiles is not Java 6 compatible?


Solution

  • The source attribute enforces source code level compliance. By assigning source=1.6, you ask the compiler to ensure that the source code, from a syntax point of view, is compatible with the Java 1.6 specification.

    The target attribute to value X tells the compiler to generate class files that will be readable by JVMs of level that is at least X. By assigning target=1.6, you ask the compiler to generate classes that will only be readable by JVMs of level 1.6 onwards.

    Neither of these parameters dictate to the compiler which JDK libraries to use as compile-time dependencies. If you want to ensure that your code can run on a Java 1.6 JVM, then you must use the javac compiler included with Java 1.6. Also, you're likely to either omit the target parameter altogether, or to keep it - but if you keep it, ensure that it is, indeed, set to 1.6.