Joseph D. Darcy's Sun Weblog

Joseph D. Darcy's Sun Weblog


20080229 Friday February 29, 2008

OpenJDK 6: Sources for b06 Published

The second code drop for OpenJDK 6, b06, was published earlier today, February 29, 2008, at the usual location.

This drop has several changes of note:

I expect with next drop will be available within two weeks, by March 14, 2008.

(2008-02-29 16:27:00.0) Permalink Comments [1]

20080225 Monday February 25, 2008

How to cross-compile for older platform versions

Besides compiling source code into class files suitable for the current JDK, javac can also be used as a cross-compiler to produce class files runnable on JDKs implementing an earlier version of the Java SE specification. However, just using
javac1.6 -source 1.4 Foo.java
is in general not sufficient to ensure that the resulting class file(s) will be usable in a 1.4 JDK. While this will work for many programs, benign evolution of the libraries and platform can cause failures if the program is run on the older JDK. As described in the cross-compilation example in the javac man page, the bootclasspath needs to be set to an appropriate library version too.

Targeting the right version of a library is important because libraries are not forward-compatible. That is, older versions of a library don't have facilities to handle calls to methods added in future versions of the library.

One fundamental job of javac is to translate symbolic name-based method and constructor calls in the source code to signature-based calls in the class file. Consider two versions of a library:

// Original
public class Library {
  public void foo(double d) {System.out.prinln("double foo");}
}

// Evolved
public class Library {
  public void foo(double d) {System.out.prinln("double foo");}
  public void foo(int i)    {System.out.prinln("int foo");}
}

and a client program

public class Client {
  public static void main(String... args) {
     (new Library()).foo(1);
  }
}

When processing a call site like ".foo(1)", javac goes through a nontrivial method resolution procedure. When Client is compiled against the original library, the method call resolves to foo taking a double parameter, Library.foo(double), which is the only choice in this case. This in turn is represented in the class file as "invoke the method in class Library named foo with one double parameter that returns void." However, after the foo method is overloaded, the call ".foo(1)" will get resolved as Library.foo(int) since it is more specific than the other applicable choice and the class file will instead "invoke the method in class Library named foo with one int parameter that returns void" Therefore, regardless of the -source or -target options given to javac, the class file of Client compiled against the new library will reference a method specific to the new version of the library. When such a class file is then run against the old version of the library, a NoSuchMethodError will result since Library.foo(int) is not present.

Library writers should be cautious about overloading in general and especially wary of adding new overloadings. Besides this cross-compilation wrinkle, which has occurred in practice, new overloadings can alter the operational semantics of existing source code, as seen in this case where the printed message is changed.

The @since tags that appear in the platform javadoc are not used by javac to constrain the set of methods considered available when setting -target. These tags are only informative and are not represented in the compiled class files on the implicit or explicit bootclasspath. While it would be technically possible to store this information in the class files, for example as annotations or class file attributes, method overloading is already very complicated and this extra complexity would increase fragility of the compiler for little benefit.

Additionally, even when the bootclasspath and -source/-target are all set appropriately for cross-compilation, compiler-internal contracts, such as how anonymous inner classes are compiled, may differ between, say, javac in JDK 1.4.2 and javac in JDK 6 running with the -target 1.4 option.

The most reliably way to produce class files that will work on a particular JDK and later is to compile the source files using the oldest JDK of interest. Barring that, the bootclasspath must be set for robust cross-compilation to an older JDK.

(2008-02-25 10:54:48.0) Permalink Comments [2]

20080218 Monday February 18, 2008

Coming in 2008: Tips and Tricks on Language Features

My bof proposal titled Tips and Tricks for Using Language Features in API Design and Implementation for a discussion on how to productively use generics, enums, and annotations was accepted for this year's JavaOne conference in the Java SE track. I'll be drawing on experiences creating and working with various JDK APIs, including JSR 269, and plan to talk on topics ranging from maintaining different kinds of compatibility, to subtleties of using interfaces versus abstract classes, to an analogy between the proper use of generics and the Mandelbrot set.

(2008-02-18 09:00:00.0) Permalink

20080214 Thursday February 14, 2008

OpenJDK 6: The End of the Beginning

The initial code drop for OpenJDK 6 is now available. More to follow.

(2008-02-14 12:34:11.0) Permalink

Calendar

« February 2008 »
SunMonTueWedThuFriSat
     
1
2
3
4
5
6
7
8
9
10
11
12
13
15
16
17
19
20
21
22
23
24
26
27
28
 
       
Today

RSS Feeds

XML
All
/Annotation Processing
/General
/Java
/JavaOne
/Numerics
/OpenJDK

Search

Links

    Blogroll
  • Download the JRE

    News

Navigation



Referers

Today's Page Hits: 738