From 1ee93b6a748db2f98aecd6335daa5c52958dbe1f Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Tue, 22 Mar 2022 10:48:39 +0100 Subject: [PATCH] Fix service files not merged with shadow plugin This commit fixes shadow jar building, by making sure that the generated jar merges service files. Fixes #406 --- .../gradle/shadow/ShadowJarSpec.groovy | 80 +++++++++++++++++++ .../MicronautMinimalApplicationPlugin.java | 7 ++ 2 files changed, 87 insertions(+) create mode 100644 functional-tests/src/test/groovy/io/micronaut/gradle/shadow/ShadowJarSpec.groovy diff --git a/functional-tests/src/test/groovy/io/micronaut/gradle/shadow/ShadowJarSpec.groovy b/functional-tests/src/test/groovy/io/micronaut/gradle/shadow/ShadowJarSpec.groovy new file mode 100644 index 00000000..2190956f --- /dev/null +++ b/functional-tests/src/test/groovy/io/micronaut/gradle/shadow/ShadowJarSpec.groovy @@ -0,0 +1,80 @@ +package io.micronaut.gradle.shadow + +import io.micronaut.gradle.fixtures.AbstractFunctionalTest +import org.gradle.testkit.runner.TaskOutcome +import spock.lang.Issue + +class ShadowJarSpec extends AbstractFunctionalTest { + + @Issue("https://github.com/micronaut-projects/micronaut-gradle-plugin/issues/406") + def "merges service files when building shadow jar"() { + def shadowJar = file("build/libs/hello-world-1.0-all.jar") + + given: + settingsFile << "rootProject.name = 'hello-world'" + buildFile << """ + plugins { + id "io.micronaut.minimal.application" + id "com.github.johnrengelman.shadow" version "7.1.0" + } + + version = "1.0" + + micronaut { + version "3.4.0" + runtime "none" + processing { + annotations("example.*") + } + } + + $repositoriesBlock + mainClassName="example.Application" + + dependencies { + annotationProcessor("info.picocli:picocli-codegen") + implementation("info.picocli:picocli") + implementation("io.micronaut.picocli:micronaut-picocli") + } + + tasks.register("shadowRun") { + def shadowJar = tasks.named("shadowJar") + inputs.file(shadowJar.flatMap { it.archiveFile }) + doLast { + def exec = services.get(ExecOperations) + exec.javaexec { + it.classpath = files(shadowJar.flatMap { it.archiveFile }.get()) + it.main = "example.Application" + } + } + } + """ + testProjectDir.newFolder("src", "main", "java", "example") + + file("src/main/java/example/Application.java") << """package example; + +import io.micronaut.configuration.picocli.PicocliRunner; +import picocli.CommandLine.Command; + +@Command(name = "demo", description = "...", mixinStandardHelpOptions = true) +public class Application implements Runnable { + + public static void main(String[] args) { + PicocliRunner.run(Application.class, args); + } + + public void run() { + System.out.println("Hello, all!"); + } +}""" + + when: + def result = build('shadowRun') + + then: + result.task(":shadowJar").outcome == TaskOutcome.SUCCESS + result.task(":shadowRun").outcome == TaskOutcome.SUCCESS + shadowJar.exists() + result.output.contains("Hello, all!") + } +} diff --git a/minimal-plugin/src/main/java/io/micronaut/gradle/MicronautMinimalApplicationPlugin.java b/minimal-plugin/src/main/java/io/micronaut/gradle/MicronautMinimalApplicationPlugin.java index 516ca9f9..517c317d 100644 --- a/minimal-plugin/src/main/java/io/micronaut/gradle/MicronautMinimalApplicationPlugin.java +++ b/minimal-plugin/src/main/java/io/micronaut/gradle/MicronautMinimalApplicationPlugin.java @@ -15,6 +15,7 @@ */ package io.micronaut.gradle; +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar; import io.micronaut.gradle.graalvm.GraalUtil; import org.apache.tools.ant.taskdefs.condition.Os; import org.gradle.api.Plugin; @@ -176,6 +177,12 @@ private void configureMicronautRuntime(Project project) { project.setProperty("mainClassName", mainClass.get()); } } + + // If shadow JAR is enabled it must be configured to merge + // all META-INF/services file into a single file otherwise this + // will break the application + project.getTasks().withType(ShadowJar.class).configureEach(ShadowJar::mergeServiceFiles); + }); }); }