Scala, bootclasspath and JAVA_HOME

I have a Gradle project (using Gradle 2.6) which compiles Java and Scala classes. I need the project to use JDK8 but compile classes with the JDK7 classes. For that, I’m using the following code to reconfigure the Java and Scala compile tasks.

allprojects {
// Retrieve the JDK 7 home directory from the relevant environment variable
def javaHome = System.env['JAVA_7_HOME']

if (javaHome) {
    // The directory containing the JDK jars
    def libDir = new File(javaHome, 'jre/lib')

    if (libDir.exists()) {
        // Create a file set with the jars we're interested in
        def jarFiles = fileTree(dir: libDir, includes: [ 'rt.jar' ])

        afterEvaluate { proj ->
            // Reconfigure all the Java and Scala compile tasks to set the bootclasspath
            proj.tasks.withType(JavaCompile).each { compileTask ->
                // Finally set the boot classpath from the above file set
                compileTask.options.bootClasspath = jarFiles.asPath

                println "[${name}] Task '${compileTask.name}' reconfigured to set the boot classpath to '${jarFiles.asPath}'"
            }
            proj.tasks.withType(ScalaCompile).each { compileTask ->
                compileTask.options.bootClasspath = jarFiles.asPath
                compileTask.scalaCompileOptions.additionalParameters = ['-bootclasspath', "${jarFiles.asPath}".toString(), '-javaextdirs', "${jarFiles.asPath}".toString()]

                println "[${name}] Task '${compileTask.name}' reconfigured to set the boot classpath to '${jarFiles.asPath}'"
            }
        }
    }
}

}

This works however I noticed at build time (when compiling the Scala classes), Gradle doesn’t take into account the bootclasspath I specified and use one generated instead.

This is the corresponding build log where the ‘-bootclasspath’ option is set twice: once with the path I specified and a second time with a path which seems generated from the JAVA_HOME environment variable (which points to /usr/java/jdk1.8.0_45).

build	02-Sep-2015 02:15:48	09:15:48.592 [QUIET] [system.out] 09:15:48.592 [DEBUG] [org.gradle.api.internal.tasks.scala.ZincScalaCompiler] Calling Scala compiler with arguments  (CompilerInterface):
build	02-Sep-2015 02:15:48	09:15:48.592 [QUIET] [system.out] 	-deprecation
build	02-Sep-2015 02:15:48	09:15:48.592 [QUIET] [system.out] 	-unchecked
build	02-Sep-2015 02:15:48	09:15:48.593 [QUIET] [system.out] 	-bootclasspath
build	02-Sep-2015 02:15:48	09:15:48.593 [QUIET] [system.out] 	/usr/local/jdk1.7.0_51/jre/lib/rt.jar
build	02-Sep-2015 02:15:48	09:15:48.593 [QUIET] [system.out] 	-javaextdirs
build	02-Sep-2015 02:15:48	09:15:48.593 [QUIET] [system.out] 	/usr/local/jdk1.7.0_51/jre/lib/rt.jar
build	02-Sep-2015 02:15:48	09:15:48.593 [QUIET] [system.out] 	-bootclasspath
build	02-Sep-2015 02:15:48	09:15:48.593 [QUIET] [system.out] 	/usr/java/jdk1.8.0_45/jre/lib/resources.jar:/usr/java/jdk1.8.0_45/jre/lib/rt.jar:/usr/java/jdk1.8.0_45/jre/lib/sunrsasign.jar:/usr/java/jdk1.8.0_45/jre/lib/jsse.jar:/usr/java/jdk1.8.0_45/jre/lib/jce.jar:/usr/java/jdk1.8.0_45/jre/lib/charsets.jar:/usr/java/jdk1.8.0_45/jre/lib/jfr.jar:/usr/java/jdk1.8.0_45/jre/classes:/home/wd-bamboo/.gradle/caches/modules-2/files-2.1/org.scala-lang/scala-library/2.10.4/9aae4cb1802537d604e03688cab744ff47b31a7d/scala-library-2.10.4.jar

In the end the Scala classes are compiled with the JDK8 classes but I need them to be compiled against JDK7.

How can I force the Scala compile tasks to use a bootclasspath set to JDK7 if my JAVA_HOME is pointing to JDK8 ? Is that possible ?

Do you really have to use JDK 7 ? Can’t you use your JDK8 with sourceCompatibility and targetCompatibility = 1.7 ?

Hello Francois,

Actually my build already sets the source and target compatibilities to 1.7. I forgot to mention that, sorry.

I need to compile against JDK 7 because there are some APIs which were broken between Java 7 and Java 8. The issue I stumbled upon is described here: https://gist.github.com/AlainODea/1375759b8720a3f9f094