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 502e84041ce..b57aaf5a58c 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 @@ -67,6 +67,16 @@ class WarIntegrationTests extends AbstractArchiveIntegrationTests { .hasAttribute("Not-Used", "Foo"))); } + @TestTemplate + void sbomManifestAttributesAreAddedToRepackagedWar(MavenBuild mavenBuild) { + mavenBuild.project("war-sbom").execute((project) -> { + File repackaged = new File(project, "target/war-sbom-0.0.1.BUILD-SNAPSHOT.war"); + assertThat(jar(repackaged)).hasEntryWithName("WEB-INF/classes/META-INF/sbom/application.cdx.json") + .manifest((manifest) -> manifest.hasAttribute("Sbom-Format", "CycloneDX") + .hasAttribute("Sbom-Location", "WEB-INF/classes/META-INF/sbom/application.cdx.json")); + }); + } + @TestTemplate void jarDependencyWithCustomFinalNameBuiltInSameReactorIsPackagedUsingArtifactIdAndVersion(MavenBuild mavenBuild) { mavenBuild.project("war-reactor") diff --git a/build-plugin/spring-boot-maven-plugin/src/intTest/projects/war-sbom/pom.xml b/build-plugin/spring-boot-maven-plugin/src/intTest/projects/war-sbom/pom.xml new file mode 100644 index 00000000000..745d5330321 --- /dev/null +++ b/build-plugin/spring-boot-maven-plugin/src/intTest/projects/war-sbom/pom.xml @@ -0,0 +1,48 @@ + + + 4.0.0 + org.springframework.boot.maven.it + war-sbom + 0.0.1.BUILD-SNAPSHOT + war + + UTF-8 + @java.version@ + @java.version@ + + + + + @project.groupId@ + @project.artifactId@ + @project.version@ + + + + repackage + + + + + + org.apache.maven.plugins + maven-war-plugin + @maven-war-plugin.version@ + + + + + + org.springframework + spring-context + @spring-framework.version@ + + + jakarta.servlet + jakarta.servlet-api + @jakarta-servlet.version@ + provided + + + diff --git a/build-plugin/spring-boot-maven-plugin/src/intTest/projects/war-sbom/src/main/java/org/test/SampleApplication.java b/build-plugin/spring-boot-maven-plugin/src/intTest/projects/war-sbom/src/main/java/org/test/SampleApplication.java new file mode 100644 index 00000000000..547d0cf0171 --- /dev/null +++ b/build-plugin/spring-boot-maven-plugin/src/intTest/projects/war-sbom/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/build-plugin/spring-boot-maven-plugin/src/intTest/projects/war-sbom/src/main/resources/META-INF/sbom/application.cdx.json b/build-plugin/spring-boot-maven-plugin/src/intTest/projects/war-sbom/src/main/resources/META-INF/sbom/application.cdx.json new file mode 100644 index 00000000000..0967ef424bc --- /dev/null +++ b/build-plugin/spring-boot-maven-plugin/src/intTest/projects/war-sbom/src/main/resources/META-INF/sbom/application.cdx.json @@ -0,0 +1 @@ +{} diff --git a/loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Packager.java b/loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Packager.java index 50754fa09c9..2e88ca53186 100644 --- a/loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Packager.java +++ b/loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Packager.java @@ -55,6 +55,7 @@ import org.springframework.util.StringUtils; * @author Stephane Nicoll * @author Madhura Bhave * @author Scott Frederick + * @author Cobi Eun * @since 2.3.0 */ public abstract class Packager { @@ -422,7 +423,8 @@ public abstract class Packager { } private boolean isCycloneDxBom(JarEntry entry) { - if (!entry.getName().startsWith("META-INF/sbom/")) { + if (!entry.getName().startsWith("META-INF/sbom/") + && !entry.getName().startsWith(getLayout().getClassesLocation() + "META-INF/sbom/")) { return false; } return entry.getName().endsWith(".cdx.json") || entry.getName().endsWith("/bom.json"); diff --git a/loader/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/AbstractPackagerTests.java b/loader/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/AbstractPackagerTests.java index 02a02d1befa..0af59e83c54 100644 --- a/loader/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/AbstractPackagerTests.java +++ b/loader/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/AbstractPackagerTests.java @@ -687,16 +687,26 @@ abstract class AbstractPackagerTests

{ } @Test - void sbomManifestEntriesAreWritten() throws IOException { - this.testJarFile.addClass("com/example/Application.class", ClassWithMainMethod.class); - this.testJarFile.addFile("META-INF/sbom/application.cdx.json", new ByteArrayInputStream(new byte[0])); + void sbomManifestEntriesAreWrittenForJar() throws IOException { + sbomManifestEntriesAreWritten(new Layouts.Jar(), ""); + } + + @Test + void sbomManifestEntriesAreWrittenForWar() throws IOException { + sbomManifestEntriesAreWritten(new Layouts.War(), "WEB-INF/classes/"); + } + + private void sbomManifestEntriesAreWritten(Layout layout, String prefix) throws IOException { + this.testJarFile.addClass(prefix + "com/example/Application.class", ClassWithMainMethod.class); + this.testJarFile.addFile(prefix + "META-INF/sbom/application.cdx.json", new ByteArrayInputStream(new byte[0])); P packager = createPackager(this.testJarFile.getFile()); + packager.setLayout(layout); execute(packager, NO_LIBRARIES); Manifest manifest = getPackagedManifest(); assertThat(manifest).isNotNull(); assertThat(manifest.getMainAttributes().getValue("Sbom-Format")).isEqualTo("CycloneDX"); assertThat(manifest.getMainAttributes().getValue("Sbom-Location")) - .isEqualTo("META-INF/sbom/application.cdx.json"); + .isEqualTo(prefix + "META-INF/sbom/application.cdx.json"); } private File createLibraryJar() throws IOException {