Repository: GradleUp/shadow
Pull request #1353 (2025-03-18 01:48:34)

No need to make `runShadow` depend on `installShadowDist`
- Split `installShadowOutputs` from `integrationWithApplicationPluginAndJavaToolchains`.
- Tweak `canOverrideMainClassAttrInManifestBlock`.

---

- [x] [CHANGELOG](https://github.com/GradleUp/shadow/blob/main/docs/changes/README.md)'s "Unreleased" section has been updated, if applicable.



Patch:
diff --git a/docs/changes/README.md b/docs/changes/README.md
index 702487ab..18c70f78 100644
--- a/docs/changes/README.md
+++ b/docs/changes/README.md
@@ -16,6 +16,7 @@
   - `ShadowSpec` no longer extends `CopySpec`.
   - Overload `relocate`, `transform` and things for better usability in Kotlin.
 - **BREAKING CHANGE:** Remove redundant types from function returning. ([#1308](https://github.com/GradleUp/shadow/pull/1308))
+- `runShadow` no longer depends on `installShadowDist`. ([#1353](https://github.com/GradleUp/shadow/pull/1353))
 
 **Fixed**
 
diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/ShadowApplicationPlugin.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/ShadowApplicationPlugin.kt
index 198e13cb..fc0ba4c2 100644
--- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/ShadowApplicationPlugin.kt
+++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/ShadowApplicationPlugin.kt
@@ -40,10 +40,7 @@ public abstract class ShadowApplicationPlugin : Plugin<Project> {
       task.description = "Runs this project as a JVM application using the shadow jar"
       task.group = ApplicationPlugin.APPLICATION_GROUP
 
-      val jarFile = tasks.installShadowDist.zip(tasks.shadowJar) { i, s ->
-        i.destinationDir.resolve("lib/${s.archiveFile.get().asFile.name}")
-      }
-      task.classpath(jarFile)
+      task.classpath = files(tasks.shadowJar)
 
       with(applicationExtension) {
         task.mainModule.set(mainModule)


Test patch:
diff --git a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/ApplicationPluginTest.kt b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/ApplicationPluginTest.kt
index f5369c2c..9082e776 100644
--- a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/ApplicationPluginTest.kt
+++ b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/ApplicationPluginTest.kt
@@ -6,7 +6,6 @@ import assertk.assertions.contains
 import assertk.assertions.containsOnly
 import assertk.assertions.doesNotContain
 import assertk.assertions.isEqualTo
-import com.github.jengelman.gradle.plugins.shadow.ShadowApplicationPlugin.Companion.SHADOW_INSTALL_TASK_NAME
 import com.github.jengelman.gradle.plugins.shadow.ShadowBasePlugin.Companion.DISTRIBUTION_NAME
 import com.github.jengelman.gradle.plugins.shadow.internal.classPathAttributeKey
 import com.github.jengelman.gradle.plugins.shadow.internal.mainClassAttributeKey
@@ -43,9 +42,6 @@ class ApplicationPluginTest : BasePluginTest() {
           toolchain.languageVersion = JavaLanguageVersion.of(17)
         }
       """.trimIndent(),
-      applicationBlock = """
-        applicationDefaultJvmArgs = ['--add-opens=java.base/java.lang=ALL-UNNAMED']
-      """.trimIndent(),
       settingsBlock = """
         plugins {
           id 'org.gradle.toolchains.foojay-resolver-convention'
@@ -65,6 +61,17 @@ class ApplicationPluginTest : BasePluginTest() {
       "Hello, World! (foo) from Main",
       "Refs: junit.framework.Test",
     )
+  }
+
+  @Test
+  fun installShadowOutputs() {
+    prepare(
+      mainClassWithImports = true,
+      dependenciesBlock = "implementation 'junit:junit:3.8.2'",
+      applicationBlock = "applicationDefaultJvmArgs = ['--add-opens=java.base/java.lang=ALL-UNNAMED']",
+    )
+
+    run(installShadowDistTask)
 
     val installPath = path("build/install/")
     assertThat(installPath.walkEntries()).containsOnly(
@@ -106,7 +113,7 @@ class ApplicationPluginTest : BasePluginTest() {
   fun installShadowDoesNotExecuteDependentShadowTask() {
     prepare()
 
-    run(SHADOW_INSTALL_TASK_NAME)
+    run(installShadowDistTask)
 
     commonAssertions(jarPath("build/install/myapp-shadow/lib/myapp-1.0-all.jar"))
   }
@@ -134,9 +141,9 @@ class ApplicationPluginTest : BasePluginTest() {
       }
     }
 
-    assertions(run(runShadowTask).output, "foo")
+    assertions(run(runShadowTask, shadowJarTask).output, "foo")
     commonAssertions(
-      jarPath("build/install/myapp-shadow/lib/myapp-1.0-all.jar"),
+      jarPath("build/libs/myapp-1.0-all.jar"),
       entriesContained = entriesInA + arrayOf(mainClass, main2ClassEntry),
       mainClassAttr = "my.Main2",
     )
diff --git a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/BasePluginTest.kt b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/BasePluginTest.kt
index 9b5f6c7f..10779b2a 100644
--- a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/BasePluginTest.kt
+++ b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/BasePluginTest.kt
@@ -6,6 +6,7 @@ import assertk.assertThat
 import assertk.assertions.doesNotContain
 import assertk.assertions.isEqualTo
 import assertk.assertions.isNotNull
+import com.github.jengelman.gradle.plugins.shadow.ShadowApplicationPlugin.Companion.SHADOW_INSTALL_TASK_NAME
 import com.github.jengelman.gradle.plugins.shadow.ShadowApplicationPlugin.Companion.SHADOW_RUN_TASK_NAME
 import com.github.jengelman.gradle.plugins.shadow.ShadowJavaPlugin.Companion.SHADOW_JAR_TASK_NAME
 import com.github.jengelman.gradle.plugins.shadow.internal.requireResourceAsPath
@@ -56,6 +57,7 @@ abstract class BasePluginTest {
   val shadowJarTask = ":$SHADOW_JAR_TASK_NAME"
   val serverShadowJarTask = ":server:$SHADOW_JAR_TASK_NAME"
   val runShadowTask = ":$SHADOW_RUN_TASK_NAME"
+  val installShadowDistTask = ":$SHADOW_INSTALL_TASK_NAME"
   val shadowDistZipTask = ":shadowDistZip"
 
   val projectScriptPath: Path get() = path("build.gradle")