问题
I'm using Gradle (6.0.1) with the moduleplugin to build an application out of JPMS modules using 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:
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.
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>
.
Is there a way to do this, short of writing my own gradle task? And if not, has anyone got an example of replacing the gradle jar task with one that calls the JDK command?
(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>
.)
回答1:
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
. In fact it doesn't look like it calls the jar
command at all which is a bit misleading. 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.
This looks janky, but it works and hopefully some day the Jar
task will include that last part.
来源:https://stackoverflow.com/questions/59117333/how-can-i-set-the-modulemainclass-attribute-of-a-jpms-module-using-gradle