DISTRIBUTION PACKAGING W/ SHADOW
About Me
- Chief Technologist - Object Partners
- http://www.objectpartners.com
- http://imperceptiblethoughts.com
- @johnrengelman
- johnrengelman
Presentation
What is Shadow?
Simple Answer
Fat (uber) JAR Creator
Detailed Answer
- Dependency exploded/combiner
- File filter/transformer
- Package relocator
Downloads
> 1,000,000 !!!
- 928K from bintray since 1st version published.
- No data from Gradle Plugin portal
Adding Shadow
$ gradle application:shadowJar && \
java -jar application/build/libs/application-shadow.jar
Client Version 1.0.0
Configuring the task
1 | Change the default of all |
Integration with Application
$ gradle runShadow
$ gradle distShadowTar
$ gradle distShadowZip
Filtering Files
Use the standard methods from Jar
task
$ gradle application-resolved-versions:jarContent
META-INF/
META-INF/MANIFEST.MF
shadow/
shadow/App.class
shadow/AdapterVersion.class
META-INF/services/
META-INF/services/shadow.client.Version
shadow/client/
shadow/client/Version.class
shadow/Version.class
Filtering Dependencies
Use the dependencies{}
block
$ gradle :application-filter-dependency:jarContent
META-INF/
META-INF/MANIFEST.MF
shadow/
shadow/AdapterVersion.class
adapter.properties
META-INF/services/
META-INF/services/shadow.client.Version
- Dependency Filters are explicit per dependency
- This means, you must exclude transitive deps explicitly
Shadow Configuration
project.configurations.shadow
holds runtime dependencies that are not merged
1 | This library will not be merged into the JAR |
1 | configurations.shadow is not added to the compile classpath by default |
$ gradle :application-shadow-conf:jarContent \
:application-shadow-conf:runShadow
META-INF/
META-INF/MANIFEST.MF
shadow/
shadow/App.class
shadow/AdapterVersion.class
adapter.properties
META-INF/services/
META-INF/services/shadow.client.Version
shadow/client/
shadow/client/Version.class
shadow/Version.class
Adapter: Client Version 2.0.0
Executing runtime code!
JAR Transformations
Service Descriptors
$ gradle application-transformer:showServices
1.0.0
1.0.0-additional
Other transforms
Package Relocation
Conflicting dependencies
$ gradle application-resolved-versions:runShadow
Adapter: Client Version 2.0.0
Client Version 2.0.0
Relocate
Update Dependency
$ gradle application-adapter-all:runShadow
Adapter: Client Version 2.0.0
Client Version 1.0.0
Publishing Shadow JARs
Simply apply Maven or Maven-Publish
(ivy-publishing untested)
With Maven-Publish Plugin
$ gradle :client-adapter-maven-publish:publishToMavenLocal
$ ls ~/.m2/repositories/shadow/client-adapter-maven-publish/1.0.0/
client-adapter-maven-publish-1.0.0-all.jar (1)
client-adapter-maven-publish-1.0.0.pom
1 | Notice the use of an artifact classifier |
Producing a Top Level Artifact w/ Shadow
With Maven-Publish Plugin
First, Configure ShadowJar
1 | Override the baseName to not step on JAR output |
2 | Remove the classifier as this will be a root artifact |
Then Configure Publishing
$ gradle :client-adapter-relocate:publishToMavenLocal
$ ls ~/.m2/repositories/shadow/client-adapter-relocate-all/1.0.0/
client-adapter-relocate-all-1.0.0.jar
client-adapter-relocate-all-1.0.0.pom
With Maven Plugin
Multi-Projects
Use the Map
notation for a project dependency
1 | Depend on the shadow configuration from the project |
$ gradle :multi-app:run
Adapter: Client Version 2.0.0
Client Version 1.0.0
User Guide
REMEMBER
$ gradle knows