короткая версия: Я пытаюсь вызвать jpackage из задачи Gradle, но ToolProvider возвращает значение NULL (или, лучше, неудачный Optional). Это относится к AdoptOpenJDK 14.0.0 (идентификатор sdkman 14.0.0.hs-adpt), а также к Java. net (я думаю, что это Oracle OpenJDK !?) 14.0.1 (идентификатор sdkman 14.0. 1-открыт). Я использую Gradle 6.3 (но это не похоже на проблему gradle).
длинная версия: Я слежу за этим докладом по jpackage , где в 12:12 отображается код для вызова jpackage из инструмента сборки. ( официальная страница jpackage также упоминает: В дополнение к интерфейсу командной строки, jpackage доступен через API ToolProvider (java .util.spi.ToolProvider) под именем "jpackage" . )
И все же мой (Kotlin) код (лежащий в buildSrc / src / main / kotlin)
object JPackage {
fun buildInstaller(
...
): Int {
val jpackageTool: ToolProvider = ToolProvider.findFirst("jpackage").orElseThrow {
val javaVersion: String = System.getProperty("java.version")
IllegalStateException(
"jpackage not found (expected JDK version: 14 or above, detected: $javaVersion)"
)
}
val arguments: Array<String> = ...
return jpackageTool.run(System.out, System.err, *arguments)
}
}
, вызванный новой задачей Gradle
tasks {
register("buildInstaller") {
JPackage.buildInstaller(
...
)
dependsOn("build")
}
}
не удается с указанием
> Could not create task ':buildInstaller'.
> jpackage not found (expected JDK version: 14 or above, detected: 14.0.1)
Я должен добавить, что у меня нет проблем с вызовом jpackage из командной строки.
ОБНОВЛЕНИЕ: Я подтвердил что это не имеет ничего общего ни с Kotlin, ни с Gradle. Эта базовая c Java -14 программа выдает то же исключение:
public class Main {
public static void main(String[] args) {
java.util.spi.ToolProvider.findFirst("jpackage").orElseThrow(() -> {
String javaVersion = System.getProperty("java.version");
return new IllegalStateException("jpackage not found (expected JDK version: 14 or above, detected: " + javaVersion + ")");
});
System.out.println("success");
}
}
Решение: (включая ответ Slaw), поскольку jpackage находится в режиме "инкубации" и поэтому недоступен для моего немодульного приложения я решил вызвать его, создав новый процесс:
object JPackage {
fun buildInstaller(
...
): Int {
val arguments: Array<String> = ...
return execJpackageViaRuntime(arguments)
}
private fun execJpackageViaRuntime(arguments: Array<String>): Int {
val cmdAndArgs = ArrayList<String>(arguments.size+1).let {
it.add("jpackage")
it.addAll(arguments)
it.toTypedArray()
}
return try {
val process: Process = Runtime.getRuntime().exec(cmdAndArgs)
process.waitFor(3L, TimeUnit.MINUTES)
return process.exitValue()
} catch (e: Exception) {
1
}
}
}
, и мое определение задачи выглядит следующим образом:
tasks {
register("buildInstaller") {
dependsOn("build")
doLast {
if (JavaVersion.current() < JavaVersion.VERSION_14) {
throw GradleException("Require Java 14+ to run 'jpackage' (currently ${JavaVersion.current()})")
}
JPackage.buildInstaller(
...
)
}
}
}
Я не могу выполнить задачу из IntelliJ, поскольку кажется, что он вызывает Gradle с JDK11, он сам поставляется в комплекте, но по крайней мере IntelliJ может скомпилировать сам скрипт сборки (поскольку проверка версии находится в блоке doLast, а не непосредственно в блоке регистра). В качестве альтернативы вы можете изменить JDK, который IntelliJ использует для вызова Gradle, прокрутите вниз до комментария Slaw под его ответом, чтобы увидеть, как.
Кстати: я уверен, что Gradle версии 6.3 сложно это необходимо для работы, поскольку это первая версия Gradle, совместимая с Java 14.