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 9597ab3cc745..62c596ce63f2 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 @@ -115,11 +115,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(); @@ -135,7 +135,7 @@ CopyAction createCopyAction(Jar jar, ResolvedDependencies resolvedDependencies, String encoding = jar.getMetadataCharset(); CopyAction action = new BootZipCopyAction(output, manifest, preserveFileTimestamps, dirPermissions, filePermissions, includeDefaultLoader, jarmodeToolsLocation, requiresUnpack, exclusions, launchScript, - librarySpec, compressionResolver, encoding, resolvedDependencies, supportsSignatureFile, layerResolver); + librarySpec, 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 5e3ad8f23625..19d72ff68b27 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 970f25335f88..737ba77d3208 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 c4735b578c00..6daf6a0897c4 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 @@ -112,8 +112,6 @@ 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, @@ -121,8 +119,7 @@ class BootZipCopyAction implements CopyAction { Spec requiresUnpack, Spec exclusions, @Nullable LaunchScriptConfiguration launchScript, 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; @@ -137,7 +134,6 @@ class BootZipCopyAction implements CopyAction { this.compressionResolver = compressionResolver; this.encoding = encoding; this.resolvedDependencies = resolvedDependencies; - this.supportsSignatureFile = supportsSignatureFile; this.layerResolver = layerResolver; } @@ -362,7 +358,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 e720ed7111bd..1c326fda9d31 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 @@ -632,6 +632,15 @@ void dirModeAndFileModeAreApplied() throws IOException { } } + @TestTemplate + void signed() throws IOException { + assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName).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 8ed557deb865..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,15 +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.TaskOutcome; import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.TestTemplate; @@ -46,15 +43,6 @@ class BootJarIntegrationTests extends AbstractBootArchiveIntegrationTests { super("bootJar", "BOOT-INF/lib/", "BOOT-INF/classes/", "BOOT-INF/"); } - @TestTemplate - void signed() throws Exception { - assertThat(this.gradleBuild.build("bootJar").task(":bootJar").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 950bcbb70898..109b36d21d12 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 @@ -240,4 +240,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/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 2d0533f5cad3..403e170f1a6e 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) -> { }); }