Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support overriding mainClass provided by JavaApplication #1182

Merged
merged 3 commits into from
Jan 23, 2025
Merged
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
4 changes: 4 additions & 0 deletions src/docs/changes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

## [Unreleased]

**Fixed**

- Support overriding `mainClass` provided by `JavaApplication`. ([#1182](https://github.com/GradleUp/shadow/pull/1182))


## [v9.0.0-beta6] (2025-01-23)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import assertk.assertions.exists
import assertk.assertions.isEqualTo
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.util.Issue
import com.github.jengelman.gradle.plugins.shadow.util.JarPath
import com.github.jengelman.gradle.plugins.shadow.util.containsEntries
import com.github.jengelman.gradle.plugins.shadow.util.getContent
Expand Down Expand Up @@ -45,7 +46,7 @@ class ApplicationPluginTest : BasePluginTest() {

assertThat(result.output).contains(
"Running application with JDK 17",
"Hello, World! (foo)",
"Hello, World! (foo) from Main",
)

commonAssertions(jarPath("build/install/myapp-shadow/lib/myapp-1.0-all.jar"))
Expand Down Expand Up @@ -108,6 +109,33 @@ class ApplicationPluginTest : BasePluginTest() {
commonAssertions(jarPath("build/install/myapp-shadow/lib/myapp-1.0-all.jar"))
}

@Issue(
"https://github.com/GradleUp/shadow/issues/613",
)
@Test
fun canOverrideMainClassAttrInManifestBlock() {
writeMainClass(className = "Main2")
prepare(
projectBlock = """
shadowJar {
manifest {
attributes 'Main-Class': 'shadow.Main2'
}
}
""".trimIndent(),
)

val result = run(SHADOW_RUN_TASK_NAME)

assertThat(result.output).contains(
"Hello, World! (foo) from Main2",
)
commonAssertions(
jarPath("build/install/myapp-shadow/lib/myapp-1.0-all.jar"),
mainClassAttr = "shadow.Main2",
)
}

private fun prepare(
projectBlock: String = "",
settingsBlock: String = "",
Expand Down Expand Up @@ -142,10 +170,11 @@ class ApplicationPluginTest : BasePluginTest() {
private fun commonAssertions(
jarPath: JarPath,
entriesContained: Array<String> = arrayOf("a.properties", "a2.properties", "shadow/Main.class"),
mainClassAttr: String = "shadow.Main",
) {
assertThat(jarPath).useAll {
containsEntries(*entriesContained)
getMainAttr("Main-Class").isEqualTo("shadow.Main")
getMainAttr("Main-Class").isEqualTo(mainClassAttr)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,16 +155,17 @@ abstract class BasePluginTest {

fun writeMainClass(
withImports: Boolean = false,
className: String = "Main",
) {
val imports = if (withImports) "import junit.framework.Test;" else ""

path("src/main/java/shadow/Main.java").writeText(
path("src/main/java/shadow/$className.java").writeText(
"""
package shadow;
$imports
public class Main {
public class $className {
public static void main(String[] args) {
String content = String.format("Hello, World! (%s)", args);
String content = String.format("Hello, World! (%s) from $className", args);
System.out.println(content);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ public abstract class ShadowApplicationPlugin : Plugin<Project> {
shadowJar.configure { jar ->
jar.inputs.property("mainClassName", classNameProvider)
jar.doFirst {
jar.manifest.attributes["Main-Class"] = classNameProvider.get()
// Inject the Main-Class attribute if it is not already present.
if (!jar.manifest.attributes.contains("Main-Class")) {
jar.manifest.attributes["Main-Class"] = classNameProvider.get()
}
}
}
}
Expand Down