简体   繁体   English

如何使用 Gradle 设置 JPMS 模块的 ModuleMainClass 属性?

[英]How can I set the ModuleMainClass attribute of a JPMS module using Gradle?

I'm using Gradle (6.0.1) with the moduleplugin to build an application out of JPMS modules using JDK 13.我使用摇篮(6.0.1)与moduleplugin来构建的应用JPMS模块使用JDK 13。

However, even with the application plugin applied & its mainClassName set it does not set the ModuleMainClass attribute in module-info.class , so when I jlink it up into a standalone JVM and run java -m mymodule I get this message:但是,即使applicationapplication插件并设置了它的mainClassName它也不会在module-info.class设置ModuleMainClass属性,所以当我将它连接到独立的 JVM 并运行java -m mymodule我收到以下消息:

module mymodule does not have a ModuleMainClass attribute, use -m <module>/<main-class>

Digging under the hood it looks like the moduleplugin doesn't change the jar task at all, and the out of the box gradle jar task does not actually use the JDK's jar command , it just zips everything up itself.在引擎盖下挖掘它看起来像 moduleplugin 根本不改变 jar 任务,开箱即用的 gradle jar 任务实际上并不使用JDK 的jar命令,它只是将所有内容压缩起来。

As far as I can tell the only way to set the ModuleMainClass attribute in module-info.class is to use the JDK's jar command as so: jar --main-class=CLASSNAME -C <classes dir> .据我所知,在module-info.class设置ModuleMainClass属性的唯一方法是使用 JDK 的 jar 命令: jar --main-class=CLASSNAME -C <classes dir>

Is there a way to do this, short of writing my own gradle task?除了编写自己的 gradle 任务之外,有没有办法做到这一点? And if not, has anyone got an example of replacing the gradle jar task with one that calls the JDK command?如果没有,有没有人有一个例子,用一个调用 JDK 命令的任务替换 gradle jar 任务?

(Please note this question is not about setting the Main-Class in the jar's MANIFEST.MF - that's easy, but isn't respected when calling java -m <modulename> .) (请注意,这个问题与在 jar 的 MANIFEST.MF 中设置Main-Class无关- 这很容易,但在调用java -m <modulename>时不受尊重。)

It looks like the jar task in gradle does not do a proper job of building the jar to also include the module-main-class in the module-info.class .看起来 gradle 中的jar任务没有正确地构建 jar 以在module-info.class包含module-main-class In fact it doesn't look like it calls the jar command at all which is a bit misleading.事实上,它看起来根本没有调用jar命令,这有点误导。 So here is an updated version that does this:所以这是一个更新版本,它可以做到这一点:

jar {
    doLast {
        project.exec {
            workingDir destinationDirectory.get()
            executable 'jar'
            args '--update'
            args '--file', archiveFileName.get()
            args '--main-class', mainClassName
            args '.'
        }
    }
}

Jar command syntax taken in part from this tutorial . Jar 命令语法部分取自本教程

This looks janky, but it works and hopefully some day the Jar task will include that last part.这看起来很笨拙,但它有效,希望有一天Jar任务将包含最后一部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM