Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Gradle] SBOM generation didn't work on Windows #1615

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 25 additions & 19 deletions lib/cli/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1852,28 +1852,34 @@ export async function createJavaBom(path, options) {
process.env.GRADLE_ARGS_DEPENDENCIES
? process.env.GRADLE_ARGS_DEPENDENCIES.split(" ")
: [],
gradleCmd.length,
);
console.log(
"Executing",
gradleCmd,
gradleArguments.join(" "),
"in",
gradleRootPath,
);
const sresult = spawnSync(gradleCmd, gradleArguments, {
cwd: gradleRootPath,
encoding: "utf-8",
timeout: TIMEOUT_MS,
maxBuffer: MAX_BUFFER,
});

if (sresult.status !== 0 || sresult.error) {
if (options.failOnError || DEBUG_MODE) {
console.error(sresult.stdout, sresult.stderr);
const allOutputs = [];
for (const gradleArg of gradleArguments) {
console.log(
"Executing",
gradleCmd,
gradleArg.join(" "),
"in",
gradleRootPath,
);
const sresult = spawnSync(gradleCmd, gradleArg, {
cwd: gradleRootPath,
encoding: "utf-8",
shell: isWin,
timeout: TIMEOUT_MS,
maxBuffer: MAX_BUFFER,
});
if (sresult.status !== 0 || sresult.error) {
if (options.failOnError || DEBUG_MODE) {
console.error(sresult.stdout, sresult.stderr);
}
options.failOnError && process.exit(1);
}
options.failOnError && process.exit(1);
allOutputs.push(sresult.stdout);
}
const sstdout = sresult.stdout;

const sstdout = allOutputs.join("\n");
if (sstdout) {
const cmdOutput = Buffer.from(sstdout).toString();
const perProjectOutput = splitOutputByGradleProjects(cmdOutput, [
Expand Down
90 changes: 58 additions & 32 deletions lib/helpers/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -3782,43 +3782,50 @@ export function executeParallelGradleProperties(dir, allProjectsStr) {
process.env.GRADLE_ARGS_PROPERTIES
? process.env.GRADLE_ARGS_PROPERTIES.split(" ")
: [],
gradleCmd.length,
);
const result = spawnSync(gradleCmd, gradleArgs, {
cwd: dir,
encoding: "utf-8",
shell: isWin,
maxBuffer: MAX_BUFFER,
});
if (result.status !== 0 || result.error) {
if (result.stderr) {
console.error(result.stdout, result.stderr);
console.log(
"1. Check if the correct version of java and gradle are installed and available in PATH. For example, some project might require Java 11 with gradle 7.\n cdxgen container image bundles Java 23 with gradle 8 which might be incompatible.",
);
console.log(
"2. Try running cdxgen with the custom JDK11-based image `ghcr.io/cyclonedx/cdxgen-java11:v11`.",
);
if (result.stderr?.includes("not get unknown property")) {
const allOutputs = [];
for (const gradleArg of gradleArgs) {
console.log("Executing", gradleCmd, gradleArg.join(" "), "in", dir);
const result = spawnSync(gradleCmd, gradleArg, {
cwd: dir,
encoding: "utf-8",
shell: isWin,
maxBuffer: MAX_BUFFER,
});
if (result.status !== 0 || result.error) {
if (result.stderr) {
console.error(result.stdout, result.stderr);
console.log(
"3. Check if the SBOM is generated for the correct root project for your application.",
"1. Check if the correct version of java and gradle are installed and available in PATH. For example, some project might require Java 11 with gradle 7.\n cdxgen container image bundles Java 23 with gradle 8 which might be incompatible.",
);
} else if (
result.stderr?.includes(
"In version catalog libs, import of external catalog file failed",
)
) {
console.log(
"3. Catalog file is required for gradle dependency resolution to succeed.",
"2. Try running cdxgen with the custom JDK11-based image `ghcr.io/cyclonedx/cdxgen-java11:v11`.",
);
}
if (result.stderr.includes("does not exist")) {
return "";
if (result.stderr?.includes("not get unknown property")) {
console.log(
"3. Check if the SBOM is generated for the correct root project for your application.",
);
} else if (
result.stderr?.includes(
"In version catalog libs, import of external catalog file failed",
)
) {
console.log(
"3. Catalog file is required for gradle dependency resolution to succeed.",
);
}
if (result.stderr.includes("does not exist")) {
return "";
}
}
}
allOutputs.push(result.stdout);
Copy link
Collaborator

Choose a reason for hiding this comment

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

How are we handling the case where stdout could be null?

}
const stdout = result.stdout;
if (stdout) {
return Buffer.from(stdout).toString();

const sstdout = allOutputs.join("\n");
if (sstdout) {
return Buffer.from(sstdout).toString();
}
return "";
}
Expand Down Expand Up @@ -11803,25 +11810,44 @@ export function getGradleCommand(srcPath, rootPath) {
* @param {string[]} gradleArguments The general gradle arguments, which must only be added once
* @param {string[]} gradleSubCommands The sub-commands that are to be executed by gradle
* @param {string[]} gradleSubCommandArguments The arguments specific to the sub-command(s), which much be added PER sub-command
* @param {int} gradleCommandLength The length of the full gradle-command
*
* @returns {string[]} Array of arguments to be added to the gradle command
* @returns {string[]} Array of arrays of arguments to be added to the gradle command
*/
export function buildGradleCommandArguments(
gradleArguments,
gradleSubCommands,
gradleSubCommandArguments,
gradleCommandLength,
) {
let allGradleArguments = [
const mainGradleArguments = [
"--build-cache",
"--console",
"plain",
"--no-parallel",
].concat(gradleArguments);
const maxCliArgsLength = isWin
? 7500 - gradleCommandLength - mainGradleArguments.join(" ").length - 2
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is 7500 the maximum gradle supports on windows?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I am fine with creating a temporary powershell script and executing the same if it could yield good performance instead of batching.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I hadn't thought about that yet. Let me check that out, it might make this, and your question above, moot.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I just can't figure out how to get powershell to return the output... @prabhu, do you have any idea/experience with powershell?

Copy link
Collaborator

Choose a reason for hiding this comment

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

It's new for me as well. May be ask Gemini or OpenAI?

Copy link
Collaborator

Choose a reason for hiding this comment

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

@malice00, powershell supports redirecting output to files.

: -1;
const splitArgs = [];
let allGradleArguments = [].concat(mainGradleArguments);
let remainingLength = maxCliArgsLength;
for (const gradleSubCommand of gradleSubCommands) {
const subCommandLength =
[gradleSubCommand, ...gradleSubCommandArguments].join(" ").length + 1;
if (maxCliArgsLength !== -1 && remainingLength - subCommandLength < 0) {
splitArgs.push(allGradleArguments);
allGradleArguments = [].concat(mainGradleArguments);
remainingLength = maxCliArgsLength;
}
allGradleArguments.push(gradleSubCommand);
allGradleArguments = allGradleArguments.concat(gradleSubCommandArguments);
remainingLength -= subCommandLength;
}
if (allGradleArguments.length !== mainGradleArguments.length) {
splitArgs.push(allGradleArguments);
}
return allGradleArguments;
return splitArgs;
}

/**
Expand Down
Loading