Skip to content

Commit 6c5fdf3

Browse files
committed
Add error handling and useful prints for SBOM feature
1 parent 322dfd6 commit 6c5fdf3

File tree

4 files changed

+77
-11
lines changed

4 files changed

+77
-11
lines changed

common/utils/src/main/java/org/graalvm/buildtools/utils/NativeImageUtils.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import static org.graalvm.buildtools.utils.SharedConstants.GRAALVM_EXE_EXTENSION;
5757

5858
public class NativeImageUtils {
59+
public static final String ORACLE_GRAALVM_IDENTIFIER = "Oracle GraalVM";
5960

6061
private static final Pattern requiredVersionPattern = Pattern.compile("^([0-9]+)(?:\\.([0-9]+)?)?(?:\\.([0-9]+)?)?$");
6162

native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@
8080
import java.util.stream.Collectors;
8181
import java.util.stream.Stream;
8282

83+
import static org.graalvm.buildtools.utils.NativeImageUtils.ORACLE_GRAALVM_IDENTIFIER;
84+
8385
/**
8486
* @author Sebastien Deleuze
8587
*/
@@ -442,7 +444,7 @@ protected void checkRequiredVersionIfNeeded() throws MojoExecutionException {
442444
}
443445

444446
protected boolean isOracleGraalVM() throws MojoExecutionException {
445-
return getVersionInformation().contains("Oracle GraalVM");
447+
return getVersionInformation().contains(ORACLE_GRAALVM_IDENTIFIER);
446448
}
447449

448450
/**

native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeCompileNoForkMojo.java

Lines changed: 69 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,14 @@
5454
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
5555
import org.codehaus.plexus.util.xml.Xpp3Dom;
5656
import org.graalvm.buildtools.maven.sbom.SBOMGenerator;
57+
import org.graalvm.buildtools.utils.NativeImageUtils;
5758

5859
import java.util.Arrays;
5960
import java.util.List;
6061
import java.util.function.BiFunction;
6162

63+
import static org.graalvm.buildtools.utils.NativeImageUtils.ORACLE_GRAALVM_IDENTIFIER;
64+
6265
/**
6366
* This goal runs native builds. It functions the same as the native:compile goal, but it
6467
* does not fork the build, so it is suitable for attaching to the build lifecycle.
@@ -74,9 +77,9 @@ public class NativeCompileNoForkMojo extends AbstractNativeImageMojo {
7477
@Parameter(property = "skipNativeBuildForPom", defaultValue = "false")
7578
private boolean skipNativeBuildForPom;
7679

77-
public static final String enableSBOMParamName = "enableSBOM";
78-
@Parameter(property = enableSBOMParamName, defaultValue = "true")
79-
private boolean enableSBOM;
80+
public static final String enableAugmentedSBOMParamName = "enableAugmentedSBOM";
81+
@Parameter(property = enableAugmentedSBOMParamName, defaultValue = "false")
82+
private boolean enableAugmentedSBOM;
8083

8184
private PluginParameterExpressionEvaluator evaluator;
8285

@@ -106,14 +109,73 @@ public void execute() throws MojoExecutionException {
106109
maybeSetMainClassFromPlugin(this::consumeConfigurationNodeValue, "org.apache.maven.plugins:maven-jar-plugin", "archive", "manifest", "mainClass");
107110
maybeAddGeneratedResourcesConfig(buildArgs);
108111

109-
if (isOracleGraalVM() && enableSBOM) {
110-
var generator = new SBOMGenerator(mavenProject, mavenSession, pluginManager, repositorySystem, mainClass, logger);
111-
generator.generate();
112-
}
112+
generateSBOMIfPossible();
113113

114114
buildImage();
115115
}
116116

117+
/**
118+
* Generates an SBOM using the {@link SBOMGenerator} if {@link NativeCompileNoForkMojo#enableAugmentedSBOM} is true
119+
* and the required pre-conditions are met.
120+
*
121+
* @throws IllegalArgumentException when some pre-conditions are not met.
122+
* @throws MojoExecutionException when SBOM generation failed.
123+
*/
124+
private void generateSBOMIfPossible() throws IllegalArgumentException, MojoExecutionException {
125+
String sbomNativeImageFlag = "--enable-sbom";
126+
boolean sbomEnabledForNativeImage = getBuildArgs().stream().anyMatch(v -> v.contains(sbomNativeImageFlag));
127+
if (!sbomEnabledForNativeImage && !enableAugmentedSBOM) {
128+
/* Omit showing a hint to use SBOM since the Native Image build output will include such a hint. */
129+
return;
130+
}
131+
132+
if (!isOracleGraalVM()) {
133+
if (enableAugmentedSBOM) {
134+
throw new IllegalArgumentException(
135+
String.format("Configuration option %s is only supported in %s.", enableAugmentedSBOMParamName, ORACLE_GRAALVM_IDENTIFIER));
136+
}
137+
return;
138+
}
139+
140+
if (!enableAugmentedSBOM) {
141+
if (checkAugmentedSBOMSupportedByVersion(false)) {
142+
logger.info(String.format("Set configuration option %s to true to create an enhanced and more accurate SBOM.", enableAugmentedSBOMParamName));
143+
}
144+
return;
145+
}
146+
147+
checkAugmentedSBOMSupportedByVersion(true);
148+
if (!sbomEnabledForNativeImage) {
149+
logger.info(String.format("Automatically added build argument %s with default options to Native Image because configuration option %s was set to true. " +
150+
"An SBOM will be embedded in the image.", sbomNativeImageFlag, enableAugmentedSBOMParamName));
151+
buildArgs.add(sbomNativeImageFlag);
152+
}
153+
154+
var sbomGenerator = new SBOMGenerator(mavenProject, mavenSession, pluginManager, repositorySystem, mainClass, logger);
155+
sbomGenerator.generate();
156+
}
157+
158+
/**
159+
* Checks if the JDK version supports the {@link NativeCompileNoForkMojo#enableAugmentedSBOM} flag.
160+
*
161+
* @param throwErrorIfNotSupported if true, then an error is thrown if the check failed.
162+
* @return true if the JDK version supports the flag, otherwise false (if {@param throwErrorIfNotSupported} is false).
163+
* @throws MojoExecutionException when {@param throwErrorIfNotSupported} is true and the version information could not be derived.
164+
* @throws IllegalArgumentException when {@param throwErrorIfNotSupported} is true and the version check failed.
165+
*/
166+
private boolean checkAugmentedSBOMSupportedByVersion(boolean throwErrorIfNotSupported) throws IllegalArgumentException, MojoExecutionException {
167+
int detectedJdkVersion = NativeImageUtils.getMajorJDKVersion(getVersionInformation());
168+
if (detectedJdkVersion < SBOMGenerator.requiredNativeImageVersion) {
169+
if (throwErrorIfNotSupported) {
170+
throw new IllegalArgumentException(
171+
String.format("%s version %s is required to use configuration option %s but major JDK version %s has been detected.",
172+
ORACLE_GRAALVM_IDENTIFIER, SBOMGenerator.requiredNativeImageVersion, enableAugmentedSBOMParamName, detectedJdkVersion));
173+
}
174+
return false;
175+
}
176+
return true;
177+
}
178+
117179
private String consumeConfigurationNodeValue(String pluginKey, String... nodeNames) {
118180
Plugin selectedPlugin = project.getPlugin(pluginKey);
119181
if (selectedPlugin == null) {

native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/sbom/SBOMGenerator.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,6 @@
5050
import org.apache.maven.project.MavenProject;
5151
import org.codehaus.plexus.logging.Logger;
5252
import org.eclipse.aether.RepositorySystem;
53-
import org.graalvm.buildtools.maven.NativeCompileNoForkMojo;
54-
5553
import java.io.IOException;
5654
import java.nio.file.Files;
5755
import java.nio.file.Path;
@@ -61,6 +59,7 @@
6159
import java.util.Set;
6260
import java.util.stream.Collectors;
6361

62+
import static org.graalvm.buildtools.maven.NativeCompileNoForkMojo.enableAugmentedSBOMParamName;
6463
import static org.twdata.maven.mojoexecutor.MojoExecutor.*;
6564

6665
/**
@@ -82,6 +81,8 @@
8281
* * Enhanced Accuracy: Native Image augments and refines the SBOM, potentially significantly improving its accuracy.
8382
*/
8483
final public class SBOMGenerator {
84+
public static final int requiredNativeImageVersion = 24;
85+
8586
private final MavenProject mavenProject;
8687
private final MavenSession mavenSession;
8788
private final BuildPluginManager pluginManager;
@@ -176,7 +177,7 @@ public void generate() throws MojoExecutionException {
176177
} catch (Exception exception) {
177178
deleteFileIfExists(sbomPath);
178179
String errorMsg = String.format("Failed to create SBOM. Please try again and report this issue if it persists. " +
179-
"To bypass this failure, disable SBOM generation by setting %s to false.", NativeCompileNoForkMojo.enableSBOMParamName);
180+
"To bypass this failure, disable SBOM generation by setting configuration option %s to false.", enableAugmentedSBOMParamName);
180181
throw new MojoExecutionException(errorMsg, exception);
181182
}
182183
}

0 commit comments

Comments
 (0)