Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into solarisfixes
Browse files Browse the repository at this point in the history
sxa authored Dec 3, 2024
2 parents 290bcb3 + ededebc commit 14d9387
Showing 18 changed files with 981 additions and 147 deletions.
5 changes: 5 additions & 0 deletions .github/linters/.gitleaks.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
title = "gitleaks config"
[allowlist]
files = [
"cyclonedx-lib/dependency_data/dependency_data.properties"
]
3 changes: 2 additions & 1 deletion .github/linters/suppressed-java.xml
Original file line number Diff line number Diff line change
@@ -28,4 +28,5 @@
<suppress files="." checks="LineLength" />
<suppress files="." checks="Header" /> <!-- Disabled as we don't use headers in our project for the test files -->
<suppress files="." checks="FileTabCharacter" /> <!-- Disabled as it generally doesn't matter if tabs are disabled or not -->
</suppressions>
<suppress files="." checks="ParameterNumber" />
</suppressions>
73 changes: 42 additions & 31 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -35,10 +35,6 @@ jobs:
build_linux:
name: Linux
runs-on: ubuntu-latest
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: 'true'
container:
image: ${{ matrix.image }}
strategy:
fail-fast: false
matrix:
@@ -80,24 +76,23 @@ jobs:
variant: bisheng
image: adoptopenjdk/centos7_build_image
steps:
# pinned at v3 to as Node.js 20.x is not supported on Centos 7
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- uses: actions/checkout@v4

- name: Build Linux
run: ./build-farm/make-adopt-build-farm.sh
env:
JAVA_TO_BUILD: ${{ matrix.version }}
ARCHITECTURE: x64
VARIANT: ${{ matrix.variant }}
TARGET_OS: ${{ matrix.os }}
FILENAME: OpenJDK.tar.gz
# Don't set the OS as we use both linux and alpine-linux
PLATFORM_CONFIG_LOCATION: adoptium/temurin-build/master/build-farm/platform-specific-configurations
BUILD_ARGS: --create-sbom
CONFIGURE_ARGS: --with-native-debug-symbols=none

# pinned at v3 to as Node.js 20.x is not supported on Centos 7
- uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
- name: Build Linux within container image "${{ matrix.image }}"
run: |
docker run --rm -w /home/jenkins -v "$PWD":"/home/jenkins" \
-e "JAVA_TO_BUILD=${{ matrix.version }}" \
-e "ARCHITECTURE=x64" \
-e "VARIANT=${{ matrix.variant }}" \
-e "TARGET_OS=${{ matrix.os }}" \
-e "FILENAME=OpenJDK.tar.gz" \
-e "PLATFORM_CONFIG_LOCATION=adoptium/temurin-build/master/build-farm/platform-specific-configurations" \
-e "BUILD_ARGS=--create-sbom" \
-e "CONFIGURE_ARGS=--with-native-debug-symbols=none" \
"${{ matrix.image }}" \
./build-farm/make-adopt-build-farm.sh
- uses: actions/upload-artifact@v4
name: Collect and Archive Artifacts
with:
name: ${{matrix.version}}-${{matrix.os}}-${{matrix.variant}}
@@ -110,17 +105,33 @@ jobs:
- name: Set root of jdk image dir
run: |
imageroot=$(find "${HOME}/JDK" -name release -type f)
echo "TEST_JDK_HOME=$(dirname "${imageroot}")" >> "$GITHUB_ENV"
- name: Smoke test
uses: adoptium/run-aqa@6bacb4e732ad546eda1b09665b9067cdc87651f4 # v2
# TEST_JDK_HOME needs to be mapped to the docker container /home/jenkins mapping
echo "TEST_JDK_HOME=$(dirname "${imageroot}")" | sed "s,${HOME},/home/jenkins," >> "$GITHUB_ENV"
- name: Checkout aqa-tests repo
uses: actions/checkout@v4
with:
build_list: 'functional/buildAndPackage'
target: '_extended.functional'
vendor_testRepos: "${{ github.event.pull_request.head.repo.html_url }}.git"
vendor_testBranches: "${{ github.head_ref }}"
vendor_testDirs: "/test/functional"
# pinned at v3 to as Node.js 20.x is not supported on Centos 7
- uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
repository: adoptium/aqa-tests
path: aqa-tests
- name: Run Smoke test within container image "${{ matrix.image }}"
env:
VENDOR_REPOS: ${{ github.event.pull_request.head.repo.html_url }}.git
VENDOR_BRANCH: ${{ github.head_ref }}
run: |
WORK_DIR="${PWD//${HOME}//home/jenkins}"
docker run --rm -w /home/jenkins -v "$HOME":"/home/jenkins" \
-e "TEST_JDK_HOME=${TEST_JDK_HOME}" \
-e "BUILD_LIST=functional/buildAndPackage" \
"${{ matrix.image }}" \
sh -c "cd ${WORK_DIR}/aqa-tests && \
./get.sh --vendor_repos ${VENDOR_REPOS} \
--vendor_branches ${VENDOR_BRANCH} \
--vendor_dirs /test/functional && \
cd TKG && \
make compile && \
make _extended.functional"
- uses: actions/upload-artifact@v4
name: Collect and Archive SmokeTest Results
if: failure()
with:
2 changes: 1 addition & 1 deletion .github/workflows/ca-cert-updater.yml
Original file line number Diff line number Diff line change
@@ -35,7 +35,7 @@ jobs:
working-directory: ./security
run: "./mk-ca-bundle.pl"

- uses: gr2m/create-or-update-pull-request-action@488876a65a2ca38b7eb05e9086166337087f5323 # v1.10.0
- uses: gr2m/create-or-update-pull-request-action@b65137ca591da0b9f43bad7b24df13050ea45d1b # v1.10.1
env:
GITHUB_TOKEN: ${{ secrets.ADOPTIUM_TEMURIN_BOT_TOKEN }}
with:
6 changes: 3 additions & 3 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -58,7 +58,7 @@ jobs:

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@396bb3e45325a47dd9ef434068033c6d5bb0d11a # v3.27.3
uses: github/codeql-action/init@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -68,7 +68,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@396bb3e45325a47dd9ef434068033c6d5bb0d11a # v3.27.3
uses: github/codeql-action/autobuild@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5

# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@@ -81,6 +81,6 @@ jobs:
# ./location_of_script_within_repo/buildscript.sh

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@396bb3e45325a47dd9ef434068033c6d5bb0d11a # v3.27.3
uses: github/codeql-action/analyze@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5
with:
category: "/language:${{matrix.language}}"
2 changes: 1 addition & 1 deletion .github/workflows/ossf-scorecard.yml
Original file line number Diff line number Diff line change
@@ -46,6 +46,6 @@ jobs:
name: SARIF file
path: results.sarif
retention-days: 5
- uses: github/codeql-action/upload-sarif@396bb3e45325a47dd9ef434068033c6d5bb0d11a # v2.13.4
- uses: github/codeql-action/upload-sarif@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v2.13.4
with:
sarif_file: results.sarif
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# ********************************************************************************
# Copyright (c) 2023 Contributors to the Eclipse Foundation
# Copyright (c) 2023, 2024 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) with this work for additional
# information regarding copyright ownership.
@@ -12,7 +12,7 @@
# ********************************************************************************

---
name: TestSBOM
name: TestCycloneDX

on:
pull_request:
@@ -30,30 +30,49 @@ permissions:
contents: read

jobs:
test_sbom_gen:
name: gen_sbom
test_cyclonedx_gen:
name: gen_cyclonedx
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

# Build with jdk8 to ensure TemurinGenSBOM meets min compatibility
# Build with jdk8 to ensure TemurinGen* meets min compatibility
- uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4.5.0
id: setup-java
with:
java-version: 8
distribution: 'temurin'

- name: Build TemurinGenSBOM.java
- name: Build TemurinGenSBOM.java and TemurinGenCDXA.java
run: |
ant -noinput -buildfile cyclonedx-lib/build.xml clean
ant -noinput -buildfile cyclonedx-lib/build.xml build
- name: Run TemurinGenSBOM Unit test
run: ant -noinput -buildfile cyclonedx-lib/build.xml run

- name: Run TemurinGenCDXA Unit test
run: ant -noinput -buildfile cyclonedx-lib/build.xml runCDXA

- name: Validate generated SBOM and CDXA documents using cyclonedx-cli validate
run: |
curl -L -O https://github.com/CycloneDX/cyclonedx-cli/releases/latest/download/cyclonedx-linux-x64
chmod +x cyclonedx-linux-x64
./cyclonedx-linux-x64 validate --input-file cyclonedx-lib/build/testSBOM.json --fail-on-errors --input-version v1_6
./cyclonedx-linux-x64 validate --input-file cyclonedx-lib/build/testSBOM.xml --fail-on-errors --input-version v1_6
./cyclonedx-linux-x64 validate --input-file cyclonedx-lib/build/testCDXA.json --fail-on-errors --input-version v1_6
./cyclonedx-linux-x64 validate --input-file cyclonedx-lib/build/testCDXA.xml --fail-on-errors --input-version v1_6
- uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
name: Collect and Archive TemurinGenSBOM Artifacts
with:
name: testSBOM
path: cyclonedx-lib/build/testSBOM.json
path: cyclonedx-lib/build/testSBOM.*

- uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
name: Collect and Archive TemurinGenCDXA Artifacts
with:
name: testCDXA
path: cyclonedx-lib/build/testCDXA.*

2 changes: 1 addition & 1 deletion RELEASING.md
Original file line number Diff line number Diff line change
@@ -149,7 +149,7 @@ flowchart TD

</details>

Disable nightly testing so the release builds aren't delayed by any nightly test runs (set `enableTests : false` in [defaults.json](https://github.com/adoptium/ci-jenkins-pipelines/blob/master/pipelines/defaults.json)). Ensure the build pipeline generator job runs successfully (<https://ci.adoptium.net/job/build-scripts/job/utils/job/build-pipeline-generator/>), and the flag is disabled by bringing up the Build pipeline job and check the `enableTests` checkbox is unticked.
Scheduled pipeline Testing is automatically disabled from the Saturday prior to "release Tuesday", to the Sunday after, see: https://github.com/adoptium/ci-jenkins-pipelines/blob/5bd79eb1d95a033c4ee364a8f9fcc270ad653178/pipelines/build/common/trigger_beta_build.groovy#L51

