Как установить Gradle `options.bootClasspath` независимым образом?

Поскольку мои источники и цели Java должны быть совместимы с JRE 1.6, мне нужно установить options.bootClasspath в путь, содержащий версии 1.6 rt.jar и jce.jar. Он должен основываться как на Windows, так и на Unix (Linux/Solaris). Каков правильный способ сделать это? Теперь я использую следующий подход на верхнем уровне build.gradle, он работает, но он кажется далеким от элегантного, особенно os-зависимый разделитель : или ;:

import org.apache.tools.ant.taskdefs.condition.Os

subprojects {
  apply plugin: 'java'

  compileJava {
    sourceCompatibility = 1.6
    targetCompatibility = 1.6
    def java6_home = System.getenv("JAVA_HOME_6")
    def java6_lib = "C:/localdata/Program Files (x86)/Java/jdk1.6.0_45/jre/lib/"

    if (java6_home != null) {
      java6_lib = java6_home + "/jre/lib/"
    }

    def sep = ':'
    if (Os.isFamily(Os.FAMILY_WINDOWS)) {
      sep = ';'
    }
    options.bootClasspath = java6_lib + "rt.jar" + sep + java6_lib + "jce.jar"
  }
}

Ответ 1

Я использую следующий код (предполагая, что JDK6_HOME указывает на корень установки JDK 1.6):

tasks.withType(JavaCompile) {
    doFirst {
        if (sourceCompatibility == '1.6' && System.env.JDK6_HOME != null) {
            options.fork = true
            options.bootClasspath = "$System.env.JDK6_HOME/jre/lib/rt.jar"
            options.bootClasspath += "$File.pathSeparator$System.env.JDK6_HOME/jre/lib/jsse.jar"
            // use the line above as an example to add jce.jar 
            // and other specific JDK jars
        }
    }
}

Этот подход автоматически определяет присутствие переменной окружения и автоматически устанавливает bootClasspath для всех модулей, объявляющих sourceCompatibility как 1.6.

options.fork = true требуется options.fork = true.

Ответ 2

Принятый ответ может работать, но если вы используете некоторые классы вне java.lang(например, javax.crypto.*), вы можете обнаружить, что вы получите различные исключения ClassNotFoundException, поскольку больше файлов JAR необходимо добавить в bootClasspath.

Чтобы этого избежать, я использую следующее, которое имеет следующие преимущества:

.

tasks.withType(JavaCompile) {
    doFirst {
        if (JavaVersion.toVersion(sourceCompatibility) == JavaVersion.VERSION_1_6
            && JavaVersion.current() != JavaVersion.VERSION_1_6
            && System.env.JDK6_HOME != null) {
            options.fork = true
            options.bootClasspath = fileTree(include: ['*.jar'], dir: "$System.env.JDK6_HOME/jre/lib/").join(File.pathSeparator)
            options.extensionDirs = "$System.env.JDK6_HOME/jre/lib/ext/"
        }
    }
}

Ответ 3

Небольшая модификация прохладного решения Олега Эстехина выше, но не требует установки JDKX_HOME (вычисляет его на лету.) Также, измененный для выполнения Java 1.7 builds:

tasks.withType(JavaCompile) {
    doFirst {
        if (sourceCompatibility == '1.7') {
            def JDK7_HOME = "/usr/libexec/java_home -v 1.7".execute().text.trim()
            options.bootClasspath = "$JDK7_HOME/jre/lib/rt.jar"
            options.bootClasspath += "$File.pathSeparator$JDK7_HOME/jre/lib/jsse.jar"
            // use the line above as an example to add jce.jar 
            // and other specific JDK jars
        }
    }
}

Ответ 4

Я попытался добавить много банок в мой bootClassPath, используя приведенные выше инструкции, но никогда не разрешил проблему с моей сборкой. Я, наконец, решил построить, установив мой JAVA_HOME, чтобы указать на IBM JDK 1.7, требуемый сервером WebSphere, и добавить его на мой путь. Мои другие проекты требуют Oracle JDK 1.8, поэтому я не хотел, чтобы это изменение было постоянным.

set JAVA_HOME="C:\Program Files (x86)\IBM\WebSphere\AppServer\java_1.7.1_64\"
set PATH=%JAVA_HOME%\bin;%PATH%
gradle clean war
gradle clean ear deployLocal

Ответ 5

Поскольку Gradle 4.3 вы можете использовать CompileOptions.bootstrapClasspath вместо этого, чтобы удалить необходимость в зависимом от ОС разделителе.