Hello,

I'm trying to generate an SBOM of a project using the CycloneDX Maven plugin. This project declares SpringBoot 3.3.0 as parent pom.

I execute the following command: mvn org.cyclonedx:cyclonedx-maven-plugin:2.8.0:makeAggregateBom -DoutputName=bom -DoutputDirectory=./sbom -q

But the resulting SBOM file is: target/classes/META-INF/sbom/application.cdx.json

Now if I downgrade the SpringBoot version to 3.2.5, the SBOM is: sbom/bom.json (as expected, and there's even a sbom/bom.xml available)

Would it be possible to make the SpringBoot's defaults configurable ?

Note that the weird part is that specifying the configuration using -D should take precedence, no ?

Thanks in advance !

Comment From: scottfrederick

Note that the weird part is that specifying the configuration using -D should take precedence, no ?

That's not the case with Maven, unfortunately. Values provided in pom.xml (or, in this case, by Spring Boot's parent POM) take precedence over -D properties on the command line. See #21536 for some details on that.

Would it be possible to make the SpringBoot's defaults configurable ?

Spring Boot documents a tip for working around Maven's order of precedence. You could use that technique with something like this in your pom.xml:

      <plugin>
        <groupId>org.cyclonedx</groupId>
        <artifactId>cyclonedx-maven-plugin</artifactId>
        <configuration>
          <outputName>${outputName}</outputName>
          <outputDirectory>${outputDirectory}</outputDirectory>
        </configuration>
      </plugin>

Overriding the value set by Spring Boot's parent POM prevents Spring Boot's actuator SBOM support from finding the generated SBOM automatically. You'll have to configure the actuator to find the SBOM file in the specified location if you want the SBOM exposed by actuators.

Comment From: nekhtan

Hello @scottfrederick

Thanks for the quick and effective feedback !

Unfortunately I can't update the Maven configuration: I need to use the command line (or via cdxgen) on various project that are not the main one: one project will invoke CycloneDX on several other projects (some will be in SpringBoot 3.3.x, some will not).

But isn't there a way to add plugin configuration in Java ? Like the one for Gradle ? If that would be possible I guess it would be possible to check that System.getProperty("outputDirectory") is already set or not, right?

If there's no workaround at all I guess I'll have to check for both output paths/files.

Comment From: AleZinov

In the same boat here. DevOps team are using several plugins from cli including aforementioned with following properties org.cyclonedx:cyclonedx-maven-plugin:${cyclonedxVersion}:makeBom -DoutputName='bom' -DoutputFormat='all' -Dcyclonedx.verbose=true as we are unable to make changes to parent pom.xml

Comment From: wilkinsona

I think we can fix this by moving the configuration into the execution:

<plugin>
  <groupId>org.cyclonedx</groupId>
  <artifactId>cyclonedx-maven-plugin</artifactId>
  <executions>
    <execution>
      <phase>generate-resources</phase>
      <goals>
        <goal>makeAggregateBom</goal>
      </goals>
      <configuration>
        <projectType>application</projectType>
        <outputDirectory>${project.build.outputDirectory}/META-INF/sbom</outputDirectory>
        <outputFormat>json</outputFormat>
        <outputName>application.cdx</outputName>
      </configuration>
    </execution>
  </executions>
</plugin>

This scopes the configuration to only that one execution, allowing different configuration to be used by other executions, configured either in the pom or on the command line.

With this change in place, a command line execution then works as it did previously:

 ./mvnw org.cyclonedx:cyclonedx-maven-plugin:2.8.0:makeBom -DoutputName='bom' -DoutputFormat='all' -Dcyclonedx.verbose=true
[INFO] Scanning for projects...
[INFO] 
[INFO] ------------------------< com.example:gh-40927 >------------------------
[INFO] Building gh-40927 0.0.1-SNAPSHOT
[INFO]   from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- cyclonedx:2.8.0:makeBom (default-cli) @ gh-40927 ---
[INFO] CycloneDX: Parameters
[INFO] ------------------------------------------------------------------------
[INFO] schemaVersion          : 1.5
[INFO] includeBomSerialNumber : true
[INFO] includeCompileScope    : true
[INFO] includeProvidedScope   : true
[INFO] includeRuntimeScope    : true
[INFO] includeTestScope       : false
[INFO] includeSystemScope     : true
[INFO] includeLicenseText     : false
[INFO] outputFormat           : all
[INFO] outputName             : bom
[INFO] ------------------------------------------------------------------------
[INFO] CycloneDX: Resolving Dependencies
[INFO] CycloneDX: Creating BOM version 1.5 with 20 component(s)
[INFO] CycloneDX: Writing and validating BOM (XML): /Users/awilkinson/dev/temp/gh-40927/target/bom.xml
[INFO]            attaching as gh-40927-0.0.1-SNAPSHOT-cyclonedx.xml
[INFO] CycloneDX: Writing and validating BOM (JSON): /Users/awilkinson/dev/temp/gh-40927/target/bom.json
[INFO]            attaching as gh-40927-0.0.1-SNAPSHOT-cyclonedx.json
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  2.698 s
[INFO] Finished at: 2024-05-29T13:19:26+01:00
[INFO] ------------------------------------------------------------------------

Comment From: nekhtan

Thanks a lot to all the people involved, I'm really grateful and amazed on how fast you've tackled this 😍

Comment From: stephanecodes

@wilkinsona overriding the configuration in pom.xml is a good option but the <configuration> and <executions> nodes must be at the same level for this to work