Add a banner to the website to indicate that the releases are coming in the near future ([Example Changes](https://github.com/adoptium/adoptium.net/blob/main/src/components/Banner.tsx)).

5 changes: 3 additions & 2 deletions SmokeTesting.md
Original file line number Diff line number Diff line change
@@ -7,8 +7,9 @@ These are the general steps to execute the Smoke Tests found in[/test/functional
1. export TEST_JDK_HOME=/someLocation // set test JDK home. On windows, the windows path format is expected. (i.e., TEST_JDK_HOME=C:\someLocation )
1. git clone [https://github.com/adoptium/aqa-tests.git](https://github.com/adoptium/aqa-tests) to /testLocation
1. cd aqa-tests
1. ./get.sh
1. ./get.sh --vendor_repos https://github.com/adoptium/temurin-build --vendor_branches master --vendor_dirs /test/functional
1. ( When running get.sh ensure the vendor parameters are passed correctly, the above example shows how to run the smoke tests contained within the temurin-build repository )
1. cd TKG
1. Export environment variables suitable for the SDK under test and for the test materials being used (i.e., export BUILD_LIST=functional/buildAndPackage, VENDOR_TEST_REPOS=https://github.com/adoptium/temurin-build, VENDOR_TEST_BRANCHES=master, VENDOR_TEST_DIRS=/test/functional )
1. Export environment variables suitable for the SDK under test and for the test materials being used (i.e., export BUILD_LIST=functional/buildAndPackage, this value details which test material that should be compiled.
1. make compile // fetches test material and compiles it, based on build.xml files in the test directories
1. make _extended.functional // executes the test target (can be test group, level, level.group or specific test). i.e., openjdk (all tests in openjdk group), sanity.functional (all functional tests labelled at sanity level), or in the case of smoke tests which are all tagged to belong to level=extended and group=functional, we use `_extended.functional` and because we have limited BUILD_LIST to the directory where the smoke test material lives, we will only run tests from that directory tagged as extended.functional.
381 changes: 373 additions & 8 deletions cyclonedx-lib/build.xml

Large diffs are not rendered by default.

16 changes: 14 additions & 2 deletions cyclonedx-lib/dependency_data/dependency_data.properties
Original file line number Diff line number Diff line change
@@ -21,11 +21,14 @@ commons-codec.jar=commons-codec-${commons-codec.version}.jar
commons-collections4.version=4.4
commons-collections4.sha256=1df8b9430b5c8ed143d7815e403e33ef5371b2400aadbe9bda0883762e0846d1
commons-collections4.jar=commons-collections4-${commons-collections4.version}.jar
commons-lang3.version=3.17.0
commons-lang3.sha256=6ee731df5c8e5a2976a1ca023b6bb320ea8d3539fbe64c8a1d5cb765127c33b4
commons-lang3.jar=commons-lang3-${commons-lang3.version}.jar
commons-io.version=2.16.1
commons-io.sha256=f41f7baacd716896447ace9758621f62c1c6b0a91d89acee488da26fc477c84f
commons-io.jar=commons-io-${commons-io.version}.jar
cyclonedx-core-java.version=9.0.5
cyclonedx-core-java.sha256=9474c73a81d9be6206367d357a3449e03e70c69bc672d82be04f15806ef170fa
cyclonedx-core-java.version=9.1.0
cyclonedx-core-java.sha256=a911ee5e5ebdabc2b2c08d08f9c92c673c21965ee1b982f40fc166d80f1eb088
cyclonedx-core-java.jar=cyclonedx-core-java-${cyclonedx-core-java.version}.jar
github-package-url.version=1.5.0
github-package-url.sha256=e45551727707acc0c56ac62d56964332ea0f138d6cc3656d988b9369150f5247
@@ -45,10 +48,17 @@ jackson-dataformat-xml.jar=jackson-dataformat-xml-${jackson-dataformat-xml.versi
json-schema-validator.version=1.5.1
json-schema-validator.sha256=de015f79d4a63d22c002bad76bb30c039cafa205465eef8770e2c6b85880ded7
json-schema-validator.jar=json-schema-validator-${json-schema-validator.version}.jar
stax2-api.version=4.2.2
stax2-api.sha256=a61c48d553efad78bc01fffc4ac528bebbae64cbaec170b2a5e39cf61eb51abe
stax2-api.jar=stax2-api-${stax2-api.version}.jar
woodstox-core.version=7.1.0
woodstox-core.sha256=81266920a1cdc47306a8a2b4726c99ec89b3fbf31c2470e4f5e477d9d857ca9f
woodstox-core.jar=woodstox-core-${woodstox-core.version}.jar

# Download URLs
commons-codec.url=${maven.central.repo}/commons-codec/commons-codec/${commons-codec.version}/${commons-codec.jar}
commons-collections4.url=${maven.central.repo}/org/apache/commons/commons-collections4/${commons-collections4.version}/${commons-collections4.jar}
commons-lang3.url=${maven.central.repo}/org/apache/commons/commons-lang3/${commons-lang3.version}/${commons-lang3.jar}
commons-io.url=${maven.central.repo}/commons-io/commons-io/${commons-io.version}/${commons-io.jar}
cyclonedx-core-java.url=${maven.central.repo}/org/cyclonedx/cyclonedx-core-java/${cyclonedx-core-java.version}/${cyclonedx-core-java.jar}
github-package-url.url=${maven.central.repo}/com/github/package-url/packageurl-java/${github-package-url.version}/${github-package-url.jar}
@@ -57,4 +67,6 @@ jackson-core.url=${maven.central.repo}/com/fasterxml/jackson/core/jackson-core/$
jackson-databind.url=${maven.central.repo}/com/fasterxml/jackson/core/jackson-databind/${jackson-databind.version}/${jackson-databind.jar}
jackson-dataformat-xml.url=${maven.central.repo}/com/fasterxml/jackson/dataformat/jackson-dataformat-xml/${jackson-dataformat-xml.version}/${jackson-dataformat-xml.jar}
json-schema-validator.url=${maven.central.repo}/com/networknt/json-schema-validator/${json-schema-validator.version}/${json-schema-validator.jar}
stax2-api.url=${maven.central.repo}/org/codehaus/woodstox/stax2-api/${stax2-api.version}/${stax2-api.jar}
woodstox-core.url=${maven.central.repo}/com/fasterxml/woodstox/woodstox-core/${woodstox-core.version}/${woodstox-core.jar}

4 changes: 3 additions & 1 deletion cyclonedx-lib/sign_src/TemurinSignSBOM.java
Original file line number Diff line number Diff line change
@@ -60,7 +60,7 @@ private TemurinSignSBOM() {
* @param args Arguments for sbom operation.
*/
public static void main(final String[] args) {
String cmd = null;
String cmd = "";
String privateKeyFile = null;
String publicKeyFile = null;
String fileName = null;
@@ -95,6 +95,8 @@ public static void main(final String[] args) {
} else if (cmd.equals("verifySignature")) {
success = verifySignature(fileName, publicKeyFile); // set success to the result of verifySignature
System.out.println("Signature verification result: " + (success ? "Valid" : "Invalid"));
} else {
System.out.println("Please enter a command.");
}

// Set success to true only when the operation is completed successfully.
336 changes: 336 additions & 0 deletions cyclonedx-lib/src/temurin/sbom/TemurinGenCDXA.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,336 @@
/*
* ********************************************************************************
* Copyright (c) 2024 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made
* available under the terms of the Apache Software License 2.0
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* SPDX-License-Identifier: Apache-2.0
* ********************************************************************************
*/

package temurin.sbom;

import org.cyclonedx.exception.GeneratorException;
import org.cyclonedx.generators.json.BomJsonGenerator;
import org.cyclonedx.generators.xml.BomXmlGenerator;
import org.cyclonedx.model.Bom;
import org.cyclonedx.model.Component;
import org.cyclonedx.model.ExternalReference;
import org.cyclonedx.model.Hash;
import org.cyclonedx.model.OrganizationalEntity;
import org.cyclonedx.model.attestation.Declarations;
import org.cyclonedx.model.attestation.Assessor;
import org.cyclonedx.model.attestation.Attestation;
import org.cyclonedx.model.attestation.AttestationMap;
import org.cyclonedx.model.attestation.Claim;
import org.cyclonedx.model.attestation.affirmation.Affirmation;
import org.cyclonedx.model.attestation.affirmation.Signatory;
import org.cyclonedx.model.attestation.Targets;
import org.cyclonedx.parsers.JsonParser;
import org.cyclonedx.parsers.XmlParser;
import org.cyclonedx.Version;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.List;
import java.util.LinkedList;
import java.util.UUID;

/**
* Command line tool to construct a CycloneDX CDXA.
*/
public final class TemurinGenCDXA {

private static boolean verbose = false;
private static boolean useJson = false;

// Valid predicates
enum CDXAPredicate {
VERIFIED_REPRODUCIBLE_BUILD
};

private TemurinGenCDXA() {
}

/**
* Main entry.
* @param args Arguments for operation.
*/
public static void main(final String[] args) {
String cmd = "";
String fileName = null;
String attestingOrgName = null;
String predicate = null;
String targetName = null;
String targetUrl = null;
String targetHash = null;
String affirmationStmt = null;
String affirmationWebsite = null;
boolean thirdParty = true;

for (int i = 0; i < args.length; i++) {
if (args[i].equals("--jsonFile")) {
fileName = args[++i];
useJson = true;
} else if (args[i].equals("--xmlFile")) {
fileName = args[++i];
useJson = false;
} else if (args[i].equals("--attesting-org-name")) {
attestingOrgName = args[++i];
} else if (args[i].equals("--predicate")) {
predicate = args[++i];
} else if (args[i].equals("--target-name")) {
targetName = args[++i];
} else if (args[i].equals("--target-url")) {
targetUrl = args[++i];
} else if (args[i].equals("--target-sha256-hash")) {
targetHash = args[++i];
} else if (args[i].equals("--affirmation-stmt")) {
affirmationStmt = args[++i];
} else if (args[i].equals("--affirmation-website")) {
affirmationWebsite = args[++i];
} else if (args[i].equals("--not-third-party")) {
thirdParty = false;
} else if (args[i].equals("--createNewCDXA")) {
cmd = "createCDXA";
} else if (args[i].equals("--verbose")) {
verbose = true;
}
}

switch (cmd) {
case "createCDXA": // Create a new CDXA json file
Bom bom = createCdxa(fileName, attestingOrgName, predicate, targetName, targetUrl, targetHash, affirmationStmt, affirmationWebsite, thirdParty);
if (bom != null) {
writeFile(bom, fileName);
} else {
System.exit(1);
}
break;

default:
System.out.println("Please enter a command.");
System.exit(1);
}
}

static Bom createCdxa(final String fileName, final String attestingOrgName, final String predicate,
final String targetName, final String targetUrl, final String targetHash,
final String affirmationStmt, final String affirmationWebsite, final boolean thirdParty) {
// Validate inputs
boolean validInput = true;
if (fileName == null) {
System.out.println("--xmlFile|--jsonFile not specified");
validInput = false;
}
if (attestingOrgName == null) {
System.out.println("--attesting-org-name not specified");
validInput = false;
}
if (predicate == null) {
System.out.println("--predicate not specified"); validInput = false;
} else {
boolean validPred = false;
for (CDXAPredicate validPredicate : CDXAPredicate.values()) {
if (validPredicate.name().equals(predicate)) {
validPred = true;
break;
}
}
if (!validPred) {
System.out.println("--predicate " + predicate + " not a valid value");
validInput = false;
}
}
if (targetName == null) {
System.out.println("--target-name not specified");
validInput = false;
}
if (targetUrl == null) {
System.out.println("--target-url not specified");
validInput = false;
}
if (targetHash == null) {
System.out.println("--target-sha256-hash not specified");
validInput = false;
}
if (affirmationStmt == null) {
System.out.println("--affirmation-stmt not specified");
validInput = false;
}
if (affirmationWebsite == null) {
System.out.println("--affirmation-website not specified");
validInput = false;
}
if (!validInput) {
return null;
}

Declarations declarations = new Declarations();
Assessor assessor = new Assessor();
Claim claim = new Claim();
Targets targets = new Targets();
Affirmation affirmation = new Affirmation();
Signatory signatory = new Signatory();
Attestation attestation = new Attestation();
AttestationMap attestationMap = new AttestationMap();

final String targetJdkBomRef = "target-jdk-1";
final String assessorBomRef = "assessor-1";
final String claimBomRef = "claim-1";

// External reference to the target JDK
ExternalReference extRef = new ExternalReference();
Hash hash1 = new Hash(Hash.Algorithm.SHA_256, targetHash);
extRef.addHash(hash1);
extRef.setUrl(targetUrl);
extRef.setType(ExternalReference.Type.DISTRIBUTION);

// Target JDK Component
Component targetJDK = new Component();
targetJDK.setType(Component.Type.APPLICATION);
targetJDK.setName(targetName);
targetJDK.addExternalReference(extRef);
targetJDK.setBomRef(targetJdkBomRef);
List<Component> components = new LinkedList<Component>();
components.add(targetJDK);
targets.setComponents(components);
declarations.setTargets(targets);

// Assessor
assessor.setThirdParty(thirdParty);
OrganizationalEntity org = new OrganizationalEntity();
org.setName(attestingOrgName);
assessor.setOrganization(org);
assessor.setBomRef(assessorBomRef);
List<Assessor> assessors = new LinkedList<Assessor>();
assessors.add(assessor);
declarations.setAssessors(assessors);

// Claim
claim.setPredicate(predicate);
claim.setTarget(targetJDK.getBomRef());
claim.setBomRef(claimBomRef);
List<Claim> claims = new LinkedList<Claim>();
claims.add(claim);
declarations.setClaims(claims);

// Affirmation
affirmation.setStatement(affirmationStmt);
signatory.setOrganization(org);
ExternalReference orgExtRef = new ExternalReference();
orgExtRef.setUrl(affirmationWebsite);
orgExtRef.setType(ExternalReference.Type.WEBSITE);
signatory.setExternalReference(orgExtRef);
List<Signatory> signatories = new LinkedList<Signatory>();
signatories.add(signatory);
affirmation.setSignatories(signatories);
declarations.setAffirmation(affirmation);

// Construct the Attestation
attestation.setSummary("Eclipse Temurin Attestation");
attestation.setAssessor(assessor.getBomRef());
List<String> claimsList = new LinkedList<String>();
claimsList.add(claim.getBomRef());
attestationMap.setClaims(claimsList);
List<AttestationMap> attestationMaps = new LinkedList<AttestationMap>();
attestationMaps.add(attestationMap);
attestation.setMap(attestationMaps);
List<Attestation> attestations = new LinkedList<Attestation>();
attestations.add(attestation);
declarations.setAttestations(attestations);

// Create CDXA Bom
Bom cdxa = new Bom();
cdxa.setSerialNumber("urn:uuid:" + UUID.randomUUID());
cdxa.setDeclarations(declarations);

return cdxa;
}

static String generateBomJson(final Bom bom) throws GeneratorException {
// Use schema v16: https://cyclonedx.org/schema/bom-1.6.schema.json
BomJsonGenerator bomGen = new BomJsonGenerator(bom, Version.VERSION_16);
String json = bomGen.toJsonString();
return json;
}

static String generateBomXml(final Bom bom) throws GeneratorException {
BomXmlGenerator bomGen = new BomXmlGenerator(bom, Version.VERSION_16);
String xml = bomGen.toXmlString();
return xml;
}

// Writes the BOM object to the specified type of file
static void writeFile(final Bom bom, final String fileName) {
if (useJson) {
writeJSONfile(bom, fileName);
} else {
writeXMLfile(bom, fileName);
}
}

// Writes the BOM object to the specified JSON file.
static void writeJSONfile(final Bom bom, final String fileName) {
FileWriter file;
try {
String json = generateBomJson(bom);

file = new FileWriter(fileName);
file.write(json);
file.close();
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}

// Writes the BOM object to the specified XML file.
static void writeXMLfile(final Bom bom, final String fileName) {
FileWriter file;
try {
String xml = generateBomXml(bom);

file = new FileWriter(fileName);
file.write(xml);
file.close();
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}

// Returns a parsed BOM object from the specified file.
static Bom readJSONfile(final String fileName) {
Bom bom = null;
try {
FileReader reader = new FileReader(fileName);
JsonParser parser = new JsonParser();
bom = parser.parse(reader);
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
} finally {
return bom;
}
}

// Returns a parsed BOM object from the specified file.
static Bom readXMLfile(final String fileName) {
Bom bom = null;
try {
FileReader reader = new FileReader(fileName);
XmlParser parser = new XmlParser();
bom = parser.parse(reader);
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
} finally {
return bom;
}
}
}
149 changes: 88 additions & 61 deletions cyclonedx-lib/src/temurin/sbom/TemurinGenSBOM.java
Original file line number Diff line number Diff line change
@@ -17,9 +17,9 @@

import org.cyclonedx.exception.GeneratorException;
import org.cyclonedx.generators.json.BomJsonGenerator;
import org.cyclonedx.generators.xml.BomXmlGenerator;
import org.cyclonedx.model.Bom;
import org.cyclonedx.model.Component;
import org.cyclonedx.model.ExternalReference;
import org.cyclonedx.model.formulation.Formula;
import org.cyclonedx.model.Hash;
import org.cyclonedx.model.Metadata;
@@ -28,19 +28,22 @@
import org.cyclonedx.model.Property;
import org.cyclonedx.model.Tool;
import org.cyclonedx.parsers.JsonParser;
import org.cyclonedx.parsers.XmlParser;
import org.cyclonedx.Version;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.Collections;
import java.util.List;
import java.util.LinkedList;
import java.util.UUID;

/**
* Command line tool to construct a CycloneDX SBOM.
*/
public final class TemurinGenSBOM {

private static boolean verbose = false;
private static boolean useJson = false;

private TemurinGenSBOM() {
}
@@ -50,7 +53,7 @@ private TemurinGenSBOM() {
* @param args Arguments for sbom operation.
*/
public static void main(final String[] args) {
String cmd = null;
String cmd = "";
String comment = null;
String compName = null;
String formulaName = null;
@@ -67,6 +70,10 @@ public static void main(final String[] args) {
for (int i = 0; i < args.length; i++) {
if (args[i].equals("--jsonFile")) {
fileName = args[++i];
useJson = true;
} else if (args[i].equals("--xmlFile")) {
fileName = args[++i];
useJson = false;
} else if (args[i].equals("--version")) {
version = args[++i];
} else if (args[i].equals("--name")) {
@@ -120,69 +127,60 @@ public static void main(final String[] args) {
}
}
switch (cmd) {
case "createNewSBOM": // Creates JSON file
case "createNewSBOM": // Creates new SBOM
Bom bom = createBom();
writeJSONfile(bom, fileName);
writeFile(bom, fileName);
break;

case "addMetadata": // Adds Metadata --> name
bom = addMetadata(fileName);
writeJSONfile(bom, fileName);
writeFile(bom, fileName);
break;

case "addMetadataComponent": // Adds Metadata --> Component --> name
bom = addMetadataComponent(fileName, name, type, version, description);
writeJSONfile(bom, fileName);
writeFile(bom, fileName);
break;

case "addMetadataProperty": // Adds MetaData --> Property --> name-value:
bom = addMetadataProperty(fileName, name, value);
writeJSONfile(bom, fileName);
writeFile(bom, fileName);
break;

case "addFormulation": // Adds Formulation --> name
bom = addFormulation(fileName, formulaName);
writeJSONfile(bom, fileName);
writeFile(bom, fileName);
break;

case "addFormulationComp": // Adds Formulation --> Component--> name
bom = addFormulationComp(fileName, formulaName, name, type);
writeJSONfile(bom, fileName);
writeFile(bom, fileName);
break;
case "addFormulationCompProp": // Adds Formulation --> Component -> name-value:
bom = addFormulationCompProp(fileName, formulaName, compName, name, value);
writeJSONfile(bom, fileName);
writeFile(bom, fileName);
break;

case "addMetadataTools":
bom = addMetadataTools(fileName, tool, version);
writeJSONfile(bom, fileName);
writeFile(bom, fileName);
break;

case "addComponent": // Adds Components --> Component --> name
bom = addComponent(fileName, compName, version, description);
writeJSONfile(bom, fileName);
writeFile(bom, fileName);
break;

case "addComponentHash": // Adds Components --> Component --> hash
bom = addComponentHash(fileName, compName, hash);
writeJSONfile(bom, fileName);
writeFile(bom, fileName);
break;

case "addComponentProp": // Adds Components --> Component --> name-value pairs
bom = addComponentProperty(fileName, compName, name, value);
writeJSONfile(bom, fileName);
break;

case "addExternalReference": // Adds external Reference
bom = addExternalReference(fileName, hash, url, comment);
writeJSONfile(bom, fileName);
writeFile(bom, fileName);
break;

case "addComponentExternalReference": // Adds external Reference to component
bom = addComponentExternalReference(fileName, hash, url, comment);
writeJSONfile(bom, fileName);
break;
default:
System.out.println("Please enter a command.");
}
@@ -194,12 +192,13 @@ public static void main(final String[] args) {
*/
static Bom createBom() {
Bom bom = new Bom();
bom.setSerialNumber("urn:uuid:" + UUID.randomUUID());
return bom;
}

// Method to store Metadata --> name.
static Bom addMetadata(final String fileName) {
Bom bom = readJSONfile(fileName);
Bom bom = readFile(fileName);
Metadata meta = new Metadata();
OrganizationalEntity org = new OrganizationalEntity();
org.setName("Eclipse Foundation");
@@ -213,7 +212,7 @@ static Bom addMetadata(final String fileName) {
}

static Bom addMetadataComponent(final String fileName, final String name, final String type, final String version, final String description) {
Bom bom = readJSONfile(fileName);
Bom bom = readFile(fileName);
Metadata meta = new Metadata();
Component comp = new Component();
Component.Type compType = Component.Type.FRAMEWORK;
@@ -235,7 +234,7 @@ static Bom addMetadataComponent(final String fileName, final String name, final

// Method to store Metadata --> Properties List --> name-values.
static Bom addMetadataProperty(final String fileName, final String name, final String value) {
Bom bom = readJSONfile(fileName);
Bom bom = readFile(fileName);
Metadata meta = new Metadata();
Property prop1 = new Property();
meta = bom.getMetadata();
@@ -247,7 +246,7 @@ static Bom addMetadataProperty(final String fileName, final String name, final S
}

static Bom addMetadataTools(final String fileName, final String toolName, final String version) {
Bom bom = readJSONfile(fileName);
Bom bom = readFile(fileName);
Metadata meta = new Metadata();
Tool tool = new Tool();
meta = bom.getMetadata();
@@ -260,7 +259,7 @@ static Bom addMetadataTools(final String fileName, final String toolName, final

// Method to store Component --> name & single name-value pair.
static Bom addComponent(final String fileName, final String compName, final String version, final String description) {
Bom bom = readJSONfile(fileName);
Bom bom = readFile(fileName);
Component comp = new Component();
comp.setName(compName);
comp.setVersion(version);
@@ -274,7 +273,7 @@ static Bom addComponent(final String fileName, final String compName, final Stri
}

static Bom addComponentHash(final String fileName, final String compName, final String hash) {
Bom bom = readJSONfile(fileName);
Bom bom = readFile(fileName);
List<Component> componentArrayList = bom.getComponents();
for (Component item : componentArrayList) {
if (item.getName().equals(compName)) {
@@ -287,7 +286,7 @@ static Bom addComponentHash(final String fileName, final String compName, final

// Method to add Component --> Property --> name-value pairs.
static Bom addComponentProperty(final String fileName, final String compName, final String name, final String value) {
Bom bom = readJSONfile(fileName);
Bom bom = readFile(fileName);
List<Component> componentArrayList = bom.getComponents();
for (Component item : componentArrayList) {
if (item.getName().equals(compName)) {
@@ -300,36 +299,8 @@ static Bom addComponentProperty(final String fileName, final String compName, fi
return bom;
}

// Method to store externalReferences: dependency_version_alsa.
static Bom addExternalReference(final String fileName, final String hash, final String url, final String comment) {
Bom bom = readJSONfile(fileName);
ExternalReference extRef = new ExternalReference();
Hash hash1 = new Hash(Hash.Algorithm.SHA3_256, hash);
extRef.setType(ExternalReference.Type.BUILD_SYSTEM); //required
extRef.setUrl(url); // required must be a valid URL with protocol
extRef.setComment(comment);
extRef.addHash(hash1);
bom.addExternalReference(extRef);
return bom;
}

// Method to store externalReferences to store: openjdk_source.
static Bom addComponentExternalReference(final String fileName, final String hash, final String url, final String comment) {
Bom bom = readJSONfile(fileName);
ExternalReference extRef = new ExternalReference();
Hash hash1 = new Hash(Hash.Algorithm.SHA3_256, hash);
Component comp = new Component();
extRef.addHash(hash1);
extRef.setUrl(url);
extRef.setComment(comment); //"openjdk_source"
extRef.setType(ExternalReference.Type.BUILD_SYSTEM);
comp.addExternalReference(extRef);
bom.addComponent(comp);
return bom;
}

static Bom addFormulation(final String fileName, final String name) {
Bom bom = readJSONfile(fileName);
Bom bom = readFile(fileName);
List<Formula> formulation = bom.getFormulation();
if (formulation == null) {
formulation = new LinkedList<Formula>();
@@ -343,7 +314,7 @@ static Bom addFormulation(final String fileName, final String name) {
}

static Bom addFormulationComp(final String fileName, final String formulaName, final String name, final String type) {
Bom bom = readJSONfile(fileName);
Bom bom = readFile(fileName);
if (formulaName == null) {
System.out.println("addFormulationComp: formulaName is null");
return bom;
@@ -376,7 +347,7 @@ static Bom addFormulationComp(final String fileName, final String formulaName, f
}

static Bom addFormulationCompProp(final String fileName, final String formulaName, final String componentName, final String name, final String value) {
Bom bom = readJSONfile(fileName);
Bom bom = readFile(fileName);
boolean foundFormula = false;
boolean foundComponent = false;
List<Formula> formulation = bom.getFormulation();
@@ -417,6 +388,32 @@ static String generateBomJson(final Bom bom) throws GeneratorException {
return json;
}

static String generateBomXml(final Bom bom) throws GeneratorException {
BomXmlGenerator bomGen = new BomXmlGenerator(bom, Version.VERSION_16);
String xml = bomGen.toXmlString();
return xml;
}

// Writes the BOM object to the specified type of file
static void writeFile(final Bom bom, final String fileName) {
if (useJson) {
writeJSONfile(bom, fileName);
} else {
writeXMLfile(bom, fileName);
}
}

// Read the BOM object from the specified type of file
static Bom readFile(final String fileName) {
Bom bom;
if (useJson) {
bom = readJSONfile(fileName);
} else {
bom = readXMLfile(fileName);
}
return bom;
}

// Writes the BOM object to the specified file.
static void writeJSONfile(final Bom bom, final String fileName) {
FileWriter file;
@@ -432,6 +429,21 @@ static void writeJSONfile(final Bom bom, final String fileName) {
}
}

// Writes the BOM object to the specified XML file.
static void writeXMLfile(final Bom bom, final String fileName) {
FileWriter file;
try {
String xml = generateBomXml(bom);

file = new FileWriter(fileName);
file.write(xml);
file.close();
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}

// Returns a parsed BOM object from the specified file.
static Bom readJSONfile(final String fileName) {
Bom bom = null;
@@ -446,4 +458,19 @@ static Bom readJSONfile(final String fileName) {
return bom;
}
}

// Returns a parsed BOM object from the specified file.
static Bom readXMLfile(final String fileName) {
Bom bom = null;
try {
FileReader reader = new FileReader(fileName);
XmlParser parser = new XmlParser();
bom = parser.parse(reader);
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
} finally {
return bom;
}
}
}
12 changes: 12 additions & 0 deletions sbin/build.sh
Original file line number Diff line number Diff line change
@@ -174,6 +174,17 @@ configureMacOSCodesignParameter() {
fi
}

# JDK 24+ includes JEP 493 which allows for the JDK to enable
# linking from the run-time image (instead of only from JMODs). Enable
# this option. This has the effect, that no 'jmods' directory will be
# produced in the resulting build. Thus, the tarball and, especially the
# extracted tarball will be smaller in terms of disk space size.
configureLinkableRuntimeParameter() {
if [[ "${BUILD_CONFIG[OPENJDK_FEATURE_NUMBER]}" -ge 24 ]]; then
addConfigureArg "--enable-linkable-runtime" ""
fi
}

# Get the OpenJDK update version and build version
getOpenJDKUpdateAndBuildVersion() {
cd "${BUILD_CONFIG[WORKSPACE_DIR]}/${BUILD_CONFIG[WORKING_DIR]}"
@@ -574,6 +585,7 @@ configureCommandParameters() {
configureVersionStringParameter
configureBootJDKConfigureParameter
configureDevKitConfigureParameter
configureLinkableRuntimeParameter
configureShenandoahBuildParameter
configureMacOSCodesignParameter
configureDebugParameters
15 changes: 0 additions & 15 deletions sbin/common/sbom.sh
Original file line number Diff line number Diff line change
@@ -205,18 +205,3 @@ addSBOMComponentPropertyFromFile() {
fi
}

# Function not in use
# Ref: https://cyclonedx.org/docs/1.4/json/#externalReferences
addExternalReference() {
local javaHome="${1}"
local classpath="${2}"
local jsonFile="${3}"
local url="${4}" # required
local comment="${5}"
local hash="${6}"
if [ -z "${hash}" ]; then
"${javaHome}"/bin/java -cp "${classpath}" temurin.sbom.TemurinGenSBOM --addExternalReference --jsonFile "${jsonFile}" --url "${url}" --comment "${comment}" --hash "${hash}"
else
"${javaHome}"/bin/java -cp "${classpath}" temurin.sbom.TemurinGenSBOM --addExternalReference --jsonFile "${jsonFile}" --url "${url}" --comment "${comment}"
fi
}
Original file line number Diff line number Diff line change
@@ -15,12 +15,15 @@

package net.adoptium.test;

import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.logging.Logger;
import java.util.regex.Pattern;

import static net.adoptium.test.JdkPlatform.Architecture;
import static net.adoptium.test.JdkPlatform.OperatingSystem;
@@ -40,6 +43,71 @@ public class FeatureTests {

private final JdkPlatform jdkPlatform = new JdkPlatform();

private String testJdkHome = null;

/**
* Ensure TEST_JDK_HOME environment variable is set for every test in this class.
*/
@BeforeTest
public final void ensureTestJDKSet() {
String tmpJdkHome = System.getenv("TEST_JDK_HOME");
if (tmpJdkHome == null) {
throw new AssertionError("TEST_JDK_HOME is not set");
}
this.testJdkHome = tmpJdkHome;
}

/**
* Tests whether JEP 493 is enabled for Eclipse Temurin builds.
*
* @see <a href="https://openjdk.java.net/jeps/493">JEP 493: Linking Run-Time Images without JMODs</a>
*/
@Test
public void testLinkableRuntimeJDK24Plus() {
// Only JDK 24 and better and temurin builds have this enabled
if (jdkVersion.isNewerOrEqual(24) && isVendorAdoptium()) {
List<String> command = new ArrayList<>();
command.add(String.format("%s/bin/jlink", testJdkHome));
command.add("-J-Duser.lang=en");
command.add("--help");

try {
ProcessBuilder processBuilder = new ProcessBuilder(command);
Process process = processBuilder.start();

String stdout = StreamUtils.consumeStream(process.getInputStream());
if (process.waitFor() != 0) {
throw new AssertionError("Could not run jlink --help");
}
String[] lines = stdout.split(Pattern.quote(System.lineSeparator()));
boolean seenCapabilities = false;
String capLine = "";
for (int i = 0; i < lines.length; i++) {
if (lines[i].trim().startsWith("Capabilities:")) {
seenCapabilities = true;
continue; // skip Capabilities line
}
if (!seenCapabilities) {
continue;
}
if (seenCapabilities) {
capLine = lines[i].trim();
break;
}
}
LOGGER.info(String.format("Matched 'Capabilities:' line: %s", capLine));
assertEquals(capLine, "Linking from run-time image enabled",
"jlink should have enabled run-time image link capability");
} catch (InterruptedException | IOException e) {
throw new RuntimeException("Failed to launch JVM", e);
}
}
}

private boolean isVendorAdoptium() {
return System.getProperty("java.vendor", "").toLowerCase(Locale.US).contains("adoptium");
}

/**
* Tests whether Shenandoah GC is available.
* <p/>
@@ -53,10 +121,6 @@ public class FeatureTests {
*/
@Test
public void testShenandoahAvailable() {
String testJdkHome = System.getenv("TEST_JDK_HOME");
if (testJdkHome == null) {
throw new AssertionError("TEST_JDK_HOME is not set");
}

boolean shouldBePresent = false;
if ((jdkVersion.isNewerOrEqual(15) || jdkVersion.isNewerOrEqualSameFeature(11, 0, 9))) {
@@ -73,7 +137,7 @@ public void testShenandoahAvailable() {
}
}
if (jdkVersion.isNewerOrEqual(17) && jdkPlatform.runsOn(OperatingSystem.LINUX, Architecture.PPC64LE)) {
shouldBePresent = true;
shouldBePresent = true;
}
if (jdkVersion.isNewerOrEqual(19)
|| jdkVersion.isNewerOrEqualSameFeature(17, 0, 9)
@@ -116,10 +180,6 @@ public void testShenandoahAvailable() {
*/
@Test
public void testZGCAvailable() {
String testJdkHome = System.getenv("TEST_JDK_HOME");
if (testJdkHome == null) {
throw new AssertionError("TEST_JDK_HOME is not set");
}

boolean shouldBePresent = false;
if (jdkVersion.isNewerOrEqual(15)) {
@@ -184,10 +244,6 @@ public void testZGCAvailable() {
*/
@Test
public void testJFRAvailable() {
String testJdkHome = System.getenv("TEST_JDK_HOME");
if (testJdkHome == null) {
throw new AssertionError("TEST_JDK_HOME is not set");
}
boolean shouldBePresent = false;
if (jdkVersion.isNewerOrEqual(11) || jdkVersion.isNewerOrEqualSameFeature(8, 0, 262)) {
if (!jdkPlatform.runsOn(OperatingSystem.AIX) || jdkVersion.isNewerOrEqual(20)) {
@@ -213,4 +269,5 @@ public void testJFRAvailable() {
throw new RuntimeException("Failed to launch JVM", e);
}
}

}
1 change: 1 addition & 0 deletions tooling/build_autotriage/build_autotriage.sh
Original file line number Diff line number Diff line change
@@ -59,6 +59,7 @@ temurinPlatforms+=("mac-aarch64"); platformStart+=(11); platformEnd+=(9
temurinPlatforms+=("mac-x64"); platformStart+=(8); platformEnd+=(99)
temurinPlatforms+=("solaris-sparcv9"); platformStart+=(8); platformEnd+=(8)
temurinPlatforms+=("solaris-x64"); platformStart+=(8); platformEnd+=(8)
temurinPlatforms+=("windows-aarch64"); platformStart+=(21); platformEnd+=(99)
temurinPlatforms+=("windows-x64"); platformStart+=(8); platformEnd+=(99)
temurinPlatforms+=("windows-x86-32"); platformStart+=(8); platformEnd+=(17)

0 comments on commit 14d9387

Please sign in to comment.