RC3 ships the junit-platform-console-standalone-1.0.0-RC3.jar with the following META-INF/MANIFEST.MF file:
Manifest-Version: 1.0
Implementation-Title: junit-platform-console-standalone
Build-Date: 2017-08-23
Implementation-Version: 1.0.0-RC3
Built-By: JUnit Team
Specification-Vendor: junit.org
Specification-Title: junit-platform-console-standalone
Class-Path: junit-platform-console-1.0.0-RC3.jar junit-jupiter-engine-
5.0.0-RC3.jar junit-jupiter-params-5.0.0-RC3.jar junit-vintage-engine
-4.12.0-RC3.jar junit-platform-launcher-1.0.0-RC3.jar junit-platform-
engine-1.0.0-RC3.jar junit-jupiter-api-5.0.0-RC3.jar junit-4.12.jar j
unit-platform-commons-1.0.0-RC3.jar opentest4j-1.0.0-RC1.jar hamcrest
-core-1.3.jar
Implementation-Vendor: junit.org
Main-Class: org.junit.platform.console.ConsoleLauncher
Build-Revision: e0af182b1440da44af16a7181cd3b03d1a3fe82d
Build-Time: 20:40:28.393+0200
Engine-Version-junit-vintage: 4.12.0-RC3
Created-By: 1.8.0_131 (Oracle Corporation 25.131-b11)
Specification-Version: 1.0.0
Engine-Version-junit-jupiter: 5.0.0-RC3
The Class-Path attribute refers to all jars that are shadowed into this standalone artifact. Therefore the Class-Path attribute should be removed from the manifest file.
Does anybody know how to prevent or erase the Class-Path attribute? @johnrengelman ?
def libs = [project.tasks.jar.manifest.attributes.get('Class-Path')]
libs.addAll files.collect { "${it.name}" }
manifest.attributes 'Class-Path': libs.findAll { it }.join(' ')
junit-jupiter-params and junit-platform-console are affected too.
Good catch!
The simplest way would be to create your own ShadowJar task instead of using the autoconfigured one.
Alternatively, you _might_ be able to do:
shadowJar {
manifest {
attributes ["Class-Path": ""]
}
}
@johnrengelman, why are the shadowed JARs added to the manifest class-path to begin with?
When would that ever make sense?
In other words, isn't this rather a _bug_ in the Shadow plug-in?
If you think it's an issue, raise it in the repo and we can have the discussion there.
When would that ever make sense?
To answer my own question...
The shadowed JARs shouldn't even be present. That's the whole point of shadowing them: so that they are _not_ present. 馃槈
Looks like we posted comments at the same time.
If you think it's an issue, raise it in the repo and we can have the discussion there.
Alrighty! 馃憤
I'm creating the issue for Shadow now.
FYI: the following _does not_ work.
shadowJar {
// ...
manifest {
attributes 'Class-Path': ''
}
}
The following doesn't work either.
manifest.getAttributes().remove('Class-Path')
@aalmiray, do you have any ideas for how we can _remove_ the Class-Path manifest header before the JAR is actually generated?
It appears that the default shadowJar creates an entry for Class-Path regardless of any configuration and /or external changes you make to the JAR's attributes. See https://github.com/johnrengelman/shadow/blob/a5fde6e57f6a05df338ec6230674e72a6c794f0e/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowJavaPlugin.groovy#L48-L56
That block of code shows the automatic calculation for Class-Path; there's nothing you can do from an external POV to change this default behavior as there's no chance to tweak the updated manifest.
This means @johnrengelman's suggestion does not work as confirmed by @sbrannen.
Workaround: create a custom plugin that overrides the default shadowJar task, avoiding the calculation of Class-Path.
To be discussed with @johnrengelman: allow the calculation of Class-path to be optional via a configuration flag.
@aalmiray Thanks for the feedback and insight!
there's nothing you can do from an external POV to change this default behavior as there's no chance to tweak the updated manifest.
Mmmmmm... that's a real shame! I _assumed_ it would be possible with some Gradle voodoo, but oh well. 馃槥
Having said that, it should still be possible (even if totally ugly) with Gradle/Groovy to unpack the JAR, rewrite the manifest, and repack the JAR after the shadowJar and jar tasks have completed -- right?
I suppose you can do that too, yes that will work :wink:
I suppose you can do that too, yes that will work 馃槈
OK.... then I'll leave the _fun_ to @sormuras, since he assigned the issue to himself. 馃槤
...as this Class-Path issue is almost a non-issue (who would ever place a JAR named exactly like an entry of the Class-Path attribute next to the "standalone.jar" anyway?!) I tend to defer the _fun_ to our backlog. Maybe there will be an option to turn off the generation in a future Shadow release.
Oh, c'mon now, Christian... don't be such a party pooper! Don't ya wanna have a little _fun_? 馃槇
Or are you suggesting that defun be limited solely to Lisp developers? 馃ぃ
All kidding aside, I actually agree with you: let's defer this issue to a later date (with the hope that the Shadow plugin eventually makes it a moot point anyway).
Moved to _General Backlog_ for the time being.
This bug in the shadowJar task (probably introduced while fixing https://github.com/johnrengelman/shadow/issues/65) was blocking me. Here is a workaround that others may find useful.
// Work around https://github.com/johnrengelman/shadow/issues/324
shadowJar.doLast {
exec {
workingDir 'build/libs'
commandLine 'jar', 'xf', shadowJar.archiveName, 'META-INF/MANIFEST.MF'
}
exec {
workingDir 'build/libs'
commandLine 'sed', '-i', '/^Class-Path:.*/d', 'META-INF/MANIFEST.MF'
}
exec {
workingDir 'build/libs'
commandLine 'zip', '-q', '-u', shadowJar.archiveName, 'META-INF/MANIFEST.MF'
ignoreExitValue true // Exit value 12 means "nothing to do"
}
delete {
delete 'build/libs/META-INF'
}
}
I'm looking at the shadow code and the only time the classpath attribute gets generated is if you specify dependencies in configurations.shadow. This configuration is reserved for compile time dependencies that you do not want merged into the final jar.
So if jars that are being merged are also ending up in the the manifest classpath, then my guess is you are configuring something incorrectly in the build.
After discussion elsewhere, we concluded this is a bona fide limitation of the shadowJar task and its documentation, so a workaround is necessary. @johnrengelman provided a simpler workaround than above (thanks!), and hopefully will improve shadowJar to not require a workaround.
_in progress_