Closed fmunch closed 2 hours ago
Thanks for the minimal reproducer.
The problem's due to the structure of your project and the effect that has on the class loaders that Gradle creates. With Spring Boot's plugin being a dependency of buildSrc
and the CycloneDX plugin being a plugin dependency of a project, they're loaded by different class loaders. This means that the Spring Boot plugin cannot load the CycloneDX plugin's classes which prevents it from being able to react to the plugin being applied. Unfortunately, there's nothing that Spring Boot can do about this as it's Gradle that controls the class loaders and their hierarchy.
You can fix the problem by adding a dependency on the CycloneDX plugin to buildSrc
. The plugin still has to be applied in the server
project but you can remove the version and Gradle will automatically use the version from buildSrc
:
diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle
index 652faac..d5fd2b8 100644
--- a/buildSrc/build.gradle
+++ b/buildSrc/build.gradle
@@ -5,6 +5,7 @@ plugins {
repositories {
mavenCentral()
+ gradlePluginPortal()
}
dependencies {
@@ -14,4 +15,5 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-gradle-plugin:3.3.4'
implementation 'io.spring.gradle:dependency-management-plugin:1.1.6'
+ implementation 'org.cyclonedx:cyclonedx-gradle-plugin:1.10.0'
}
diff --git a/server/build.gradle b/server/build.gradle
index 3990375..486d825 100644
--- a/server/build.gradle
+++ b/server/build.gradle
@@ -1,6 +1,6 @@
plugins {
id 'custom.spring'
- id 'org.cyclonedx.bom' version '1.10.0'
+ id 'org.cyclonedx.bom'
}
With these changes in place, the cyclonedxBom
task will be run when executing bootJar
:
$ ./gradlew bootJar --console=plain
> Task :buildSrc:extractPluginRequests UP-TO-DATE
> Task :buildSrc:generatePluginAdapters UP-TO-DATE
> Task :buildSrc:compileJava UP-TO-DATE
> Task :buildSrc:compileGroovy NO-SOURCE
> Task :buildSrc:compileGroovyPlugins UP-TO-DATE
> Task :buildSrc:pluginDescriptors UP-TO-DATE
> Task :buildSrc:processResources UP-TO-DATE
> Task :buildSrc:classes UP-TO-DATE
> Task :buildSrc:jar UP-TO-DATE
> Task :server:compileJava
> Task :server:cyclonedxBom
> Task :server:processResources
> Task :server:classes
> Task :server:resolveMainClassName
> Task :server:bootJar
BUILD SUCCESSFUL in 2s
12 actionable tasks: 5 executed, 7 up-to-date
And the bom's included in the jar:
$ unzip -l server/build/libs/server-0.0.1-SNAPSHOT.jar | grep cdx
61768 10-11-2024 14:53 META-INF/sbom/application.cdx.json
In a multi projects Gradle build the CycloneDX SBOM is not generated and not added to the boot JAR.
Sample project: https://github.com/fmunch/spring-boot-gradle-cyclonedx (our actual project is a bit more complicated, I tried to keep the bare minimum)
gradle bootJar
does not generate a boot JAR containing the SBOM. When looking at the task tree forbootJar
thecyclonedxBom
task is not present:When debugging
org.springframework.boot.gradle.plugin.SpringBootPlugin
it seems thatCycloneDxPlugin
is not in the classpath, preventingCycloneDxPluginAction
from configuringCycloneDxTask
.Even if we add the following,
cyclonedxBom
appears in the task tree and generatesserver/build/reports/bom.*
butCycloneDxPlugin
is still missing from the classpath and the SBOM is missing in the JAR and manifest.