Skip to content

Conversation

rudsberg
Copy link
Contributor

This PR updates the SBOM integration in the native-maven-plugin to handle SBOMs being embedded by default in GraalVM 25. SBOMs will be embedded even if --enable-sbom is not passed to native-image. We have updated our checks accordingly to ensure the base SBOM is generated only when the SBOM feature is enabled.

Additionally, the option augmentedSBOM has been renamed to skipBaseSBOM. We are discontinuing the use of the term "augmented" and will instead refer to the SBOM produced by native-maven-plugin (and consumed by native-image) as the "base" SBOM. The new "skip" prefix aligns better with other configuration options. skipBaseSBOM defaults to false and when set to true the base SBOM is not generated.

With regards to backwards compatibility, I believe the deprecation of augmentedSBOM should be OK given that it was just recently introduced for 24 and it's not documented in the public native-maven-plugin documentation.

@oracle-contributor-agreement oracle-contributor-agreement bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Jul 31, 2025
@rudsberg
Copy link
Contributor Author

rudsberg commented Jul 31, 2025

The failing functional tests seems unrelated to this PR, but I'm looking into it.

The failing test is JavaApplicationFunctionalTest > can build and execute a native image with the Maven plugin when the application has a custom packaging type FAILED and fails with:

org.graalvm.demo.ApplicationTest > message is hello native FAILED
Failures (1):
JUnit Jupiter:ApplicationTest:message is hello native
MethodSource [className = 'org.graalvm.demo.ApplicationTest', methodName = 'usesReflection', methodParameterTypes = '']
=> org.opentest4j.AssertionFailedError: expected: <Hello, native!> but was: <null>

Update:
I've identified and resolved the issue. Here’s what went wrong:

  • This PR correctly generates a base SBOM for GraalVM 25 builds that embed SBOMs by default. In other words, previously all functional tests running on GraalVM 25 and that did not use --enable-sbom did not exercise the SBOMGenerator code path, but now they do.
  • That caused this line to fail. The reason was that it uses mvnDebug, causing excessive printing by the cyclonedx-maven-plugin on version 2.8.1 that we were using, leading to a java.lang.OutOfMemoryError.

The excessive printing seemed like a bug, so I tried updating cyclonedx-maven-plugin to the latest version (2.9.1), which indeed solved it. It now logs in a reasonable manner.

}
logger.warn(String.format("Could not generate an augmented SBOM: %s. Fallback to generating a non-augmented SBOM.",
sbomGenerator.generateIfSupportedAndEnabled(config);
} catch (Exception e) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We now catch all exceptions to avoid the risk of a runtime exception bypassing this fallback mechanism.

Path sbomPath = Paths.get(outputDirectory, SBOM_FILENAME);
try {
/* Suppress the output from the plugin. */
int loggingLevel = logger.getThreshold();
logger.setThreshold(Logger.LEVEL_DISABLED);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logging suppression was removed because it was not working. Setting the logging level like so doesn't restrict the logging in the executeMojo call. Another PR could ensure that the output from cyclonedx-maven-plugin is suppressed.

@rudsberg rudsberg force-pushed the jrudsberg/GR-67605 branch from 8d2773f to ae5ddac Compare August 4, 2025 12:32
…or `SBOMGenerator.generateIfSupportedAndEnabled`
@rudsberg rudsberg force-pushed the jrudsberg/GR-67605 branch from ae5ddac to 5b995dc Compare August 4, 2025 13:02
@@ -277,8 +299,10 @@ private void augmentComponentNode(JSONObject componentNode, Set<ArtifactAdapter>
if (optionalArtifact.isPresent()) {
ArtifactAdapter artifact = optionalArtifact.get();
JSONArray packageNamesArray = new JSONArray();
List<String> sortedPackageNames = artifact.packageNames.stream().sorted().collect(Collectors.toList());
sortedPackageNames.forEach(packageNamesArray::put);
if (artifact.prunable) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor orthogonal improvement.

(Shaded dependencies are correctly marked as non-prunable since we cannot be sure the packageNames are accurate. Therefore, leaving the packageNames array empty increases clarity.)

@rudsberg rudsberg requested review from dnestoro and melix August 4, 2025 14:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
OCA Verified All contributors have signed the Oracle Contributor Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant