Java 9 & Clojure Research Notes

Table of Contents

This provides additional information to go along with my Java 9 talk from Clojure/West 2017. A recording of the talk is available, as are the slides.

General resources

Multi-release JARs

AOT compilation

The following is based on instructions from http://openjdk.java.net/jeps/295 (using Java 9-ea+160).

To compile the java.base module:

jaotc -J-XX:+UseCompressedOops -J-XX:+UseG1GC -J-Xmx4g --compile-for-tiered --info \
  --compile-commands java.base-list.txt --output libjava.base.so --module java.base

Where java.base-list.txt contains:

# jaotc: java.lang.StackOverflowError
exclude sun.util.resources.LocaleNames.getContents()[[Ljava/lang/Object;
exclude sun.util.resources.TimeZoneNames.getContents()[[Ljava/lang/Object;
exclude sun.util.resources.cldr.LocaleNames.getContents()[[Ljava/lang/Object;
exclude sun.util.resources..*.LocaleNames_.*.getContents\(\)\[\[Ljava/lang/Object;
exclude sun.util.resources..*.LocaleNames_.*_.*.getContents\(\)\[\[Ljava/lang/Object;
exclude sun.util.resources..*.TimeZoneNames_.*.getContents\(\)\[\[Ljava/lang/Object;
exclude sun.util.resources..*.TimeZoneNames_.*_.*.getContents\(\)\[\[Ljava/lang/Object;
# java.lang.Error: Trampoline must not be defined by the bootstrap classloader
exclude sun.reflect.misc.Trampoline.<clinit>()V
exclude sun.reflect.misc.Trampoline.invoke(Ljava/lang/reflect/Method;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
# JVM asserts
exclude com.sun.crypto.provider.AESWrapCipher.engineUnwrap([BLjava/lang/String;I)Ljava/security/Key;
exclude sun.security.ssl.*
exclude sun.net.RegisteredDomain.<clinit>()V

Compiling a simple Clojure uberjar (you may need all dependencies on the classpath, not just Clojure):

jaotc -J-XX:+UseCompressedOops -J-XX:+UseG1GC -J-Xmx4g -J-cp -J/path/to/clojure-1.8.0.jar \
  --compile-for-tiered --info --output libtest-app.so --jar path/to/uberjar.jar --ignore-errors

For "fun", I worked on AOT'ing the lein uberjar. That required:

  • AOT compiling the lein uberjar:
jaotc -J-XX:+UseCompressedOops -J-XX:+UseParallelGC -J-Xmx4g -J-cp \
  -J/home/tcrawley/.m2/repository/junit/junit/4.12/junit-4.12.jar:/home/tcrawley/.m2/repository/org/osgi/org.osgi.core/4.3.1/org.osgi.core-4.3.1.jar:/home/tcrawley/.m2/repository/org/osgi/org.osgi.compendium/4.2.0/org.osgi.compendium-4.2.0.jar:/home/tcrawley/jars/plexus-cli-1.6.jar:/home/tcrawley/jars/archetype-common-3.0.0.jar:/home/tcrawley/jars/javax.servlet-api-3.1.0.jar:/home/tcrawley/.m2/repository/org/clojure/clojure/1.8.0/clojure-1.8.0.jar \
  --compile-for-tiered --info --output ~/.lein/liblein.so  \ 
  --jar ~/.lein/self-installs/leiningen-2.7.1-standalone.jar --ignore-errors
  • Editing the lein script to comment out bootclasspath usage (since that doesn't work under Java 9):
# BOOTCLASSPATH="-Xbootclasspath/a:$LEIN_JAR"
  • Copying libjava.base.so to ~/.lein
  • Setting the proper JVM args:
export LEIN_JVM_OPTS="-XX:+TieredCompilation -XX:TieredStopAtLevel=1 -XX:+UseParallelGC -XX:AOTLibrary=~/.lein/libjava.base.so:~/.lein/liblein.so"
  • And, finally, running lein:
lein version

However, this resulted decreased startup performance:

  • lein + Java 8 w/bootclasspath hack: 1.495s
  • lein + Java 9 no bootclasspath hack: 2.334s
  • lein + Java 9 + AOT: 3.051s

G1 garbage collector

Modules

Author: Toby Crawley

Created: 2017-03-31 Fri 15:49

Emacs 24.5.1 (Org mode 8.2.10)

Validate