Repository: GradleUp/shadow (kotlin)

Issue:
Gigantic jar when using Gradle 8.x
Please check the [User Guide](http://imperceptiblethoughts.com/shadow) before submitting "how do I do 'x'?" questions!

### Shadow Version

8.1.1

### Gradle Version

8.6

### Expected Behavior

Should only need to shadow bouncycastle dependencies, and resulting jar should be small, with just bouncycastle relocated.

### Actual Behavior

Without adding a number of other dependencies, the resulting jar was not usable by our code, which failed at runtime with missing-class exceptions.

See comment in shadow-bad's dependency.gradle that starts with "// If this dependencies{} block is commented out".

[shadow-good.zip](https://github.com/johnrengelman/shadow/files/14529660/shadow-good.zip)

[shadow-bad.zip](https://github.com/johnrengelman/shadow/files/14529663/shadow-bad.zip)

Pull request description:
- Ports #459.
- Reverts #675.
- Reverts d530cff65c086e1cdd666bf3b12663949ae7ffcc.
- Closes #910.

Patch:
diff --git a/build.gradle b/build.gradle
index a184c9e77..28e75df46 100644
--- a/build.gradle
+++ b/build.gradle
@@ -44,13 +44,6 @@ tasks.withType(Test).configureEach {
     )
 }
 
-// Remove the gradleApi so it isn't merged into the jar file.
-// This is required because 'java-gradle-plugin' adds gradleApi() to the 'api' configuration.
-// See https://github.com/gradle/gradle/blob/972c3e5c6ef990dd2190769c1ce31998a9402a79/subprojects/plugin-development/src/main/java/org/gradle/plugin/devel/plugins/JavaGradlePluginPlugin.java#L161
-configurations.named(JavaPlugin.API_CONFIGURATION_NAME) {
-    dependencies.remove(project.dependencies.gradleApi())
-}
-
 tasks.named('shadowJar', ShadowJar) {
     from rootProject.file('LICENSE')
     from rootProject.file('NOTICE')
diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle
index 0d6264cd4..62dcc8e6e 100644
--- a/gradle/dependencies.gradle
+++ b/gradle/dependencies.gradle
@@ -1,6 +1,5 @@
 dependencies {
     compileOnly localGroovy()
-    compileOnly gradleApi()
     shadow 'org.codehaus.groovy:groovy-backports-compat23:3.0.8'
 
     implementation 'org.jdom:jdom2:2.0.6.1'
diff --git a/src/docs/configuration/relocation/README.md b/src/docs/configuration/relocation/README.md
index aa2c36d6e..ee5b90d6d 100644
--- a/src/docs/configuration/relocation/README.md
+++ b/src/docs/configuration/relocation/README.md
@@ -84,6 +84,4 @@ In versions before 8.1.0 it was necessary to configure a separate `ConfigureShad
 > Configuring package auto relocation can add significant time to the shadow process as it will process all dependencies
 in the configurations declared to be shadowed. By default, this is the `runtime` or `runtimeClasspath` configurations.
 Be mindful that some Gradle plugins will automatically add dependencies to your class path. You may need to remove these 
-dependencies if you do not intend to shadow them into your library.  The `java-gradle-plugin` would normally cause such
-problems if it were not for the special handling that Shadow provides as described in 
-[Special Handling of the Java Gradle Plugin Development Plugin](/plugins/#special-handling-of-the-java-gradle-plugin-gevelopmeny-plugin).
+dependencies if you do not intend to shadow them into your library.
\ No newline at end of file
diff --git a/src/docs/plugins/README.md b/src/docs/plugins/README.md
index 6ce6397f4..1736cb9c9 100644
--- a/src/docs/plugins/README.md
+++ b/src/docs/plugins/README.md
@@ -46,16 +46,6 @@ Starting with this version, plugin projects that apply both Shadow and the Gradl
 automatically configured to publish the output of the `shadowJar` tasks as the consumable artifact for the plugin.
 See the [Gradle Plugin Publish docs](https://docs.gradle.org/current/userguide/publishing_gradle_plugins.html#shadow_dependencies) for details.
 
-## Special Handling of the Java Gradle Plugin Development Plugin
-
-The Java Gradle Plugin Development plugin, `java-gradle-plugin`, automatically adds the full Gradle API to the `compile` 
-configuration; thus overriding a possible assignment of `gradleApi()` to the `shadow` configuration.  Since it is never
-a good idea to include the Gradle API when creating a Gradle plugin, the dependency is removed so that it is not 
-included in the resultant shadow jar.  Virtually:
-
-    // needed to prevent inclusion of gradle-api into shadow JAR
-    configurations.compile.dependencies.remove dependencies.gradleApi()
-
 ## Automatic package relocation with Shadow prior to v8.1.0
 
 Prior to Shadow v8.1.0, Shadow handled this by introducing a new task type `ConfigureShadowRelocation`.
diff --git a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowJavaPlugin.groovy b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowJavaPlugin.groovy
index aec258850..d3926974e 100644
--- a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowJavaPlugin.groovy
+++ b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowJavaPlugin.groovy
@@ -7,8 +7,10 @@ import org.gradle.api.attributes.Bundling
 import org.gradle.api.attributes.Category
 import org.gradle.api.attributes.LibraryElements
 import org.gradle.api.attributes.Usage
+import org.gradle.api.plugins.JavaPlugin
 import org.gradle.api.tasks.SourceSetContainer
 import org.gradle.configuration.project.ProjectConfigurationActionContainer
+import org.gradle.plugin.devel.plugins.JavaGradlePluginPlugin
 
 import javax.inject.Inject
 
@@ -51,6 +53,19 @@ class ShadowJavaPlugin implements Plugin<Project> {
                 mapToOptional() // make it a Maven optional dependency
             }
         }
+
+        project.plugins.withType(JavaGradlePluginPlugin).configureEach {
+            // Remove the gradleApi so it isn't merged into the jar file.
+            // This is required because 'java-gradle-plugin' adds gradleApi() to the 'api' configuration.
+            // See https://github.com/gradle/gradle/blob/972c3e5c6ef990dd2190769c1ce31998a9402a79/subprojects/plugin-development/src/main/java/org/gradle/plugin/devel/plugins/JavaGradlePluginPlugin.java#L161
+            project.configurations.named(JavaPlugin.API_CONFIGURATION_NAME) {
+                it.dependencies.remove(project.dependencies.gradleApi())
+            }
+            // Compile only gradleApi() to make sure the plugin can compile against Gradle API.
+            project.configurations.named(JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME) {
+                it.dependencies.add(project.dependencies.gradleApi())
+            }
+        }
     }
 
     protected static void configureShadowTask(Project project) {
@@ -75,9 +90,6 @@ class ShadowJavaPlugin implements Plugin<Project> {
             shadow.configurations = [project.configurations.findByName('runtimeClasspath') ?
                                              project.configurations.runtimeClasspath : project.configurations.runtime]
             shadow.exclude('META-INF/INDEX.LIST', 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA', 'module-info.class')
-            shadow.dependencies {
-                exclude(dependency(project.dependencies.gradleApi()))
-            }
         }
         project.artifacts.add(ShadowBasePlugin.CONFIGURATION_NAME, project.tasks.named(SHADOW_JAR_TASK_NAME))
     }


Test patch:
diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowPluginSpec.groovy b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowPluginSpec.groovy
index 7cec61db8..f7035e395 100644
--- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowPluginSpec.groovy
+++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowPluginSpec.groovy
@@ -1217,6 +1217,36 @@ class ShadowPluginSpec extends PluginSpecification {
         assert result.output.contains('TestApp: Hello World! (foo)')
     }
 
+    @Issue("https://github.com/GradleUp/shadow/pull/459")
+    def 'exclude gradleApi() by default'() {
+        given:
+        buildFile.text = getDefaultBuildScript('java-gradle-plugin')
+
+        file('src/main/java/my/plugin/MyPlugin.java') << """
+            package my.plugin;
+            import org.gradle.api.Plugin;
+            import org.gradle.api.Project;
+            public class MyPlugin implements Plugin<Project> {
+                public void apply(Project project) {
+                    System.out.println("MyPlugin: Hello World!");
+                }
+            }
+        """.stripIndent()
+        file('src/main/resources/META-INF/gradle-plugins/my.plugin.properties') << """
+            implementation-class=my.plugin.MyPlugin
+        """.stripIndent()
+
+        when:
+        run('shadowJar')
+
+        then:
+        assert output.exists()
+
+        and:
+        JarFile jar = new JarFile(output)
+        assert jar.entries().collect().findAll { it.name.endsWith('.class') }.size() == 1
+    }
+
     private String escapedPath(File file) {
         file.path.replaceAll('\\\\', '\\\\\\\\')
     }