简短版本:我正在尝试从gradle任务中调用jpackage,但ToolProvider返回null(或者最好是失败的Optional)。在AdoptOpenJDK 14.0.0(sdkman标识符14.0.0.hs-adpt)以及Java.net(我认为是Oracle OpenJDK !?)14.0.1(sdkman标识符14.0.1-open)中就是这种情况。我正在使用Gradle 6.3(但这并不像gradle的问题)。

较长版本:我遵循此talk on jpackage,其中在12:12处显示从构建工具调用jpackage的代码。 (official jpackage page还提到:除了命令行界面,还可以通过ToolProvider API(java.util.spi.ToolProvider)以名称“jpackage”访问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无关。这个基本的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内部执行任务,因为它似乎是 bundle 了JDK11来调用Gradle的,但是至少IntelliJ可以编译构建脚本本身(因为版本检查位于doLast块中,而不是直接在寄存器块)。或者,您可以更改IntelliJ用来调用Gradle的JDK,向下滚动到Slaw在他的回答下的注释以了解操作方法。

顺便说一句:我很确定 Gradle版本6.3 是实现此要求的硬性要求,因为它是第一个兼容Java 14的Gradle版本。

最佳答案

问题与JEP 11: Incubator Modules有关。 JEP声明:

在Java 14中,可能在以后的几个发行版中,jpackage工具包含在名为 jdk.incubator.jpackage 的模块中。从名称的前缀,我们可以看到该模块是一个孵化器模块。相同的JEP后来指出:

由于孵化器模块不参与服务绑定(bind),因此无法在运行时解析jdk.incubator.jpackage模块。不幸的是,这意味着无法通过ToolProvider找到该工具,除非您执行以下操作之一:

  • 使用--add-modules jdk.incubator.jpackage
  • 启动Java进程
  • 或将代码模块化,并在module-info文件中包含requires jdk.incubator.jpackage;指令。

  • 由于您尝试从Gradle任务中调用jpackage,因此我认为选项二是不可行的。但是,第一种选择似乎确实可行。执行Gradle时,您可以指定适当的org.gradle.jvmargs系统属性。例如:
    ./gradlew "-Dorg.gradle.jvmargs=--add-modules=jdk.incubator.jpackage" buildInstaller
    
    您不必每次都在命令行中键入它。 checkout this Gradle documentation,看看您还能在哪里定义该系统属性。虽然不确定,但也可以通过您的IDE进行某些操作。
    也就是说,也可以使用jpackage任务将Exec作为另一个进程来调用。例如:
    tasks {
        val build by existing
    
        register<Exec>("buildInstaller") {
            if (JavaVersion.current() < JavaVersion.VERSION_14) {
                throw GradleException("Require Java 14+ to run 'jpackage'")
            }
            dependsOn(build)
    
            executable = "jpackage"
            args(/* your args */)
        }
    }
    

    关于java - 通过ToolProvider无法找到jpackage,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/61307077/

    10-09 03:51