From 0b2e1849c8f6822c9ff27f9b7bcc6409f7c2ffd9 Mon Sep 17 00:00:00 2001 From: Helder Pereira Date: Tue, 25 May 2021 21:27:18 +0100 Subject: [PATCH 1/2] Make Spock tests run again --- build.gradle | 4 +- gradle/dependencies.gradle | 4 +- .../plugins/shadow/ApplicationSpec.groovy | 11 +- .../plugins/shadow/PublishingSpec.groovy | 141 +----------------- .../plugins/shadow/RelocationSpec.groovy | 4 +- .../plugins/shadow/ShadowPluginSpec.groovy | 54 ++----- .../caching/RelocationCachingSpec.groovy | 4 +- .../caching/ShadowJarCachingSpec.groovy | 2 +- .../shadow/util/PluginSpecification.groovy | 8 +- .../plugins/shadow/util/file/TestFile.java | 1 + 10 files changed, 29 insertions(+), 204 deletions(-) diff --git a/build.gradle b/build.gradle index 19feb7076..6d1c618b2 100644 --- a/build.gradle +++ b/build.gradle @@ -62,12 +62,14 @@ repositories { } test { + useJUnitPlatform() + if (System.env.CI == 'true') { testLogging.showStandardStreams = true minHeapSize "1g" maxHeapSize "1g" } - + systemProperty 'java.io.tmpdir', buildDir.absolutePath } diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 98e132f77..afc878b1e 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -16,10 +16,10 @@ dependencies { exclude group: 'org.ow2.asm' } - testImplementation("org.spockframework:spock-core:2.0-M4-groovy-3.0") { + testImplementation('org.spockframework:spock-core:2.0-groovy-3.0') { exclude group: 'org.codehaus.groovy' } - testImplementation "org.spockframework:spock-junit4:2.0-M4-groovy-3.0" + testImplementation 'org.spockframework:spock-junit4:2.0-groovy-3.0' testImplementation 'xmlunit:xmlunit:1.6' testImplementation 'org.apache.commons:commons-lang3:3.12.0' testImplementation 'com.google.guava:guava:30.1.1-jre' diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/ApplicationSpec.groovy b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/ApplicationSpec.groovy index c71282278..323e1d734 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/ApplicationSpec.groovy +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/ApplicationSpec.groovy @@ -1,6 +1,5 @@ package com.github.jengelman.gradle.plugins.shadow -import com.github.jengelman.gradle.plugins.shadow.util.AppendableMavenFileRepository import com.github.jengelman.gradle.plugins.shadow.util.PluginSpecification import org.apache.tools.zip.ZipFile import org.gradle.testkit.runner.BuildResult @@ -11,14 +10,6 @@ import java.util.jar.JarFile class ApplicationSpec extends PluginSpecification { - AppendableMavenFileRepository repo - AppendableMavenFileRepository publishingRepo - - def setup() { - repo = repo() - publishingRepo = repo('remote_repo') - } - def 'integration with application plugin'() { given: repo.module('shadow', 'a', '1.0') @@ -124,7 +115,7 @@ class ApplicationSpec extends PluginSpecification { ZipFile zipFile = new ZipFile(zip) println zipFile.entries.collect { it.name } assert zipFile.entries.find { it.name == 'myapp-shadow-1.0/lib/myapp-1.0-all.jar' } - assert zipFile.entries.find { it.name == 'myapp-shadow-1.0/lib/a-1.0.jar'} + assert zipFile.entries.find { it.name == 'myapp-shadow-1.0/lib/a-1.0.jar' } cleanup: zipFile?.close() diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/PublishingSpec.groovy b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/PublishingSpec.groovy index 01f8476fc..7ea155900 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/PublishingSpec.groovy +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/PublishingSpec.groovy @@ -3,157 +3,18 @@ package com.github.jengelman.gradle.plugins.shadow import com.github.jengelman.gradle.plugins.shadow.util.AppendableMavenFileRepository import com.github.jengelman.gradle.plugins.shadow.util.PluginSpecification import groovy.json.JsonSlurper +import groovy.xml.XmlSlurper import org.gradle.api.attributes.Bundling import org.gradle.api.attributes.Usage -import spock.lang.Issue class PublishingSpec extends PluginSpecification { - AppendableMavenFileRepository repo AppendableMavenFileRepository publishingRepo def setup() { - repo = repo() publishingRepo = repo('remote_repo') } - def "publish shadow jar with maven plugin"() { - given: - repo.module('shadow', 'a', '1.0') - .insertFile('a.properties', 'a') - .insertFile('a2.properties', 'a2') - .publish() - repo.module('shadow', 'b', '1.0') - .insertFile('b.properties', 'b') - .publish() - - settingsFile << "rootProject.name = 'maven'" - buildFile << """ - apply plugin: 'maven' - - dependencies { - implementation 'shadow:a:1.0' - shadow 'shadow:b:1.0' - } - - shadowJar { - archiveBaseName = 'maven-all' - archiveClassifier = null - archiveClassifier.convention(null) - } - - uploadShadow { - repositories { - mavenDeployer { - repository(url: "${publishingRepo.uri}") - } - } - } - """.stripIndent() - - when: - runWithDeprecationWarnings('uploadShadow') - - then: 'Check that shadow artifact exists' - File publishedFile = publishingRepo.rootDir.file('shadow/maven-all/1.0/maven-all-1.0.jar').canonicalFile - assert publishedFile.exists() - - and: 'Check contents of shadow artifact' - contains(publishedFile, ['a.properties', 'a2.properties']) - - and: 'Check that shadow artifact pom exists and contents' - File pom = publishingRepo.rootDir.file('shadow/maven-all/1.0/maven-all-1.0.pom').canonicalFile - assert pom.exists() - - def contents = new XmlSlurper().parse(pom) - assert contents.dependencies.size() == 1 - assert contents.dependencies[0].dependency.size() == 1 - - def dependency = contents.dependencies[0].dependency[0] - assert dependency.groupId.text() == 'shadow' - assert dependency.artifactId.text() == 'b' - assert dependency.version.text() == '1.0' - } - - def "exclude api and implementation dependencies when publishing shadow jar with maven plugin"() { - given: - repo.module('shadow', 'a', '1.0') - .insertFile('a.properties', 'a') - .insertFile('a2.properties', 'a2') - .publish() - repo.module('shadow', 'b', '1.0') - .insertFile('b.properties', 'b') - .publish() - - settingsFile << "rootProject.name = 'maven'" - buildFile << """ - apply plugin: 'java-library' - apply plugin: 'maven' - - dependencies { - api 'shadow:a:1.0' - implementation 'shadow:b:1.0' - } - - uploadShadow { - repositories { - mavenDeployer { - repository(url: "${publishingRepo.uri}") - } - } - } - """.stripIndent() - - when: - runWithDeprecationWarnings('uploadShadow') - - then: 'Check that shadow artifact exists' - File publishedFile = publishingRepo.rootDir.file('shadow/maven/1.0/maven-1.0-all.jar').canonicalFile - assert publishedFile.exists() - - and: 'Check contents of shadow artifact' - contains(publishedFile, ['a.properties', 'a2.properties']) - - and: 'Check that shadow artifact pom exists and contents' - File pom = publishingRepo.rootDir.file('shadow/maven/1.0/maven-1.0.pom').canonicalFile - assert pom.exists() - - def contents = new XmlSlurper().parse(pom) - assert contents.dependencies.size() == 0 - } - - @Issue('SHADOW-347') - def "maven install with application plugin"() { - given: - repo.module('shadow', 'a', '1.0') - .insertFile('a.properties', 'a') - .insertFile('a2.properties', 'a2') - .publish() - repo.module('shadow', 'b', '1.0') - .insertFile('b.properties', 'b') - .publish() - - settingsFile << "rootProject.name = 'maven'" - buildFile << """ - apply plugin: 'maven' - apply plugin: 'application' - - mainClassName = 'my.App' - - dependencies { - implementation 'shadow:a:1.0' - shadow 'shadow:b:1.0' - } - """.stripIndent() - - when: - // The Maven plugin is deprecated - runWithDeprecationWarnings('install') - - then: - noExceptionThrown() - } - def "publish shadow jar with maven-publish plugin"() { given: repo.module('shadow', 'a', '1.0') diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/RelocationSpec.groovy b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/RelocationSpec.groovy index 1bc838902..1ac3439d7 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/RelocationSpec.groovy +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/RelocationSpec.groovy @@ -184,10 +184,10 @@ class RelocationSpec extends PluginSpecification { def "relocate does not drop dependency resources"() { given: 'Core project with dependency and resource' file('core/build.gradle') << """ - apply plugin: 'java' + apply plugin: 'java-library' repositories { maven { url "${repo.uri}" } } - dependencies { implementation 'junit:junit:3.8.2' } + dependencies { api 'junit:junit:3.8.2' } """.stripIndent() file('core/src/main/resources/TEST') << 'TEST RESOURCE' diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowPluginSpec.groovy b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowPluginSpec.groovy index deee7b42f..65e150537 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowPluginSpec.groovy +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowPluginSpec.groovy @@ -86,13 +86,13 @@ class ShadowPluginSpec extends PluginSpecification { assert output.exists() where: - version << ['6.0', '6.1', '6.2'] + version << ['7.0'] } - def 'Error in Gradle versions < 6.0'() { + def 'Error in Gradle versions < 7.0'() { given: GradleRunner versionRunner = GradleRunner.create() - .withGradleVersion('5.5') + .withGradleVersion('6.9') .withArguments('--stacktrace') .withProjectDir(dir.root) .forwardOutput() @@ -796,7 +796,7 @@ class ShadowPluginSpec extends PluginSpecification { buildFile << """ dependencies { - runtime 'shadow:a:1.0' + runtimeOnly 'shadow:a:1.0' shadow 'shadow:b:1.0' } """.stripIndent() @@ -830,25 +830,15 @@ class ShadowPluginSpec extends PluginSpecification { .dependsOn('implementation-dep') .publish() - repo.module('shadow', 'compile', '1.0') - .insertFile('compile.properties', 'compile') - .publish() - - repo.module('shadow', 'runtime', '1.0') - .insertFile('runtime.properties', 'runtime') - .publish() - repo.module('shadow', 'runtimeOnly', '1.0') .insertFile('runtimeOnly.properties', 'runtimeOnly') .publish() - buildFile.text = defaultBuildScript.replace('java', 'java-library') + buildFile.text = getDefaultBuildScript('java-library') buildFile << """ dependencies { api 'shadow:api:1.0' implementation 'shadow:implementation:1.0' - compile 'shadow:compile:1.0' - runtime 'shadow:runtime:1.0' runtimeOnly 'shadow:runtimeOnly:1.0' } """.stripIndent() @@ -857,8 +847,8 @@ class ShadowPluginSpec extends PluginSpecification { versionRunner.withArguments('shadowJar').build() then: - contains(output, ['api.properties', 'implementation.properties', 'compile.properties', - 'runtime.properties', 'runtimeOnly.properties', 'implementation-dep.properties']) + contains(output, ['api.properties', 'implementation.properties', + 'runtimeOnly.properties', 'implementation-dep.properties']) } def "doesn't include compileOnly configuration by default"() { @@ -873,7 +863,7 @@ class ShadowPluginSpec extends PluginSpecification { buildFile << """ dependencies { - runtime 'shadow:a:1.0' + runtimeOnly 'shadow:a:1.0' compileOnly 'shadow:b:1.0' } """.stripIndent() @@ -900,8 +890,8 @@ class ShadowPluginSpec extends PluginSpecification { buildFile << """ dependencies { - runtime 'shadow:a:1.0' - runtime 'shadow:b:1.0' + runtimeOnly 'shadow:a:1.0' + runtimeOnly 'shadow:b:1.0' } """.stripIndent() @@ -917,7 +907,7 @@ class ShadowPluginSpec extends PluginSpecification { given: buildFile << """ - dependencies { compile 'junit:junit:3.8.2' } + dependencies { implementation 'junit:junit:3.8.2' } """.stripIndent() when: @@ -988,26 +978,6 @@ class ShadowPluginSpec extends PluginSpecification { } - @Issue('SHADOW-256') - def "allow configuration of non-maven projects with uploads"() { - given: - buildFile << """ - configurations.each { configuration -> - def upload = project.getTasks().getByName(configuration.getUploadTaskName()) - upload.repositories.ivy { - layout 'ivy' - url "\$buildDir/repo" - } - } - """ - - when: - run('shadowJar') - - then: - assert output.exists() - } - @Issue('SHADOW-203') def "support ZipCompression.STORED"() { given: @@ -1103,7 +1073,7 @@ class ShadowPluginSpec extends PluginSpecification { mainClassName = 'myapp.Main' dependencies { - compile 'shadow:a:1.0' + implementation 'shadow:a:1.0' } def generatedResourcesDir = new File(project.buildDir, "generated-resources") diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/caching/RelocationCachingSpec.groovy b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/caching/RelocationCachingSpec.groovy index 25243bf52..40f3fdd7c 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/caching/RelocationCachingSpec.groovy +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/caching/RelocationCachingSpec.groovy @@ -7,7 +7,7 @@ class RelocationCachingSpec extends AbstractCachingSpec { def 'shadowJar is cached correctly when relocation is added'() { given: buildFile << """ - dependencies { compile 'junit:junit:3.8.2' } + dependencies { implementation 'junit:junit:3.8.2' } """.stripIndent() file('src/main/java/server/Server.java') << """ @@ -30,7 +30,7 @@ class RelocationCachingSpec extends AbstractCachingSpec { when: changeConfigurationTo """ - dependencies { compile 'junit:junit:3.8.2' } + dependencies { implementation 'junit:junit:3.8.2' } shadowJar { relocate 'junit.framework', 'foo.junit.framework' diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/caching/ShadowJarCachingSpec.groovy b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/caching/ShadowJarCachingSpec.groovy index e9d098c62..1395f5c21 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/caching/ShadowJarCachingSpec.groovy +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/caching/ShadowJarCachingSpec.groovy @@ -184,7 +184,7 @@ class ShadowJarCachingSpec extends AbstractCachingSpec { when: changeConfigurationTo """ - dependencies { compile 'junit:junit:3.8.2' } + dependencies { implementation 'junit:junit:3.8.2' } shadowJar { dependencies { diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/PluginSpecification.groovy b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/PluginSpecification.groovy index 5cf84fddf..81ec812b0 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/PluginSpecification.groovy +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/PluginSpecification.groovy @@ -35,11 +35,11 @@ class PluginSpecification extends Specification { println buildFile.text } - String getDefaultBuildScript() { + String getDefaultBuildScript(String javaPlugin = 'java') { return """ plugins { - id 'java' - id 'com.github.johnrengelman.shadow' + id '${javaPlugin}' + id 'com.github.johnrengelman.shadow' version '${SHADOW_VERSION}' } version = "1.0" @@ -91,7 +91,7 @@ class PluginSpecification extends Specification { } } - private static boolean containsDeprecationWarning(String output) { + static boolean containsDeprecationWarning(String output) { output.contains("has been deprecated and is scheduled to be removed in Gradle") || output.contains("has been deprecated. This is scheduled to be removed in Gradle") } diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/file/TestFile.java b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/file/TestFile.java index 32450ce8a..b6d395d90 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/file/TestFile.java +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/util/file/TestFile.java @@ -36,6 +36,7 @@ import java.util.jar.JarFile; import java.util.jar.Manifest; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.*; public class TestFile extends File { From 448aced5f6f19c119349d92ac38182e61003faf3 Mon Sep 17 00:00:00 2001 From: Roberto Perez Alcolea Date: Tue, 13 Jul 2021 18:31:16 -0700 Subject: [PATCH 2/2] ShadowApplicationPlugin: configure JavaJarExec to use javaLauncher in order to leverage Toolchains. Fixes #690 --- .../shadow/ShadowApplicationPlugin.groovy | 12 ++++ .../plugins/shadow/ApplicationSpec.groovy | 71 +++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowApplicationPlugin.groovy b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowApplicationPlugin.groovy index f7b5f57f4..5c020acc0 100644 --- a/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowApplicationPlugin.groovy +++ b/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowApplicationPlugin.groovy @@ -11,9 +11,13 @@ import org.gradle.api.file.CopySpec import org.gradle.api.plugins.ApplicationPlugin import org.gradle.api.plugins.ApplicationPluginConvention import org.gradle.api.plugins.JavaApplication +import org.gradle.api.plugins.JavaPluginExtension +import org.gradle.api.provider.Provider import org.gradle.api.tasks.Sync import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.application.CreateStartScripts +import org.gradle.jvm.toolchain.JavaLauncher +import org.gradle.jvm.toolchain.JavaToolchainService class ShadowApplicationPlugin implements Plugin { @@ -87,9 +91,17 @@ class ShadowApplicationPlugin implements Plugin { run.conventionMapping.jarFile = { project.file("${install.get().destinationDir.path}/lib/${jar.get().archivePath.name}") } + configureJavaLauncher(run) } } + private void configureJavaLauncher(JavaJarExec run) { + def toolchain = project.getExtensions().getByType(JavaPluginExtension.class).toolchain + JavaToolchainService service = project.getExtensions().getByType(JavaToolchainService.class) + Provider defaultLauncher = service.launcherFor(toolchain) + run.getJavaLauncher().set(defaultLauncher) + } + protected void addCreateScriptsTask(Project project) { ApplicationPluginConvention pluginConvention = (ApplicationPluginConvention) project.convention.plugins.application diff --git a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/ApplicationSpec.groovy b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/ApplicationSpec.groovy index 323e1d734..4ec08237a 100644 --- a/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/ApplicationSpec.groovy +++ b/src/test/groovy/com/github/jengelman/gradle/plugins/shadow/ApplicationSpec.groovy @@ -71,6 +71,77 @@ class ApplicationSpec extends PluginSpecification { jar?.close() } + def 'integration with application plugin and java toolchains'() { + given: + repo.module('shadow', 'a', '1.0') + .insertFile('a.properties', 'a') + .insertFile('a2.properties', 'a2') + .publish() + + file('src/main/java/myapp/Main.java') << """ + package myapp; + public class Main { + public static void main(String[] args) { + System.out.println("TestApp: Hello World! (" + args[0] + ")"); + } + } + """.stripIndent() + + buildFile << """ + apply plugin: 'application' + + mainClassName = 'myapp.Main' + + dependencies { + implementation 'shadow:a:1.0' + } + + java { + toolchain { + languageVersion = JavaLanguageVersion.of(16) + } + } + + runShadow { + args 'foo' + doFirst { + project.logger.lifecycle("Running application with JDK \${it.javaLauncher.get().metadata.languageVersion.asInt()}") + } + } + """.stripIndent() + + settingsFile << "rootProject.name = 'myapp'" + + when: + BuildResult result = run('runShadow', '--stacktrace') + + then: 'tests that runShadow executed and exited' + assert result.output.contains('Running application with JDK 16') + assert result.output.contains('TestApp: Hello World! (foo)') + + and: 'Check that the proper jar file was installed' + File installedJar = getFile('build/install/myapp-shadow/lib/myapp-1.0-all.jar') + assert installedJar.exists() + + and: 'And that jar file as the correct files in it' + contains(installedJar, ['a.properties', 'a2.properties', 'myapp/Main.class']) + + and: 'Check the manifest attributes in the jar file are correct' + JarFile jar = new JarFile(installedJar) + Attributes attributes = jar.manifest.mainAttributes + assert attributes.getValue('Main-Class') == 'myapp.Main' + + then: 'Check that the start scripts is written out and has the correct Java invocation' + File startScript = getFile('build/install/myapp-shadow/bin/myapp') + assert startScript.exists() + assert startScript.text.contains("CLASSPATH=\$APP_HOME/lib/myapp-1.0-all.jar") + assert startScript.text.contains("-jar \"\\\"\$CLASSPATH\\\"\" \"\$APP_ARGS\"") + assert startScript.text.contains("exec \"\$JAVACMD\" \"\$@\"") + + cleanup: + jar?.close() + } + @Issue('SHADOW-89') def 'shadow application distributions should use shadow jar'() { given: