diff --git a/docs/changes/README.md b/docs/changes/README.md index ea3078b2c..ee079a86f 100644 --- a/docs/changes/README.md +++ b/docs/changes/README.md @@ -3,6 +3,9 @@ ## [Unreleased](https://github.com/GradleUp/shadow/compare/9.0.0...HEAD) - 2025-xx-xx +### Added + +- Improve the error message for empty `mainClassName`. ([#1601](https://github.com/GradleUp/shadow/pull/1601)) ## [9.0.0](https://github.com/GradleUp/shadow/compare/9.0.0) - 2025-08-07 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 f931db3b5..ef7d1a14c 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 @@ -158,6 +158,17 @@ class ApplicationPluginTest : BasePluginTest() { assertions(run(":run").output, "bar") } + @Test + fun errorWhenMainClassNotSet() { + prepare(mainClassBlock = "") + + val result = runWithFailure(runShadowTask) + + assertThat(result.output).contains( + "The main class must be specified and not left empty in `application.mainClass` or manifest attributes.", + ) + } + @Test fun addExtraFilesIntoDistribution() { path("extra/echo.sh").writeText("echo 'Hello, World!'") @@ -220,6 +231,7 @@ class ApplicationPluginTest : BasePluginTest() { private fun prepare( mainClassWithImports: Boolean = false, projectBlock: String = "", + mainClassBlock: String = "mainClass = 'my.Main'", applicationBlock: String = "", settingsBlock: String = "", dependenciesBlock: String = "implementation 'my:a:1.0'", @@ -231,7 +243,7 @@ class ApplicationPluginTest : BasePluginTest() { apply plugin: 'application' $projectBlock application { - mainClass = 'my.Main' + $mainClassBlock $applicationBlock } dependencies { 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 e6e30d304..72d362abc 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 @@ -129,11 +129,14 @@ public abstract class ShadowApplicationPlugin : Plugin { protected open fun Project.configureShadowJarMainClass() { val mainClassName = applicationExtension.mainClass tasks.shadowJar.configure { task -> - task.inputs.property("mainClassName", mainClassName) task.doFirst { // Inject the attribute if it is not already present. if (!task.manifest.attributes.contains(mainClassAttributeKey)) { - task.manifest.attributes[mainClassAttributeKey] = mainClassName.get() + task.manifest.attributes[mainClassAttributeKey] = mainClassName.orNull.also { value -> + if (value.isNullOrEmpty()) { + error("The main class must be specified and not left empty in `application.mainClass` or manifest attributes.") + } + } } } }