Repository: GradleUp/shadow (kotlin)

Issue:
Regression: Creating shadowJar fails when configurations contain directories (9.0.0)
### Expected and Results

Expected: ShadowJar would contain all classes and resources from its configurations. (as in latest 8.x release)

Actual: The execution of shadowJar fails with the message:

```
Execution failed for task ':myproj:shadowJar'.
> Cannot expand ZIP '/Users/myuser/devel/myproj/build/classes/java/custom' as it is not a file.
```
(The referenced path is a output-directory of a custom source set, its contents to not need to be extracted, but should be included)



### Related environment and versions

shadow 8.3.9 => ✅ 
shadow 9.0.0 => ❌ 



### Reproduction steps

_No response_

### Anything else?

_No response_

Pull request:
Closes #1606.

---

- [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 ee079a86f..dc11a63ae 100644
--- a/docs/changes/README.md
+++ b/docs/changes/README.md
@@ -7,6 +7,10 @@
 
 - Improve the error message for empty `mainClassName`. ([#1601](https://github.com/GradleUp/shadow/pull/1601))
 
+### Fixed
+
+- Fix the regression of can't shadow directory inputs. ([#1606](https://github.com/GradleUp/shadow/pull/1606))
+
 ## [9.0.0](https://github.com/GradleUp/shadow/compare/9.0.0) - 2025-08-07
 
 !!! warning
diff --git a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowJar.kt b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowJar.kt
index 386a08e9f..bff26b860 100644
--- a/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowJar.kt
+++ b/src/main/kotlin/com/github/jengelman/gradle/plugins/shadow/tasks/ShadowJar.kt
@@ -345,9 +345,12 @@ public abstract class ShadowJar : Jar() {
 
   @TaskAction
   override fun copy() {
-    from(
-      includedDependencies.files.map { file ->
-        if (file.extension.equals("aar", ignoreCase = true)) {
+    includedDependencies.files.forEach { file ->
+      when {
+        file.isDirectory -> {
+          from(file)
+        }
+        file.extension.equals("aar", ignoreCase = true) -> {
           val message = """
             Shadowing AAR file is not supported.
             Please exclude dependency artifact: $file
@@ -355,9 +358,11 @@ public abstract class ShadowJar : Jar() {
           """.trimIndent()
           error(message)
         }
-        archiveOperations.zipTree(file)
-      },
-    )
+        else -> {
+          from(archiveOperations.zipTree(file))
+        }
+      }
+    }
     injectMultiReleaseAttrIfPresent()
     super.copy()
   }


Test patch:
diff --git a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/JavaPluginsTest.kt b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/JavaPluginsTest.kt
index d2c17cac5..91593960c 100644
--- a/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/JavaPluginsTest.kt
+++ b/src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/JavaPluginsTest.kt
@@ -191,6 +191,53 @@ class JavaPluginsTest : BasePluginTest() {
     }
   }
 
+  @Issue(
+    "https://github.com/GradleUp/shadow/issues/1606",
+  )
+  @Test
+  fun shadowExposedCustomSourceSetOutput() {
+    writeClientAndServerModules()
+    path("client/build.gradle").appendText(
+      """
+        sourceSets {
+          custom
+        }
+        dependencies {
+          implementation sourceSets.custom.output
+        }
+      """.trimIndent(),
+    )
+    path("client/src/custom/java/client/Custom1.java").writeText(
+      """
+        package client;
+        public class Custom1 {}
+      """.trimIndent(),
+    )
+    path("client/src/custom/java/client/Custom2.java").writeText(
+      """
+        package client;
+        public class Custom2 {}
+      """.trimIndent(),
+    )
+    path("client/src/custom/resources/Foo.bar").writeText("Foo=Bar")
+
+    run(serverShadowJarPath)
+
+    assertThat(outputServerShadowedJar).useAll {
+      containsOnly(
+        "Foo.bar",
+        "client/",
+        "server/",
+        "client/Client.class",
+        "client/Custom1.class",
+        "client/Custom2.class",
+        "server/Server.class",
+        *junitEntries,
+        *manifestEntries,
+      )
+    }
+  }
+
   @Issue(
     "https://github.com/GradleUp/shadow/issues/449",
   )