Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,5 @@ Gradle plugin for creating fat/uber JARs with support for package relocation.
| 9.3.0+ | 9.0 | 17 | [`com.gradleup.shadow`][gradleup's] |
| 9.5.0+ | 9.2 | 17 | [`com.gradleup.shadow`][gradleup's] |



[johnrengelman's]: https://plugins.gradle.org/plugin/com.github.johnrengelman.shadow
[gradleup's]: https://plugins.gradle.org/plugin/com.gradleup.shadow
33 changes: 14 additions & 19 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

# Introduction

Shadow is a Gradle plugin for combining a project's dependency classes and resources into a single
output Jar. The combined Jar is often referred to a _fat-jar_ or _uber-jar_.
Shadow utilizes [`JarInputStream`][JarInputStream] and [`JarOutputStream`][JarOutputStream] to efficiently process
dependent libraries into the output jar without incurring the I/O overhead of expanding the jars to disk.
Shadow is a Gradle plugin for combining a project's dependency classes and resources into a single output Jar. The
combined Jar is often referred to a _fat-jar_ or _uber-jar_. Shadow utilizes [`JarInputStream`][JarInputStream] and [
`JarOutputStream`][JarOutputStream] to efficiently process dependent libraries into the output jar without incurring the
I/O overhead of expanding the jars to disk.

!!! warning "Plugin ID Change"

Expand Down Expand Up @@ -39,34 +39,29 @@ Shadowing a project output has 2 major use cases:
### Executable Distributions

Executable distribution is the main use case for deploying an _application_ that can be executed/run in the runtime
environment.
In the case of Shadow, this is a single _uber_ or _fat_ JAR.
The JAR file contains all the application code and dependent libraries to execute (not including the standard JVM
libraries).
The shadow JAR does **not** include the JRE itself.
It must be available on the target system.
environment. In the case of Shadow, this is a single _uber_ or _fat_ JAR. The JAR file contains all the application code
and dependent libraries to execute (not including the standard JVM libraries). The shadow JAR does **not** include the
JRE itself. It must be available on the target system.

Executable JARs contain a JAR MANIFEST that specifies the application Main Class.
This allows the application to be started with a single command:
Executable JARs contain a JAR MANIFEST that specifies the application Main Class. This allows the application to be
started with a single command:

```sh
java -jar application-shadow.jar
```

### Library Bundling

Dependency bundling and relocation is the main use case for _library_ authors.
The goal of a bundled library is to create a pre-packaged dependency for other libraries or applications to utilize.
Often in these scenarios, a library may contain a dependency that a downstream library or application also uses.
In _some_ cases, different versions of this common dependency can cause an issue in either the upstream library or
the downstream application.
These issues often manifest themselves as binary incompatibilities in either the library or application code.
Dependency bundling and relocation is the main use case for _library_ authors. The goal of a bundled library is to
create a pre-packaged dependency for other libraries or applications to utilize. Often in these scenarios, a library may
contain a dependency that a downstream library or application also uses. In _some_ cases, different versions of this
common dependency can cause an issue in either the upstream library or the downstream application. These issues often
manifest themselves as binary incompatibilities in either the library or application code.

By utilizing Shadow's ability to _relocate_ the package names for dependencies, a library author can ensure that the
library's dependencies will not conflict with the same dependency being declared by the downstream application.



[JarInputStream]: https://docs.oracle.com/javase/8/docs/api/java/util/jar/JarInputStream.html
[JarOutputStream]: https://docs.oracle.com/javase/8/docs/api/java/util/jar/JarOutputStream.html
[johnrengelman's]: https://plugins.gradle.org/plugin/com.github.johnrengelman.shadow
Expand Down
18 changes: 7 additions & 11 deletions docs/about/README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
# About This Project

I (John Engelman) started this project in December 2012. We were working on converting from a monolithic application
into the new hot jazz of "microservices" using Dropwizard.
I had also just started learning about Gradle and I knew that the incremental build system it provided would benefit
our development team greatly.
Unfortunately, the closest thing that Gradle had to Maven's Shade plugin was its ability to create application TARs and
ZIPs.
into the new hot jazz of "microservices" using Dropwizard. I had also just started learning about Gradle and I knew that
the incremental build system it provided would benefit our development team greatly. Unfortunately, the closest thing
that Gradle had to Maven's Shade plugin was its ability to create application TARs and ZIPs.

So, Charlie Knudsen and I set out to port the existing Shade code into a Gradle plugin.
This port is what existed up until the `0.9` milestone releases for Shadow.
It functioned, but it wasn't idiomatic Gradle by any means.
So, Charlie Knudsen and I set out to port the existing Shade code into a Gradle plugin. This port is what existed up
until the `0.9` milestone releases for Shadow. It functioned, but it wasn't idiomatic Gradle by any means.

Starting with 0.9, Shadow was rewritten from the ground up as standard Gradle plugin and leveraged as much of Gradle's
classes and concepts as possible.
At the same time as the 0.9 release, Gradle was announcing the [Gradle Plugin Portal](https://plugins.gradle.org) and
so Shadow was published there.
classes and concepts as possible. At the same time as the 0.9 release, Gradle was announcing
the [Gradle Plugin Portal](https://plugins.gradle.org) and so Shadow was published there.

## Maintainers

Expand Down
19 changes: 8 additions & 11 deletions docs/application-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
Shadow reacts to the presence of Gradle's [`application`][application] plugin and will automatically configure
additional tasks for running the shadowed JAR and creating distributions containing the shadowed JAR.

Just like the normal [`Jar`][Jar] task, when the [`application`][application] plugin is applied,
the [`ShadowJar`][ShadowJar] manifest will be configured to contain the `Main-Class` attribute with the value specified
in the project's `application.mainClass` attribute.
Just like the normal [`Jar`][Jar] task, when the [`application`][application] plugin is applied, the [
`ShadowJar`][ShadowJar] manifest will be configured to contain the `Main-Class` attribute with the value specified in
the project's `application.mainClass` attribute.

=== "Kotlin"

Expand Down Expand Up @@ -35,10 +35,9 @@ in the project's `application.mainClass` attribute.

## Running the Shadow JAR

When applied along with the `application` plugin, the `runShadow` task will be created for starting
the application from the shadowed JAR.
The `runShadow` task is a [`JavaExec`][JavaExec] task that is configured to execute `java -jar myproject-all.jar`.
It can be configured the same as any other [`JavaExec`][JavaExec] task.
When applied along with the `application` plugin, the `runShadow` task will be created for starting the application from
the shadowed JAR. The `runShadow` task is a [`JavaExec`][JavaExec] task that is configured to execute
`java -jar myproject-all.jar`. It can be configured the same as any other [`JavaExec`][JavaExec] task.

=== "Kotlin"

Expand Down Expand Up @@ -81,9 +80,8 @@ It can be configured the same as any other [`JavaExec`][JavaExec] task.
## Distributing the Shadow JAR

The Shadow plugin will also configure distribution tasks when in the presence of the [`application`][application]
plugin. The plugin will create `shadowDistZip` and `shadowDistTar` which creates Zip and Tar distributions
respectively. Each distribution will contain the shadowed JAR file along with the necessary start scripts to launch
the application.
plugin. The plugin will create `shadowDistZip` and `shadowDistTar` which creates Zip and Tar distributions respectively.
Each distribution will contain the shadowed JAR file along with the necessary start scripts to launch the application.

Additionally, the plugin will create the `installShadowDist` and `startShadowScripts` tasks which stages the necessary
files for a distribution to `build/install/<project name>-shadow/`.
Expand Down Expand Up @@ -170,7 +168,6 @@ View [The Distribution Plugin](https://docs.gradle.org/current/userguide/distrib
for more information about configuring distributions.



[Jar]: https://docs.gradle.org/current/dsl/org.gradle.api.tasks.bundling.Jar.html
[JavaExec]: https://docs.gradle.org/current/dsl/org.gradle.api.tasks.JavaExec.html
[ShadowJar]: ../api/shadow/com.github.jengelman.gradle.plugins.shadow.tasks/-shadow-jar/index.html
Expand Down
42 changes: 20 additions & 22 deletions docs/configuration/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Configuring Shadow

The [`ShadowJar`][ShadowJar] task type extends from Gradle's [`Jar`][Jar] type.
This means that all attributes and methods available on [`Jar`][Jar] are also available on [`ShadowJar`][ShadowJar].
The [`ShadowJar`][ShadowJar] task type extends from Gradle's [`Jar`][Jar] type. This means that all attributes and
methods available on [`Jar`][Jar] are also available on [`ShadowJar`][ShadowJar].

## Configuring Output Name

Expand Down Expand Up @@ -47,22 +47,19 @@ This will result in the output file being named `myApp-all.jar` instead of `myAp

## Configuring the Runtime Classpath

Each Java JAR file contains a manifest file that provides metadata about the contents of the JAR file itself.
When using a shadowed JAR file as an executable JAR, it is assumed that all necessary runtime classes are contained
within the JAR itself.
There may be situations where the desire is to **not** bundle select dependencies into the shadowed JAR file, but
they are still required for runtime execution.
Each Java JAR file contains a manifest file that provides metadata about the contents of the JAR file itself. When using
a shadowed JAR file as an executable JAR, it is assumed that all necessary runtime classes are contained within the JAR
itself. There may be situations where the desire is to **not** bundle select dependencies into the shadowed JAR file,
but they are still required for runtime execution.

In these scenarios, Shadow creates a `shadow` configuration to declare these dependencies.
Dependencies added to the `shadow` configuration are **not** bundled into the output JAR.
Think of `configurations.shadow` as unmerged, runtime dependencies.
The integration with the [`maven-publish`][maven-publish] plugin will automatically configure dependencies added
to `configurations.shadow` as `RUNTIME` scope dependencies in the resulting POM file.
In these scenarios, Shadow creates a `shadow` configuration to declare these dependencies. Dependencies added to the
`shadow` configuration are **not** bundled into the output JAR. Think of `configurations.shadow` as unmerged, runtime
dependencies. The integration with the [`maven-publish`][maven-publish] plugin will automatically configure dependencies
added to `configurations.shadow` as `RUNTIME` scope dependencies in the resulting POM file.

Additionally, Shadow automatically configures the manifest of the [`ShadowJar`][ShadowJar] task to contain a
`Class-Path` entry in the JAR manifest.
The value of the `Class-Path` entry is the name of all dependencies resolved in the `shadow` configuration for the
project.
`Class-Path` entry in the JAR manifest. The value of the `Class-Path` entry is the name of all dependencies resolved in
the `shadow` configuration for the project.

=== "Kotlin"

Expand Down Expand Up @@ -91,8 +88,8 @@ When deploying a shadowed JAR as an execution JAR, it is important to note that

## Configuring the JAR Manifest

The [`ShadowJar`][ShadowJar] manifest is configured in a number of ways. First, the manifest for the `shadowJar` task
is configured to __inherit__ from the manifest of the standard `jar` task.
The [`ShadowJar`][ShadowJar] manifest is configured in a number of ways. First, the manifest for the `shadowJar` task is
configured to __inherit__ from the manifest of the standard `jar` task.

=== "Kotlin"

Expand Down Expand Up @@ -153,8 +150,8 @@ configure the upstream.

## Adding Multi-Release Manifest Attribute

The [`ShadowJar`][ShadowJar] task can automatically add the `Multi-Release` attribute to the JAR manifest if any of
the included dependencies contain this attribute. This is controlled by the `addMultiReleaseAttribute` property.
The [`ShadowJar`][ShadowJar] task can automatically add the `Multi-Release` attribute to the JAR manifest if any of the
included dependencies contain this attribute. This is controlled by the `addMultiReleaseAttribute` property.

By default, `addMultiReleaseAttribute` is set to `true`. When enabled, Shadow will scan all dependencies being merged
into the shadow JAR. If any dependency JAR has the `Multi-Release` manifest attribute set to `true`, Shadow will add
Expand All @@ -178,8 +175,8 @@ You can disable this behavior by setting `addMultiReleaseAttribute` to `false`:
}
```

This is useful if you want to control the presence of the `Multi-Release` attribute manually or avoid inheriting it
from dependencies.
This is useful if you want to control the presence of the `Multi-Release` attribute manually or avoid inheriting it from
dependencies.

## Adding Extra Files

Expand Down Expand Up @@ -208,7 +205,8 @@ method can be used to add extra files.
}
```

See also [Embedding Local Jar Files Into Your Shadowed Jar](dependencies/README.md#embedding-local-jar-files-into-your-shadowed-jar).
See
also [Embedding Local Jar Files Into Your Shadowed Jar](dependencies/README.md#embedding-local-jar-files-into-your-shadowed-jar).


[Jar.from]: https://docs.gradle.org/current/dsl/org.gradle.jvm.tasks.Jar.html#org.gradle.jvm.tasks.Jar:from(java.lang.Object,%20org.gradle.api.Action)
Expand Down
25 changes: 11 additions & 14 deletions docs/configuration/dependencies/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ merging can be configured using the [`configurations`][ShadowJar.configurations]
```

The above code sample would configure the [`ShadowJar`][ShadowJar] task to merge dependencies from only the
`compileClasspath` configuration.
This means any dependency declared in the `runtimeOnly` configuration would be **not** be included in the final JAR.
`compileClasspath` configuration. This means any dependency declared in the `runtimeOnly` configuration would be **not**
be included in the final JAR.

> Note the literal use of [`project.configurations`][Project.configurations] when setting the
> [`configurations`][ShadowJar.configurations] attribute of a [`ShadowJar`][ShadowJar] task.
Expand Down Expand Up @@ -99,9 +99,9 @@ See also [Adding Extra Files](../README.md#adding-extra-files)
Dependencies added into `runtimeClasspath` configuration (`api`, `implementation`, `runtimeOnly`) will be unzipped and
merged into the shadowed JAR. Not all dependencies are JAR files, e.g. some of them are
[POM files](https://repo1.maven.org/maven2/org/graalvm/polyglot/js-community/24.2.2/),
[SO files](https://repo1.maven.org/maven2/io/github/ganadist/sqlite4java/libsqlite4java-osx-aarch64/1.0.392/),
and so on. If such dependencies are added into `runtimeClasspath`, you will encounter the following error when building
the shadowed JAR:
[SO files](https://repo1.maven.org/maven2/io/github/ganadist/sqlite4java/libsqlite4java-osx-aarch64/1.0.392/), and so
on. If such dependencies are added into `runtimeClasspath`, you will encounter the following error when building the
shadowed JAR:

```
* What went wrong:
Expand Down Expand Up @@ -168,8 +168,8 @@ configuration.

### Excluding Non-JAR Transitive Dependencies

If the non-JAR file is a transitive dependency (e.g., a POM-only metapackage) that you don't actually need
in your shadowed JAR, you can exclude it using the `dependencies` block instead of embedding it.
If the non-JAR file is a transitive dependency (e.g., a POM-only metapackage) that you don't actually need in your
shadowed JAR, you can exclude it using the `dependencies` block instead of embedding it.

=== "Kotlin"

Expand Down Expand Up @@ -200,8 +200,8 @@ in your shadowed JAR, you can exclude it using the `dependencies` block instead
## Filtering Dependencies

Individual dependencies can be filtered from the final JAR by using the `dependencies` block of a
[`ShadowJar`][ShadowJar] task. Dependency filtering does **not** apply to transitive dependencies.
That is, excluding a dependency does not exclude any of its dependencies from the final JAR.
[`ShadowJar`][ShadowJar] task. Dependency filtering does **not** apply to transitive dependencies. That is, excluding a
dependency does not exclude any of its dependencies from the final JAR.

The `dependency` blocks provides a number of methods for resolving dependencies using the notations familiar from
Gradle's [`project.configurations`][Project.configurations] block.
Expand Down Expand Up @@ -268,9 +268,8 @@ Gradle's [`project.configurations`][Project.configurations] block.

### Using Regex Patterns to Filter Dependencies

Dependencies can be filtered using regex patterns.
Coupled with the `<group>:<artifact>:<version>` notation for dependencies, this allows for excluding/including
using any of these individual fields.
Dependencies can be filtered using regex patterns. Coupled with the `<group>:<artifact>:<version>` notation for
dependencies, this allows for excluding/including using any of these individual fields.

=== "Kotlin"

Expand Down Expand Up @@ -475,8 +474,6 @@ block provides a method that accepts a `Closure` for selecting dependencies.
}
```



[Jar.from]: https://docs.gradle.org/current/dsl/org.gradle.jvm.tasks.Jar.html#org.gradle.jvm.tasks.Jar:from(java.lang.Object,%20org.gradle.api.Action)
[Jar]: https://docs.gradle.org/current/dsl/org.gradle.api.tasks.bundling.Jar.html
[ShadowJar.configurations]: ../../api/shadow/com.github.jengelman.gradle.plugins.shadow.tasks/-shadow-jar/configurations.html
Expand Down
8 changes: 3 additions & 5 deletions docs/configuration/filtering/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
The final contents of a shadow JAR can be filtered using the `exclude` and `include` methods inherited from Gradle's
[`Jar`][Jar] task type.

When using `exclude`/`include` with a [`ShadowJar`][ShadowJar] task, the resulting copy specs are applied to the
_final_ JAR contents. This means that, the configuration is applied to the individual files from both the project
source set or _any_ of the dependencies to be merged.
When using `exclude`/`include` with a [`ShadowJar`][ShadowJar] task, the resulting copy specs are applied to the _final_
JAR contents. This means that, the configuration is applied to the individual files from both the project source set or
_any_ of the dependencies to be merged.

=== "Kotlin"

Expand Down Expand Up @@ -46,7 +46,5 @@ Excludes and includes can be combined just like a normal [`Jar`][Jar] task, with
}
```



[Jar]: https://docs.gradle.org/current/dsl/org.gradle.api.tasks.bundling.Jar.html
[ShadowJar]: ../../api/shadow/com.github.jengelman.gradle.plugins.shadow.tasks/-shadow-jar/index.html
Loading