<plugin>
  <groupId>org.cyclonedx</groupId>
  <artifactId>cyclonedx-maven-plugin</artifactId>
  <configuration>
    <projectType>application</projectType>
    <outputDirectory>${project.build.outputDirectory}/META-INF/sbom</outputDirectory>
    <outputFormat>json</outputFormat>
    <outputName>application.cdx</outputName>
  </configuration>
  <executions>
    <execution>
      <phase>generate-resources</phase>
      <goals>
        <goal>makeAggregateBom</goal>
      </goals>
    </execution>
  </executions>
</plugin>```

**Comment From: oallauddin**

I am upgrading of our existing projects from Spring Boot 3.2.x to Spring Boot 3.3.x.  
Project already had a custom configuration for the Cyclone DX maven plugin.  
Spring Boot 3.3.x is no longer letting use our custom configuration.  
What am I doing wrong?  I am still experiencing the problem.  
Below example project is using Spring Boot 3.3.5 but this issue was closed in Spring Boot 3.3.1.  

Steps to reproduce:
1. Clone this [project](https://github.com/piomin/sample-spring-microservices-new) from this [article](https://piotrminkowski.com/2024/09/05/sbom-with-spring-boot/)
2. Add below configuration to the root pom.xml and run `mvn clean generate-sources`
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        <plugin>
            <groupId>org.cyclonedx</groupId>
            <artifactId>cyclonedx-maven-plugin</artifactId>
            <configuration>
                <outputFormat>all</outputFormat>
                <outputName>bom</outputName>
                <outputDirectory>${project.build.directory}</outputDirectory>
            </configuration>
            <executions>
                <execution>
                    <phase>generate-sources</phase>
                    <goals>
                        <goal>makeBom</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
3.  Custom configuration is being ignored

[INFO] --- cyclonedx:2.8.2:makeBom (default) @ discovery-service --- [INFO] CycloneDX: Resolving Dependencies [INFO] CycloneDX: Creating BOM version 1.5 with 124 component(s) [INFO] CycloneDX: Writing and validating BOM (JSON): /mnt/c/workspaces/github/sample-spring-microservices-new/discovery-service/target/classes/META-INF/sbom/application.cdx.json [INFO] attaching as discovery-service-1.1-SNAPSHOT-cyclonedx.json

![Image](https://github.com/user-attachments/assets/faf8fa12-2edd-440a-861a-46bc0bdeaafa)
4.  I also tried putting the default plugin configuration in `pluginManagement`.  Does not work there either.  



**Comment From: wilkinsona**

@oallauddin I find Maven's behavior rather counter-intuitive here. As you've currently configured it, the effective pom ends up like this:

```xml
      <plugin>
        <groupId>org.cyclonedx</groupId>
        <artifactId>cyclonedx-maven-plugin</artifactId>
        <version>2.8.2</version>
        <executions>
          <execution>
            <phase>generate-sources</phase>
            <goals>
              <goal>makeBom</goal>
              <goal>makeAggregateBom</goal>
            </goals>
            <configuration>
              <projectType>application</projectType>
              <outputDirectory>/Users/aw036093/dev/temp/sample-spring-microservices-new/discovery-service/target/classes/META-INF/sbom</outputDirectory>
              <outputFormat>json</outputFormat>
              <outputName>application.cdx</outputName>
            </configuration>
          </execution>
        </executions>
        <configuration>
          <outputFormat>all</outputFormat>
          <outputName>bom</outputName>
          <outputDirectory>/Users/aw036093/dev/temp/sample-spring-microservices-new/discovery-service/target</outputDirectory>
        </configuration>
      </plugin>

As you can see, Boot's <execution>-level configuration is applying to your execution as well, overriding your broader configuration. You can avoid the problem by adding an <id> to your <exection>:

$ mvn --projects discovery-service generate-resources 
[INFO] Scanning for projects...
[INFO] 
[INFO] ----------------< pl.piomin.services:discovery-service >----------------
[INFO] Building discovery-service 1.1-SNAPSHOT
[INFO]   from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- cyclonedx:2.8.2:makeBom (makeBom) @ discovery-service ---
[INFO] CycloneDX: Resolving Dependencies
[INFO] CycloneDX: Creating BOM version 1.5 with 124 component(s)
[INFO] CycloneDX: Writing and validating BOM (XML): /Users/aw036093/dev/temp/sample-spring-microservices-new/discovery-service/target/bom.xml
[INFO]            attaching as discovery-service-1.1-SNAPSHOT-cyclonedx.xml
[INFO] CycloneDX: Writing and validating BOM (JSON): /Users/aw036093/dev/temp/sample-spring-microservices-new/discovery-service/target/bom.json
[INFO]            attaching as discovery-service-1.1-SNAPSHOT-cyclonedx.json
[INFO] 
[INFO] --- cyclonedx:2.8.2:makeAggregateBom (default) @ discovery-service ---
[INFO] CycloneDX: Resolving Dependencies
[INFO] CycloneDX: Creating BOM version 1.5 with 124 component(s)
[INFO] CycloneDX: Writing and validating BOM (JSON): /Users/aw036093/dev/temp/sample-spring-microservices-new/discovery-service/target/classes/META-INF/sbom/application.cdx.json
[INFO]            attaching as discovery-service-1.1-SNAPSHOT-cyclonedx.json
[WARNING] artifact pl.piomin.services:discovery-service:json:cyclonedx:1.1-SNAPSHOT already attached, replace previous instance
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  4.101 s
[INFO] Finished at: 2025-02-07T16:45:42Z
[INFO] ------------------------------------------------------------------------

@snicoll, is there a better way to do this? Should we have an <id> on our <execution> that's configured in the parent?