You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm leaving this less as a feature request / bug report and more as a "this is something I've encountered that I'm sure other people will also suffer through". There's probably a minor change that can be made to the plugin to prevent future headaches however.
I was recently trying to bump some projects of mine to Gradle 8.x and Spring 3.3.x but wasn't able to because of how CycloneDX handles its outputs. Spring 3.3.x added new features around SBOMs that copy them into your WARs/JARs if you use the CycloneDX plugin. This works fine when you're building just one BOM but when you're building more, like I do, it falls apart:
> Task :cyclonedxBuildBom FAILED
FAILURE: Build failed with an exception.
* What went wrong:
A problem was found with the configuration of task ':cyclonedxBuildBom' (type 'CycloneDxTask').
- Gradle detected a problem with the following location: 'C:\Users\ThomGeG\git\<my-project>\build\reports'.
Reason: Task ':processResources' uses this output of task ':cyclonedxBuildBom' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed.
Possible solutions:
1. Declare task ':cyclonedxBuildBom' as an input of ':processResources'.
2. Declare an explicit dependency on ':cyclonedxBuildBom' from ':processResources' using Task#dependsOn.
3. Declare an explicit dependency on ':cyclonedxBuildBom' from ':processResources' using Task#mustRunAfter.
For more information, please refer to https://docs.gradle.org/8.10/userguide/validation_problems.html#implicit_dependency in the Gradle documentation.
Specifically I've got two CycloneDxTask, cyclonedxBom (the automatically created one) that builds me BOMs for the runtime depenedncies and another, cyclonedxBuildBom, that builds them for the non-runtime dependencies (test scope and build pipeline stuff). The problem is that those tasks have overlapping outputs because CycloneDxTask uses an @OutputDirectory rather than a specific @OutputFile and I hadn't made them distinct folders:
While processResources has an input of just build/reports/application-bom.json, that file actually exists in a directory that's the output of two different tasks. Gradle 8.x tightened how it treats overlapping outputs (this stuff will work fine on Gradle 7.x), spitting the dummy when it finds them because they're bad practice that compromise its caching mechanisms. processResources is being specifically mentioned because the new Spring feature works by reconfiguring processResources to copy the BOM producted by cyclonedxBom to META-INF/sbom so it gets zipped into the JARs/WARs:
Rather than having @OutputDirectory destination we'd instead have @OutputFile output.
There'd be three inputs for controlling the output file, outputName, outputDirectory, outputFormat.
Those three inputs would be used to define said @OutputFile (<outputDirectory>/<outputName>.<outputFormat>).
Each task would only produce a single file, so no more outputFormat = 'all'. If you need multiple formats, you'd need mutliple tasks.
I'm not sure how I feel about this as a general solution. outputFormat = 'all' seems very convenient for getting both XML and JSON BOMs without needing to scrape all the data again. This would also be a breaking change because of all the input/output changes and would mean going to 2.x.
It would however seem to definitively solve the overlapping outputs problem as there's no more directories to have overlap.
Reconfigure cyclonedxBuildBom and cyclonedxBom to have their own distinct output folders
This is much more straightforward and what I'll be doing, at least in the short term. That'd mean:
Reconfiguring cyclonedxBom to output to something like build/reports/cyclonedx/application
Reconfiguring cyclonedxBuildBom output to something like build/reports/cyclonedx/build
Registering a Copy task that copies the BOMs from both to a shared directory, build/reports/boms, for things like Jenkins.
It seems like if this is the desired solution then the default output location should be changed to something like build/reports/boms or build/reports/cyclonedx w/ a note in the README.md about registering your own tasks.
Additional context
I started a thread on the Gradle Community Slack here that also has some details about the problem and feedback from the Gradle maintainers.
So the only action here I think is to just change the default output directory from build/reports to either build/reports/boms or build/reports/cyclonedx. I'm happy to raise the change if people like the idea.
Hey all,
I'm leaving this less as a feature request / bug report and more as a "this is something I've encountered that I'm sure other people will also suffer through". There's probably a minor change that can be made to the plugin to prevent future headaches however.
I was recently trying to bump some projects of mine to Gradle 8.x and Spring 3.3.x but wasn't able to because of how CycloneDX handles its outputs. Spring 3.3.x added new features around SBOMs that copy them into your WARs/JARs if you use the CycloneDX plugin. This works fine when you're building just one BOM but when you're building more, like I do, it falls apart:
Specifically I've got two
CycloneDxTask
,cyclonedxBom
(the automatically created one) that builds me BOMs for the runtime depenedncies and another,cyclonedxBuildBom
, that builds them for the non-runtime dependencies (test scope and build pipeline stuff). The problem is that those tasks have overlapping outputs becauseCycloneDxTask
uses an@OutputDirectory
rather than a specific@OutputFile
and I hadn't made them distinct folders:cyclonedx-gradle-plugin/src/main/java/org/cyclonedx/gradle/CycloneDxTask.java
Lines 264 to 267 in d137d9b
While
processResources
has an input of justbuild/reports/application-bom.json
, that file actually exists in a directory that's the output of two different tasks. Gradle 8.x tightened how it treats overlapping outputs (this stuff will work fine on Gradle 7.x), spitting the dummy when it finds them because they're bad practice that compromise its caching mechanisms.processResources
is being specifically mentioned because the new Spring feature works by reconfiguringprocessResources
to copy the BOM producted bycyclonedxBom
toMETA-INF/sbom
so it gets zipped into the JARs/WARs:https://github.com/spring-projects/spring-boot/blob/3.3.x/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/CycloneDxPluginAction.java#L71-L76
cyclonedxBuildBom
is problematic because it hasn't been wired toprocessResources
butcyclonedxBom
is fine because it has.There's two ways I see to address this:
Rework how the
CycloneDxTask
defines its outputsThere's an example of how to handle tasks that create files in the Gradle docs. If the CycloneDX plugin were to follow it that would mean:
@OutputDirectory destination
we'd instead have@OutputFile output
.outputName
,outputDirectory
,outputFormat
.@OutputFile
(<outputDirectory>/<outputName>.<outputFormat>
).outputFormat = 'all'
. If you need multiple formats, you'd need mutliple tasks.I'm not sure how I feel about this as a general solution.
outputFormat = 'all'
seems very convenient for getting both XML and JSON BOMs without needing to scrape all the data again. This would also be a breaking change because of all the input/output changes and would mean going to 2.x.It would however seem to definitively solve the overlapping outputs problem as there's no more directories to have overlap.
Reconfigure
cyclonedxBuildBom
andcyclonedxBom
to have their own distinct output foldersThis is much more straightforward and what I'll be doing, at least in the short term. That'd mean:
cyclonedxBom
to output to something likebuild/reports/cyclonedx/application
cyclonedxBuildBom
output to something likebuild/reports/cyclonedx/build
build/reports/boms
, for things like Jenkins.It seems like if this is the desired solution then the default output location should be changed to something like
build/reports/boms
orbuild/reports/cyclonedx
w/ a note in the README.md about registering your own tasks.Additional context
I started a thread on the Gradle Community Slack here that also has some details about the problem and feedback from the Gradle maintainers.
There's also some stuff here about why overlapping outputs are bad and an open issue in GitHub where they plan to deprecate them entirely.
The text was updated successfully, but these errors were encountered: