GradleUp / shadow

Gradle plugin to create fat/uber JARs, apply file transforms, and relocate packages for applications and libraries. Gradle version of Maven's Shade plugin.
https://www.gradleup.com/shadow/
Apache License 2.0
3.76k stars 395 forks source link

Main class name of manifest is incorrect when using Application plugin with JPMS #483

Open mpe85 opened 5 years ago

mpe85 commented 5 years ago

ShadowJar produces a Jar with an incorrect Main-Class entry in the manifest file. This happens when you apply the Application plugin and you have a java 9 module.

Shadow Version

5.0.0

Gradle Version

5.3.1

Expected Behavior

I applied the application plugin in a project that uses the java 9 module system. Therefore the main class name must be specified including the module name, otherwise the application plugin prints a warning (e.g. when I try to run the 'run' task):

application {
  mainClassName = "$moduleName/x.y.Z"
}

I would expect ShadowJar to put the main class name without the module name into the manifest: Main-Class: x.y.Z

Actual Behavior

ShadowJar puts the main class attribute including the module name into the manifest: Main-Class: a.b.c/x.y.Z

When trying to execute the fat jar using java -jar xxx.jar it fails with an error because it does not find the class inside the package a.b.c.x.y (which of course does not exist)

It's not possible to override the manifest entry manually using manifest.attributes["Main-Class"] = x.y.Z No matter what I specify here, ShadowJar always uses application.mainClassName

Gradle Build Script(s)

See above

Content of Shadow JAR (jar tf <jar file> - post link to GIST if too long)

chrismaster commented 5 years ago

Any news on this one?

It seems the application (or here jlink) plugin overrides the MainClassName attribute from the jar plugin.

I think a.b.c.x.y is only a terminal problem. In the manifest of the jar should be a.b.c/x.y.Z

Try java -cp shadowJar.jar x.y.Z

How to set the MainClassName from shadow plugin?

So from the docs jar { manifest { attributes 'Main-Class': 'my.main.ClassName'
} } wont work

mpe85 commented 5 years ago

@johnrengelman Could you please provide any information about this?

johnrengelman commented 5 years ago

When using JPMS, there must be a different task generating the Manifest file (other than the normal Jar task). ShadowJar by default, inherits it’s config from Jar, so you’ll need to change that. https://imperceptiblethoughts.com/shadow/configuration/#configuring-the-jar-manifest