[SOLVED] Windows, Cygwin and Gradle: How to portably set up options.bootClasspath? Error: Fatal Error: Unable to find package java.lang in classpath or bootclasspath

Hi All

I have a multi-module project with a Java compilation that requires the following:

gradle.projectsEvaluated {
    tasks.withType(JavaCompile) {
        // In order to configure the bootstrap classpath to be used for the compiler process, we have to fork the compilation :(
        // SEE ALSO: http://gradle.org/docs/current/dsl/org.gradle.api.tasks.compile.CompileOptions.html#org.gradle.api.tasks.compile.CompileOptions:bootClasspath
        options.fork = true
        options.compilerArgs << "-XDignore.symbol.file"
//        options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
        println("detected JAVA_HOME=$System.env.JAVA_HOME")
        println("setting options.bootClasspath = $System.env.JAVA_HOME/jre/lib/rt.jar")
        options.bootClasspath = "$System.env.JAVA_HOME/jre/lib/rt.jar"
    }
}

On Windows command line, the above gradle compileJava work flawlessly.

Inside Cygwin, unfortunately the command fails.

All input files are considered out-of-date for incremental task ':shared:emso-core:compileJava'.
Starting process 'Gradle Compiler Daemon 1'. Working directory: C:\Users\ppilgrim_wpk\Documents\IdeaProjects\repo-new\Rotary Command: C:\Program Files\Java\jdk1.8.0_45\bin\java.exe -Dfile.encoding=windows-1252 -Duser.country=GB -Duser.language=en -Duser.variant -cp C:\opt\gradle-2.2.1\lib\gradle-base-services-2.2.1.jar;C:\opt\gradle-2.2.1\lib\gradle-core-2.2.1.jar;C:\opt\gradle-2.2.1\lib\gradle-cli-2.2.1.jar;C:\opt\gradle-2.2.1\lib\gradle-native-2.2.1.jar;C:\opt\gradle-2.2.1\lib\gradle-messaging-2.2.1.jar;C:\opt\gradle-2.2.1\lib\slf4j-api-1.7.7.jar;C:\opt\gradle-2.2.1\lib\logback-classic-1.0.13.jar;C:\opt\gradle-2.2.1\lib\logback-core-1.0.13.jar;C:\opt\gradle-2.2.1\lib\jul-to-slf4j-1.7.7.jar;C:\opt\gradle-2.2.1\lib\guava-jdk5-17.0.jar org.gradle.process.internal.launcher.GradleWorkerMain 'Gradle Compiler Daemon 1'
Successfully started process 'Gradle Compiler Daemon 1'
Started Gradle compiler daemon (0.485 secs) with fork options DaemonForkOptions{minHeapSize=null, maxHeapSize=null, jvmArgs=[], classpath=[]}.
Executing org.gradle.api.internal.tasks.compile.JdkJavaCompiler@7d78be33 in compiler daemon.
Compiling with JDK Java compiler API.
Fatal Error: Unable to find package java.lang in classpath or bootclasspath
Exception executing org.gradle.api.internal.tasks.compile.JdkJavaCompiler@7d78be33 in compiler daemon: org.gradle.api.internal.tasks.compile.CompilationFailedException: Compilation failed; see the compiler error output for details..
:shared:emso-core:compileJava FAILED
:shared:emso-core:compileJava (Thread[main,5,main]) completed. Took 3.368 secs.

FAILURE: Build failed with an exception.

I suspect that the forked javac' has the wrong JAVA_HOME settings. That is/cydrive/c/Program Files/Java/jdk1.8.0_45, which pointed to Cygwin munged path, but this may not be correct for a Windows Java process under Cywin. A normal windows DOS process would have the JAVA_HOME asC:\Program Files\Java\jdk1.8.0_45`. So what type of process is Gradle forking? Is it a CygWin process or is it DOS shell process?

Have anyone correctly grokked the correct magic incantation for portably configuring the options.bootClasspath under both Cygwin terminal and normal Window DOS command line?

When you’re in the shell that you run Gradle in, what is JAVA_HOME set to?

Hi David

Thanks for getting back, hope you had a good weekend.

I wanted to double check on the actually workstation before I responded, so here is the information.

$ gradle --version

------------------------------------------------------------
Gradle 2.4
------------------------------------------------------------

Build time:   2015-05-05 08:09:24 UTC
Build number: none
Revision:     5c9c3bc20ca1c281ac7972643f1e2d190f2c943c

Groovy:       2.3.10
Ant:          Apache Ant(TM) version 1.9.4 compiled on April 29 2014
JVM:          1.8.0_45 (Oracle Corporation 25.45-b02)
OS:           Windows 7 6.1 amd64


peter@X32 ~/Documents/IdeaProjects/repo-new/Rotary/shared/x-core
$ echo $JAVA_HOME
C:\Program Files\Java\jdk1.8.0_45

peter@X32 ~/Documents/IdeaProjects/repo-new/Rotary/shared/x-core
$

Ok, I see from the `gradle’ launch script that the JAVA_HOME is being correctly reset inside the Cygwin environment.

Line 45

# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi

So really forking the JVM to compile should reuse this setting or it perhaps the child process in then resetting the JAVA_HOME. Under a Cygwin environment, how does Gradle fork the JVM process?

[SOLVED]

Ok I figured it out. I hardCoded the option.bootClasspath.

gradle.projectsEvaluated {
    tasks.withType(JavaCompile) {
        // In order to configure the bootstrap classpath to be used for the compiler process, we have to fork the compilation :(
        // SEE ALSO: http://gradle.org/docs/current/dsl/org.gradle.api.tasks.compile.CompileOptions.html#org.gradle.api.tasks.compile.CompileOptions:bootClasspath

        options.fork = true
        options.compilerArgs << "-XDignore.symbol.file"

        def rtLocationDir = "C:\\Program Files\\Java\\jdk1.8.0_45\\jre\\lib\\rt.jar"
        // FIXME: 1) Write Operating System and environment detection code here. 
        // 2) Remove the `/C/cygdrive' from JAVA_HOME explicitly.
//        options.bootClasspath = "$System.env.JAVA_HOME/jre/lib/rt.jar"
        options.bootClasspath = rtLocationDir
    }
}

I ran gradle compileJava > gradle.log and analysed the log file and checked for setting of the bootClasspath argument. Hard setting the path explicitly got me past the Fatal Error: Unable to find package java.lang in classpath or bootclasspath and now I just see normal compilation deprecation warnings.

I just have to write the logic to test the operating system and portable file path handling.

Ta!