diff --git a/build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootArchiveSupport.java b/build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootArchiveSupport.java index 0689e1afb4ce..12b68384e91f 100644 --- a/build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootArchiveSupport.java +++ b/build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootArchiveSupport.java @@ -113,11 +113,11 @@ private String determineSpringBootVersion() { return (version != null) ? version : "unknown"; } - CopyAction createCopyAction(Jar jar, ResolvedDependencies resolvedDependencies, boolean supportsSignatureFile) { - return createCopyAction(jar, resolvedDependencies, supportsSignatureFile, null, null); + CopyAction createCopyAction(Jar jar, ResolvedDependencies resolvedDependencies) { + return createCopyAction(jar, resolvedDependencies, null, null); } - CopyAction createCopyAction(Jar jar, ResolvedDependencies resolvedDependencies, boolean supportsSignatureFile, + CopyAction createCopyAction(Jar jar, ResolvedDependencies resolvedDependencies, @Nullable LayerResolver layerResolver, @Nullable String jarmodeToolsLocation) { File output = jar.getArchiveFile().get().getAsFile(); Manifest manifest = jar.getManifest(); @@ -132,7 +132,7 @@ CopyAction createCopyAction(Jar jar, ResolvedDependencies resolvedDependencies, String encoding = jar.getMetadataCharset(); CopyAction action = new BootZipCopyAction(output, manifest, preserveFileTimestamps, dirPermissions, filePermissions, includeDefaultLoader, jarmodeToolsLocation, requiresUnpack, exclusions, librarySpec, - compressionResolver, encoding, resolvedDependencies, supportsSignatureFile, layerResolver); + compressionResolver, encoding, resolvedDependencies, layerResolver); return action; } diff --git a/build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootJar.java b/build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootJar.java index 25ee5a2d795b..b4a2143995af 100644 --- a/build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootJar.java +++ b/build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootJar.java @@ -148,8 +148,7 @@ protected CopyAction createCopyAction() { layerResolver = new LayerResolver(this.resolvedDependencies, this.layered, this::isLibrary); } String jarmodeToolsLocation = isIncludeJarmodeTools() ? LIB_DIRECTORY : null; - return this.support.createCopyAction(this, this.resolvedDependencies, true, layerResolver, - jarmodeToolsLocation); + return this.support.createCopyAction(this, this.resolvedDependencies, layerResolver, jarmodeToolsLocation); } private boolean isIncludeJarmodeTools() { diff --git a/build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootWar.java b/build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootWar.java index 4b9c5ba4f661..46a3520ac22c 100644 --- a/build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootWar.java +++ b/build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootWar.java @@ -122,8 +122,7 @@ protected CopyAction createCopyAction() { layerResolver = new LayerResolver(this.resolvedDependencies, this.layered, this::isLibrary); } String jarmodeToolsLocation = isIncludeJarmodeTools() ? LIB_DIRECTORY : null; - return this.support.createCopyAction(this, this.resolvedDependencies, false, layerResolver, - jarmodeToolsLocation); + return this.support.createCopyAction(this, this.resolvedDependencies, layerResolver, jarmodeToolsLocation); } private boolean isIncludeJarmodeTools() { diff --git a/build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootZipCopyAction.java b/build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootZipCopyAction.java index e799d139739b..c8cd2f43b7ae 100644 --- a/build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootZipCopyAction.java +++ b/build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootZipCopyAction.java @@ -109,16 +109,13 @@ class BootZipCopyAction implements CopyAction { private final ResolvedDependencies resolvedDependencies; - private final boolean supportsSignatureFile; - private final @Nullable LayerResolver layerResolver; BootZipCopyAction(File output, Manifest manifest, boolean preserveFileTimestamps, @Nullable Integer dirMode, @Nullable Integer fileMode, boolean includeDefaultLoader, @Nullable String jarmodeToolsLocation, Spec requiresUnpack, Spec exclusions, Spec librarySpec, Function compressionResolver, @Nullable String encoding, - ResolvedDependencies resolvedDependencies, boolean supportsSignatureFile, - @Nullable LayerResolver layerResolver) { + ResolvedDependencies resolvedDependencies, @Nullable LayerResolver layerResolver) { this.output = output; this.manifest = manifest; this.preserveFileTimestamps = preserveFileTimestamps; @@ -132,7 +129,6 @@ class BootZipCopyAction implements CopyAction { this.compressionResolver = compressionResolver; this.encoding = encoding; this.resolvedDependencies = resolvedDependencies; - this.supportsSignatureFile = supportsSignatureFile; this.layerResolver = layerResolver; } @@ -341,7 +337,7 @@ private void writeJarModeLibrary(String location, JarModeLibrary library) throws } private void writeSignatureFileIfNecessary() throws IOException { - if (BootZipCopyAction.this.supportsSignatureFile && hasSignedLibrary()) { + if (hasSignedLibrary()) { writeEntry("META-INF/BOOT.SF", (out) -> { }, false); } diff --git a/build-plugin/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/AbstractBootArchiveIntegrationTests.java b/build-plugin/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/AbstractBootArchiveIntegrationTests.java index 5d3de661347d..07a878742315 100644 --- a/build-plugin/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/AbstractBootArchiveIntegrationTests.java +++ b/build-plugin/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/AbstractBootArchiveIntegrationTests.java @@ -641,6 +641,17 @@ void dirModeAndFileModeAreApplied() throws IOException { } } + @TestTemplate + void signed() throws IOException { + BuildTask task = this.gradleBuild.build(this.taskName).task(":" + this.taskName); + assertThat(task).isNotNull(); + assertThat(task.getOutcome()).isEqualTo(TaskOutcome.SUCCESS); + File jar = new File(this.gradleBuild.getProjectDir(), "build/libs").listFiles()[0]; + try (JarFile jarFile = new JarFile(jar)) { + assertThat(jarFile.getEntry("META-INF/BOOT.SF")).isNotNull(); + } + } + private void copyMainClassApplication() throws IOException { copyApplication("main"); } diff --git a/build-plugin/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests.java b/build-plugin/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests.java index b77880082301..bc2045ca6eb7 100644 --- a/build-plugin/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests.java +++ b/build-plugin/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests.java @@ -16,16 +16,12 @@ package org.springframework.boot.gradle.tasks.bundling; -import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.Set; import java.util.TreeSet; -import java.util.jar.JarFile; import org.gradle.testkit.runner.BuildResult; -import org.gradle.testkit.runner.BuildTask; -import org.gradle.testkit.runner.TaskOutcome; import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.TestTemplate; @@ -47,17 +43,6 @@ class BootJarIntegrationTests extends AbstractBootArchiveIntegrationTests { super("bootJar", "BOOT-INF/lib/", "BOOT-INF/classes/", "BOOT-INF/"); } - @TestTemplate - void signed() throws Exception { - BuildTask task = this.gradleBuild.build("bootJar").task(":bootJar"); - assertThat(task).isNotNull(); - assertThat(task.getOutcome()).isEqualTo(TaskOutcome.SUCCESS); - File jar = new File(this.gradleBuild.getProjectDir(), "build/libs").listFiles()[0]; - try (JarFile jarFile = new JarFile(jar)) { - assertThat(jarFile.getEntry("META-INF/BOOT.SF")).isNotNull(); - } - } - @TestTemplate void whenAResolvableCopyOfAnUnresolvableConfigurationIsResolvedThenResolutionSucceeds() { Assumptions.assumeTrue(this.gradleBuild.gradleVersionIsLessThan("9.0-milestone-1")); diff --git a/build-plugin/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/bundling/BootWarIntegrationTests-signed.gradle b/build-plugin/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/bundling/BootWarIntegrationTests-signed.gradle new file mode 100644 index 000000000000..c1c9216e0d50 --- /dev/null +++ b/build-plugin/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/bundling/BootWarIntegrationTests-signed.gradle @@ -0,0 +1,36 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + id 'war' + id 'java' + id 'org.springframework.boot' version '{version}' +} + +bootWar { + mainClass = 'com.example.Application' +} + +repositories { + mavenCentral() + maven { + url = 'repository' + } +} + +dependencies { + implementation("org.bouncycastle:bcprov-jdk18on:1.78.1") +} diff --git a/build-plugin/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/WarIntegrationTests.java b/build-plugin/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/WarIntegrationTests.java index 2e7dc0930fd9..502e84041ce7 100644 --- a/build-plugin/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/WarIntegrationTests.java +++ b/build-plugin/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/WarIntegrationTests.java @@ -250,4 +250,12 @@ void whenEntryIsExcludedItShouldNotBePresentInTheRepackagedWar(MavenBuild mavenB }); } + @TestTemplate + void whenSigned(MavenBuild mavenBuild) { + mavenBuild.project("war-signed").execute((project) -> { + File repackaged = new File(project, "target/war-signed-0.0.1.BUILD-SNAPSHOT.war"); + assertThat(jar(repackaged)).hasEntryWithName("META-INF/BOOT.SF"); + }); + } + } diff --git a/build-plugin/spring-boot-maven-plugin/src/intTest/projects/war-signed/pom.xml b/build-plugin/spring-boot-maven-plugin/src/intTest/projects/war-signed/pom.xml new file mode 100644 index 000000000000..18114a26d1c5 --- /dev/null +++ b/build-plugin/spring-boot-maven-plugin/src/intTest/projects/war-signed/pom.xml @@ -0,0 +1,62 @@ + + + 4.0.0 + org.springframework.boot.maven.it + war-signed + 0.0.1.BUILD-SNAPSHOT + + UTF-8 + @java.version@ + @java.version@ + + + + + @project.groupId@ + @project.artifactId@ + @project.version@ + + + + repackage + + + + + + org.apache.maven.plugins + maven-war-plugin + @maven-war-plugin.version@ + + + + some.random.Main + + + Foo + + + + + + + + + org.springframework + spring-context + @spring-framework.version@ + + + jakarta.servlet + jakarta.servlet-api + @jakarta-servlet.version@ + provided + + + org.bouncycastle + bcprov-jdk18on + 1.78.1 + + + diff --git a/build-plugin/spring-boot-maven-plugin/src/intTest/projects/war-signed/src/main/java/org/test/SampleApplication.java b/build-plugin/spring-boot-maven-plugin/src/intTest/projects/war-signed/src/main/java/org/test/SampleApplication.java new file mode 100644 index 000000000000..547d0cf01711 --- /dev/null +++ b/build-plugin/spring-boot-maven-plugin/src/intTest/projects/war-signed/src/main/java/org/test/SampleApplication.java @@ -0,0 +1,24 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.test; + +public class SampleApplication { + + public static void main(String[] args) { + } + +} diff --git a/buildpack/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/docker/configuration/with-default-context/contexts/meta/ea1b2003cc8155cb8af43960c89a4c1e28777d6fd848ff3422cf375329c2626d/meta.json b/buildpack/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/docker/configuration/with-default-context/contexts/meta/ea1b2003cc8155cb8af43960c89a4c1e28777d6fd848ff3422cf375329c2626d/meta.json deleted file mode 100644 index f072aa2647e2..000000000000 --- a/buildpack/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/docker/configuration/with-default-context/contexts/meta/ea1b2003cc8155cb8af43960c89a4c1e28777d6fd848ff3422cf375329c2626d/meta.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "Name": "test-context", - "Metadata": { - "Description": "A context for testing" - }, - "Endpoints": { - "docker": { - "Host": "unix:///home/user/.docker/docker.sock", - "SkipTLSVerify": false - } - } -} diff --git a/buildpack/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/docker/configuration/with-default-context/contexts/tls/ea1b2003cc8155cb8af43960c89a4c1e28777d6fd848ff3422cf375329c2626d/docker/cert.pem b/buildpack/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/docker/configuration/with-default-context/contexts/tls/ea1b2003cc8155cb8af43960c89a4c1e28777d6fd848ff3422cf375329c2626d/docker/cert.pem deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/buildpack/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/docker/configuration/with-default-context/contexts/tls/ea1b2003cc8155cb8af43960c89a4c1e28777d6fd848ff3422cf375329c2626d/docker/key.pem b/buildpack/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/docker/configuration/with-default-context/contexts/tls/ea1b2003cc8155cb8af43960c89a4c1e28777d6fd848ff3422cf375329c2626d/docker/key.pem deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Repackager.java b/loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Repackager.java index 1f3f6d312588..fb6525cf0aba 100644 --- a/loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Repackager.java +++ b/loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Repackager.java @@ -53,7 +53,8 @@ public Repackager(File source) { @Override protected void writeSignatureFileIfNecessary(Map writtenLibraries, AbstractJarWriter writer) throws IOException { - if (getSource().getName().toLowerCase(Locale.ROOT).endsWith(".jar") && hasSignedLibrary(writtenLibraries)) { + String sourceName = getSource().getName().toLowerCase(Locale.ROOT); + if ((sourceName.endsWith(".jar") || sourceName.endsWith(".war")) && hasSignedLibrary(writtenLibraries)) { writer.writeEntry("META-INF/BOOT.SF", (entryWriter) -> { }); }