Anatomy of the JDK Build

The recent "javac -target 7" changes to the jdk7 repositories has prompted me to post this blog about OpenJDK builds. To those unfamiliar with Java classfile versions, each JDK release typically has upgraded the version of the classfiles created by the javac compiler, newer JDKs understand it's own classfile version, plus all the older versions. But older JDKs can NOT understand the newer classfile versions, and their javac instances will not understand how to create newer versions, which of course, makes perfect sense, not sure why I had to say that... oh well... The JDK itself usually contains the newest classfile version, however JDK6 delivered JDK5 classfiles. With JDK7 we want to deliver the latest classfile version in the JDK itself, so the way the JDK is built becomes more interesting to know.

See Alex's version blog, Joe's version blog, and Joe's build advice blog for more information.

When building the OpenJDK from scratch, there are 7 repositories involved, many different system components used in the build process, and an ordering or dependency chain.

For now I'll ignore the build variations or flavors of builds, such as product (optimized), fastdebug, and debug, which generally just repeat the same steps but with slight variations on how the bits are built. What I wanted to do here was describe the dependencies between the repositories and the bootstrap jdk used in the build.

Granted this could change, but currently building OpenJDK JDK7 sources from scratch happens in this order:

  1. The langtools repository (repository that holds javac, javah, etc.) is built first using the bootstrap jdk6 javac. This creates a bootstrap javac.jar compiler that can be run with the bootstrap jdk. This bootstrap javac.jar is capable of compiling and creating the newer jdk7 source and classfiles, e.g. it understand -target 7 and -source 7.

    Note that the langtools sources need to be jdk6 compiled sources, and when this repository is built, it also uses the bootstrap javac.jar to compile itself into -target 7 classfiles to be put into the final jdk7 image. Keep in mind that we cannot run jdk7 classfiles yet, we can create them using the bootstrap jdk and the bootstrap javac.jar, but we have no jdk7 image to run yet.

  2. The corba repository is built using the bootstrap jdk and the bootstrap javac.jar from the langtools build.
  3. The jaxp repository is built using the bootstrap jdk and the bootstrap javac.jar from the langtools build.
  4. The jaxws repository is built using the bootstrap jdk and the bootstrap javac.jar from the langtools build.

    Note that up to this point, these are jdk7 classes, but built with a jdk6 runtime (the jdk6 rt.jar classes). The jdk7 rt.jar has not been built yet. This has not been an issue in that the sources in corba, jaxp, and jaxws are restricted to jdk6 interfaces and have no need for jdk7 specific interfaces. This is also why a jdk5 cannot be used as the bootstrap jdk, jdk5 does not have all the interfaces needed by the above repositories.

  5. The hotspot repository is built using the native C++ compiler.

    Note that hotspot includes java source, however that source is currently compiled with the bootstrap jdk javac, not the langtools bootstrap javac.jar. This may need to change in the future, but there may be some requirements for using -target 6 or even -target 5 with whatever javac is used here.

  6. Lastly the jdk repository is built. This repository pulls all the above builds together, and also builds the rest of the jdk using the bootstrap jdk and the langtools bootstrap javac.jar. The actual javac included in the jdk7 image will have been the -target 7 built classes. Eventually it will have created enough of a jdk7 image that it could be run on it's own, at that point the demos are built and the image is finalized.

    Note that when building these jdk sources, they are built in a particular order defined by the Makefiles, and against themselves, so that in a sense, these classes are compiled against what will become the jdk7 runtime.

A really good test at this point is to use this newly built jdk7 as the bootstrap jdk, and build a second jdk7. It should work. The top level Makefile has an option to do this make SKIP_BOOT_CYCLE=false.

You can build each repository separately and most developers do, but now that we have this -target 7 requirement, you may need to specify the bootstrap jdk as jdk7, include the langtools repository as part of your build, or set ALT_LANGTOOLS_DIST to point to the langtools/dist directory (a built langtools repository).

Hope this helps to explain things a little. Please post any questions you have, I'll try and answer all I can. And hopefully Jonathan will keep me honest here. :\^)



Post a Comment:
Comments are closed for this entry.

Various blogs on JDK development procedures, including building, build infrastructure, testing, and source maintenance.


« July 2016