diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cec6c6661..76b72b2d5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,24 +7,16 @@ name: Release on: push: tags: - - 'v[0-9]+.[0-9]+.[0-9]+' - - 'v[0-9]+.[0-9]+.[0-9]+-*' + - "v[0-9]+.[0-9]+.[0-9]+" + - "v[0-9]+.[0-9]+.[0-9]+-*" workflow_dispatch: -jobs: - test: - uses: ./.github/workflows/test.yml +env: + IMAGE_NAME: ${{ github.repository_owner }}/fabric-javaenv - # Publishing steps to both the Github Packages and the Sonatype - publishjars: - strategy: - fail-fast: false - matrix: - publish_target: - - publishAllPublicationsToGithubPackagesRepository - - publishAllPublicationsToReleaseRepository +jobs: + publish-github: runs-on: ubuntu-latest - needs: test permissions: contents: read packages: write @@ -32,74 +24,139 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-java@v4 with: - distribution: 'temurin' + distribution: "temurin" java-version: 21 - uses: gradle/actions/setup-gradle@v4 - - name: Push to registry ${{ matrix.publish_target }} + - name: Publish to GitHub Packages run: | - set -xev - ./gradlew -Psigning.key="${SIGNING_KEY}" -Psigning.password="${SIGNING_PASSWORD}" -PossrhUsername="${OSSRH_USER}" -PossrhPassword="${OSSRH_PASSWORD}" ${TARGET} + ./gradlew publishAllPublicationsToGitHubRepository env: - SIGNING_PASSWORD: ${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }} - SIGNING_KEY: ${{ secrets.OSSRH_GPG_SECRET_KEY }} - OSSRH_USER: ${{ secrets.OSSRH_USERNAME }} - OSSRH_PASSWORD: ${{ secrets.OSSRH_TOKEN }} - TARGET: ${{ matrix.publish_target }} + ORG_GRADLE_PROJECT_signingKey: ${{ secrets.OSSRH_GPG_SECRET_KEY }} + ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # Publish to docker registries docker.io and ghcr.io - publishdocker: - strategy: - fail-fast: false - matrix: - DOCKER_REGISTRY: - - 'docker.io' - - 'ghcr.io' + publish-maven: runs-on: ubuntu-latest - needs: test + permissions: + contents: read + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + distribution: "temurin" + java-version: 21 + - uses: gradle/actions/setup-gradle@v4 + - name: Publish to Maven Central + run: | + ./gradlew publishAllPublicationsToStagingRepository + ./gradlew jreleaserDeploy --stacktrace + env: + ORG_GRADLE_PROJECT_signingKey: ${{ secrets.OSSRH_GPG_SECRET_KEY }} + ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }} + JRELEASER_MAVENCENTRAL_USERNAME: ${{ secrets.MAVENCENTRAL_USERNAME }} + JRELEASER_MAVENCENTRAL_PASSWORD: ${{ secrets.MAVENCENTRAL_PASSWORD }} + + docker-build-push: + name: Push Docker image + runs-on: ${{ matrix.arch.runner }} permissions: contents: read packages: write + strategy: + fail-fast: false + matrix: + arch: + - platform: linux-amd64 + runner: ubuntu-24.04 + - platform: linux-arm64 + runner: ubuntu-24.04-arm steps: - uses: actions/checkout@v4 - uses: actions/setup-java@v4 with: - distribution: 'temurin' + distribution: "temurin" java-version: 21 - uses: gradle/actions/setup-gradle@v4 - name: Build the dependencies needed for the image run: ./gradlew :fabric-chaincode-docker:copyAllDeps - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + - name: Get commit timestamp + run: echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> "${GITHUB_ENV}" + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + registry: docker.io + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 + - name: Build image + id: build + uses: docker/build-push-action@v6 + with: + file: fabric-chaincode-docker/Dockerfile + context: fabric-chaincode-docker + outputs: type=registry,"name=${{ format('ghcr.io/{0},docker.io/{0}', env.IMAGE_NAME) }}",push-by-digest=true,name-canonical=true + env: + SOURCE_DATE_EPOCH: ${{ env.SOURCE_DATE_EPOCH }} + - name: Export digest + run: | + mkdir -p ${{ runner.temp }}/digests + digest="${{ steps.build.outputs.digest }}" + touch "${{ runner.temp }}/digests/${digest#sha256:}" + - name: Upload digest + uses: actions/upload-artifact@v4 with: - buildkitd-flags: --debug - buildkitd-config-inline: | - [worker.oci] - max-parallelism = 1 - - name: Login to the ${{ matrix.DOCKER_REGISTRY }} Container Registry + name: digest-${{ matrix.arch.platform }} + path: ${{ runner.temp }}/digests/* + if-no-files-found: error + + docker-meta: + needs: docker-build-push + name: Publish Docker metadata + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + strategy: + fail-fast: false + matrix: + registry: + - docker.io + - ghcr.io + steps: + - name: Download digests + uses: actions/download-artifact@v4 + with: + path: ${{ runner.temp }}/digests + pattern: digest-* + merge-multiple: true + - name: Login to ${{ matrix.registry }} uses: docker/login-action@v3 with: - registry: ${{ matrix.DOCKER_REGISTRY }} - username: ${{ matrix.DOCKER_REGISTRY == 'docker.io' && secrets.DOCKERHUB_USERNAME || github.actor }} - password: ${{ matrix.DOCKER_REGISTRY == 'docker.io' && secrets.DOCKERHUB_TOKEN || secrets.GITHUB_TOKEN }} - - name: Docker meta + registry: ${{ matrix.registry }} + username: ${{ matrix.registry == 'docker.io' && secrets.DOCKERHUB_USERNAME || github.actor }} + password: ${{ matrix.registry == 'docker.io' && secrets.DOCKERHUB_TOKEN || secrets.GITHUB_TOKEN }} + - name: Docker metadata id: meta uses: docker/metadata-action@v5 with: - images: ${{ matrix.DOCKER_REGISTRY }}/${{ github.repository_owner }}/fabric-javaenv + images: ${{ matrix.registry }}/${{ env.IMAGE_NAME }} tags: | type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{major}}.{{minor}}.{{patch}} - - name: Build and push image - id: push - uses: docker/build-push-action@v5 - with: - platforms: linux/amd64,linux/arm64 - file: fabric-chaincode-docker/Dockerfile - context: fabric-chaincode-docker - tags: ${{ steps.meta.outputs.tags }} - push: ${{ github.event_name != 'pull_request' }} - labels: ${{ steps.meta.outputs.labels }} + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Create and push manifest list + working-directory: ${{ runner.temp }}/digests + run: | + docker buildx imagetools create $(jq -cr '.tags | map("--tag " + .) | join(" ")' <<< "${DOCKER_METADATA_OUTPUT_JSON}") \ + $(printf '${{ matrix.registry }}/${{ env.IMAGE_NAME }}@sha256:%s ' *) + - name: Inspect image + run: docker buildx imagetools inspect '${{ matrix.registry }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}' diff --git a/.github/workflows/scan.yml b/.github/workflows/scan.yml index 3bf42b58f..b0754fd5d 100644 --- a/.github/workflows/scan.yml +++ b/.github/workflows/scan.yml @@ -19,15 +19,14 @@ jobs: - uses: actions/checkout@v4 with: ref: ${{ inputs.ref }} + - uses: actions/setup-go@v5 # Needed for scanning of v2.5.5 and earlier + with: + go-version: stable + cache: false - uses: actions/setup-java@v4 with: distribution: temurin java-version: 21 - uses: gradle/actions/setup-gradle@v4 - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: stable - cache: false - name: Scan run: make scan diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 942cc24f0..9d45c2a4e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,7 +8,7 @@ on: workflow_call: inputs: ref: - default: '' + default: "" required: false type: string @@ -16,16 +16,16 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - with: - ref: ${{ inputs.ref }} - - uses: actions/setup-java@v4 - with: - distribution: temurin - java-version: 21 - - uses: gradle/actions/setup-gradle@v4 - - name: Build and Unit test - run: ./gradlew :fabric-chaincode-shim:build + - uses: actions/checkout@v4 + with: + ref: ${{ inputs.ref }} + - uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 21 + - uses: gradle/actions/setup-gradle@v4 + - name: Build and Unit test + run: ./gradlew :fabric-chaincode-shim:build intergationtest: runs-on: ubuntu-latest @@ -37,6 +37,9 @@ jobs: with: distribution: temurin java-version: 21 + - uses: actions/setup-node@v4 + with: + node-version: "lts/*" - uses: gradle/actions/setup-gradle@v4 - name: Populate chaincode with latest java-version run: | @@ -49,7 +52,7 @@ jobs: run: | curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/main/scripts/install-fabric.sh | bash -s -- binary npm install -g @hyperledger-labs/weft - + # set the path and cfg env var for the rest of the step echo "FABRIC_CFG_PATH=$GITHUB_WORKSPACE/config" >> $GITHUB_ENV echo "$GITHUB_WORKSPACE/bin" >> $GITHUB_PATH diff --git a/COMPATIBILITY.md b/COMPATIBILITY.md index 6c1708b61..57924e508 100644 --- a/COMPATIBILITY.md +++ b/COMPATIBILITY.md @@ -1,68 +1,40 @@ -# Support and Compatibility for fabric-chaincode-java - -Github is used for code base management, issues should reported in the [FABCJ](https://jira.hyperledger.org/projects/FABCJ/issues/) component in JIRA. +# Support and Compatibility +Github is used for code base management and issue tracking. ## Summary of Compatibility -This table shows the summary of the compatibility of the Java libraries, together with the JVM version they require and the Fabric Peer versions they can communicate with. - -| | Fabric Peer v1.4 connectivity | Java 8 VM | Fabric Peer v2.2/2.5 Connectivity | Java 11 VM | -| ----------------------- | ----------------------------- | --------- | ----------------------------- | ---------- | -| Java libraries **v1.4** | Yes | Yes | Yes | Yes | -| Java libraries **v2.1** | Yes | No | Yes | Yes | -| Java libraries **v2.4** | Yes | No | Yes | Yes | -| Java libraries **v2.5** | Yes | No | Yes | Yes | - - -Testing is performed with - - Java v8: OpenJDK - - Java v11: Eclipse Temurin (this has changed from OpenJDK) - - -By default a Fabric Peer v1.4 will create a Java 8 VM, and a Fabric Peer v2.x will create a Java 11 VM. Whilst is the default, the docker image used to host the chaincode and contracts can be altered. Set the environment variable `CORE_CHAINCODE_JAVA_RUNTIME` on the peer to the name of the docker image. For example `CORE_CHAINCODE_JAVA_RUNTIME=example/customJavaRuntime:latest` - -The Java Libraries will connect to the peer whilst running; this is referred to as 'Fabric Peer Connectivity' in the table. For example, whilst the Fabric Peer v1.4 will create a Java 8 environment, if a Java 11 environment was configured, the Java Libraries at v2.5 still function when connecting to the Fabric Peer v1.4. - -## Compatibility - -The key elements are: - -- the version of the Fabric Contract Java libraries used -- the version of the JVM used to run the code -- When starting a chaincode container to run a Smart Contract the version of the runtime that is used is determined by these factors: - -Fabric v1.4.2, and Fabric v2.5.x will, by default, start up docker image to host the chaincode and contracts. The version of the docker image used is defined by the version of Fabric in use. - -With Fabric v2.1.0 and later, the chaincode container can be configured to be started by different chaincode builders, and not the Peer. In this case, the environment used is not in the control of Fabric. +This table shows the summary of the compatibility of the Java chaincode libraries, together with the JVM version they require. -The Java libraries are produced are `group: 'org.hyperledger.fabric-chaincode-java', name: 'fabric-chaincode-shim'` +| Java chaincode version | Minimum supported Java | Java runtime | Docker image platforms | +|------------------------|------------------------|--------------|------------------------| +| v1.4 | 8 | 8 | amd64 | +| v2.2 | 11 | 11 | amd64 | +| v2.5.0 - v2.5.4 | 11 | 11 | amd64, arm64 | +| v2.5.5+ | 11 | 21 | amd64, arm64 | -### Supported JVMs +The Java runtime provided by the chaincode Docker image determines the maximum Java version (and features) that smart contract code can exploit when using the default Java chaincode container. -v1.4.x and v2.5.x Java Libraries are supported running in Java 11 with the x86_64 architecture. Later Java 11 versions are supported but are not tested. +Subject to a suitable runtime environment, the Java chaincode libraries can be used to communicate with Fabric peers at different LTS versions. The level of functionality is determined by the Fabric version in use and channel capabilities. -v1.4.x Java Libraries are supported running in Java 8 with the x86_64 architecture. Later Java 8 versions are supported but are not tested. +All Docker images, chaincode libraries and tools are tested using amd64 (x86-64) only. -Architecture Support: all docker images, JVMs, tools are tested under x86_64 ONLY +## Chaincode builder +The default Fabric chaincode builder creates a Docker container to run deployed smart contracts. Java chaincode Docker containers are built using the `hyperledger/fabric-javaenv` Docker image, tagged with the same major and minor version as the Fabric peer version. For example, Fabric v2.5 creates Java chaincode containers using the `hyperledger/fabric-javaenv:2.5` Docker image. Fabric v3 continues to use the v2.5 Java chaincode image. -### Default Peer Runtime selection +A different chaincode Docker image can be specified using the `CORE_CHAINCODE_JAVA_RUNTIME` environment variable on the Fabric peer. For example, `CORE_CHAINCODE_JAVA_RUNTIME=example/customJavaRuntime:latest`. -When using Fabric v2.5, the default docker image that is used to run the Java chaincode is *eclipse-temurin:11.0.21_9-jdk* +With Fabric v2 and later, an alternative chaincode builder can be configured on the Fabric peer. In this case the configured chaincode builder controls how chaincode is launched. See the [Fabric documentation](https://hyperledger-fabric.readthedocs.io/en/release-2.5/cc_launcher.html) for further details. -With the default docker image used by Fabric v2.5, if the packaged Java code contains a build script or a wrapper for either Maven or Gradle, it will be built using Gradle 7.0 wrapper, or Maven 3.8.1 wrapper. +## Chaincode packaging - - If both Gradle and Maven files are present Gradle is used. - - Gradle build files can be groovy, or kotlin. - - If the Gradle or Maven wrappers are present, this will used in preference to the installed wrappers. - -Remember that when using the wrappers, code will be downloaded from the internet. Keep this in mind for any installation with limited or no internet access. - -Alternatively it is recommended to package prebuilt jar files, including the contract and all dependencies, in which case no build or Internet access is required when installing Java chaincode. +When using the `hyperledger/fabric-javaenv` Java chaincode Docker images, deployed chaincode is built as follows: -Please check the [Dockerfile](./fabric-chaincode-docker/Dockerfile) that is used for the environment to see exactly how these versions are installed. +- If both Gradle and Maven files are present, Gradle is used. +- Gradle build files can be either Groovy or Kotlin. +- If Gradle or Maven wrappers are present, they will be used instead of the preinstalled Gradle or Maven versions. -### Supported Runtime communication with the Peer +Remember that when using the wrappers, code will be downloaded from the Internet. Keep this in mind for any installation with limited network access. -Subject to a suitable runtime environment, the 1.4 and 2.5 Java Libraries can used to communicate with Fabric Peers at 2.5 and previous LTS versions. The level of functionality that is implied by the Fabric version in use and channel capabilities. +Alternatively, it is recommended to package prebuilt JAR files, including the smart contract and all dependencies. In this case, no Internet access is required when deploying Java chaincode. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d872b5bc1..20f0f0d13 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,29 +2,29 @@ We welcome contributions to the [Hyperledger Fabric](https://hyperledger-fabric.readthedocs.io) Project. There's always plenty to do! -If you have any questions about the project or how to contribute, you can find us in the [fabric-contracts-api](https://discordapp.com/channels/905194001349627914/943090527920877598) channel on Discord. +If you have any questions about the project or how to contribute, you can find us in the [fabric-contracts-api](https://discordapp.com/channels/905194001349627914/943090527920877598) channel on [Discord](https://discord.lfdecentralizedtrust.org/). Here are a few guidelines to help you contribute successfully... ## Issues -All issues are tracked in the issues tab in github. If you find a bug which we don't already know about, you can help us by creating a new issue describing the problem. Please include as much detail as possible to help us track down the cause.If you want to begin contributing code, looking through our open issues is a good way to start. Try looking for recent issues with detailed descriptions first, or ask us on Discord if you're unsure which issue to choose. +All issues are tracked in the issues tab in GitHub. If you find a bug which we don't already know about, you can help us by creating a new issue describing the problem. Please include as much detail as possible to help us track down the cause.If you want to begin contributing code, looking through our open issues is a good way to start. Try looking for recent issues with detailed descriptions first, or ask us on Discord if you're unsure which issue to choose. ## Enhancements -Make sure you have the support of the Hyperledger Fabric community before investing a lot of effort in project enhancements. Please look up the Fabric RFC process for large changes. +Make sure you have the support of the Hyperledger Fabric community before investing a lot of effort in project enhancements. Please look up the [Fabric RFC](https://github.com/hyperledger/fabric-rfcs) process for large changes. ## Pull Requests -We use our own forks and [Github Flow](https://guides.github.com/introduction/flow/index.html) to deliver changes to the code. Follow these steps to deliver your first pull request: +We use our own forks and [Github Flow](https://docs.github.com/en/get-started/using-github/github-flow) to deliver changes to the code. Follow these steps to deliver your first pull request: -1. [Fork the repository](https://guides.github.com/activities/forking/#fork) and create a new branch from `main`. +1. [Fork the repository](https://docs.github.com/en/get-started/exploring-projects-on-github/contributing-to-a-project) and create a new branch from `main`. 2. If you've added code that should be tested, add tests! 3. If you've added any new features or made breaking changes, update the documentation. 4. Ensure all the tests pass. -5. Include the JIRA issue number, a descriptive message, and the [Developer Certificate of Origin (DCO) sign-off](https://github.com/probot/dco#how-it-works) on all commit messages. -6. [Issue a pull request](https://guides.github.com/activities/forking/#making-a-pull-request)! -7. [Azure DevOps](https://dev.azure.com/Hyperledger/Fabric-Chaincode-Java) builds must succeed before the pull request can be reviewed and merged. +5. Include the JIRA issue number, a descriptive message, and the [Developer Certificate of Origin (DCO) sign-off](https://github.com/dcoapp/app#how-it-works) on all commit messages. +6. [Issue a pull request](https://docs.github.com/en/get-started/exploring-projects-on-github/contributing-to-a-project#making-a-pull-request)! +7. [GitHub Actions](https://github.com/hyperledger/fabric-chaincode-java/actions) builds must succeed before the pull request can be reviewed and merged. ## Coding Style diff --git a/Makefile b/Makefile index f8f60fbfc..44118a94c 100644 --- a/Makefile +++ b/Makefile @@ -2,8 +2,29 @@ # SPDX-License-Identifier: Apache-2.0 # -.PHONEY: scan -scan: - go install github.com/google/osv-scanner/cmd/osv-scanner@latest - ./gradlew --quiet resolveAndLockAll --write-locks - osv-scanner scan --lockfile=fabric-chaincode-shim/gradle.lockfile +bin_dir := bin +osv-scanner := $(bin_dir)/osv-scanner + +kernel_name := $(shell uname -s | tr '[:upper:]' '[:lower:]') +machine_hardware := $(shell uname -m) +ifeq ($(machine_hardware), x86_64) + machine_hardware := amd64 +endif +ifeq ($(machine_hardware), aarch64) + machine_hardware := arm64 +endif + +.PHONY: scan +scan: $(osv-scanner) + ./gradlew --quiet :fabric-chaincode-shim:dependencies --write-locks --configuration runtimeClasspath + bin/osv-scanner scan --lockfile=fabric-chaincode-shim/gradle.lockfile + +.PHONY: install-osv-scanner +install-osv-scanner: + mkdir -p '$(bin_dir)' + curl --fail --location --show-error --silent --output '$(osv-scanner)' \ + 'https://github.com/google/osv-scanner/releases/latest/download/osv-scanner_$(kernel_name)_$(machine_hardware)' + chmod u+x '$(osv-scanner)' + +$(osv-scanner): + $(MAKE) install-osv-scanner diff --git a/RELEASING.md b/RELEASING.md index 16288ffc0..7550061e5 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -3,9 +3,9 @@ The following artifacts are created as a result of releasing Fabric Chaincode Java: - docker images - - [fabric-javaenv](https://hub.docker.com/r/hyperledger/fabric-javaenv) + - [fabric-javaenv](https://hub.docker.com/r/hyperledger/fabric-javaenv) - Java libraries - - [fabric-chaincode-shim](https://search.maven.org/search?q=a:fabric-chaincode-shim) + - [fabric-chaincode-shim](https://search.maven.org/search?q=a:fabric-chaincode-shim) **Note:** A docker image with a matching V.R version is required before releasing a new version of Fabric. @@ -17,10 +17,12 @@ The following tasks are required before releasing: - Update version numbers in `build.gradle` files to the required version - Update test, sample, and docs files to match the new version -- Update the [`COMPATIBILITY.md`](./COMPATIBILITY.md) +- Update the [`COMPATIBILITY.md`](./COMPATIBILITY.md) See the [[FABCJ-289] release: 2.2.0 LTS](https://github.com/hyperledger/fabric-chaincode-java/pull/124) pull request for an example, although be careful to search for all versions in the codebase as they're easy to miss and things change! +Ensure the last branch build passed since exactly this repository state will be released. + ## Create release Creating a GitHub release on the [releases page](https://github.com/hyperledger/fabric-chaincode-java/releases) will trigger the build to publish the new release. @@ -57,6 +59,7 @@ See the [Bump version to 2.2.1](https://github.com/hyperledger/fabric-chaincode- ## Interim Build Publishing The nightly Azure Pipeline Builds will also publish the 'dev' drivers to Artifactory. These can be accessed via the repository at + ``` maven { url "https://hyperledger.jfrog.io/hyperledger/fabric-maven" diff --git a/build.gradle b/build.gradle index 654a4d7f5..d0be9fd6c 100644 --- a/build.gradle +++ b/build.gradle @@ -5,11 +5,11 @@ */ plugins { - id "com.github.ben-manes.versions" version "0.51.0" - id "com.diffplug.spotless" version "6.25.0" + id "com.github.ben-manes.versions" version "0.52.0" + id "com.diffplug.spotless" version "7.0.4" } -version = '2.5.5' +version = '2.5.6' // If the nightly property is set, then this is the scheduled main @@ -28,15 +28,13 @@ allprojects { repositories { mavenCentral() - maven { url "https://oss.sonatype.org/content/repositories/snapshots" } - maven { url "https://www.jitpack.io" } } spotless { format 'misc', { target '*.gradle', '.gitattributes', '.gitignore' trimTrailingWhitespace() - indentWithSpaces() + leadingTabsToSpaces() endWithNewline() } } @@ -62,14 +60,14 @@ subprojects { dependencies { implementation 'commons-cli:commons-cli:1.9.0' - implementation 'commons-logging:commons-logging:1.3.4' + implementation 'commons-logging:commons-logging:1.3.5' - testImplementation platform('org.junit:junit-bom:5.11.3') + testImplementation platform('org.junit:junit-bom:5.13.1') testImplementation 'org.junit.jupiter:junit-jupiter' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' - testImplementation 'org.assertj:assertj-core:3.26.3' - testImplementation 'org.mockito:mockito-core:5.14.2' - testImplementation 'uk.org.webcompere:system-stubs-jupiter:2.1.7' + testImplementation 'org.assertj:assertj-core:3.27.3' + testImplementation 'org.mockito:mockito-core:5.18.0' + testImplementation 'uk.org.webcompere:system-stubs-jupiter:2.1.8' testImplementation 'org.hamcrest:hamcrest-library:3.0' } @@ -81,7 +79,7 @@ subprojects { spotless { java { removeUnusedImports() - palantirJavaFormat('2.50.0').formatJavadoc(true) + palantirJavaFormat('2.67.0').formatJavadoc(true) formatAnnotations() } } diff --git a/examples/fabric-contract-example-as-service/Dockerfile b/examples/fabric-contract-example-as-service/Dockerfile index 2afd44b6f..8e21e344a 100644 --- a/examples/fabric-contract-example-as-service/Dockerfile +++ b/examples/fabric-contract-example-as-service/Dockerfile @@ -4,7 +4,7 @@ # Example multi-stage dockerfile for Java Chaincode # the first stage -FROM gradle:jdk11 AS GRADLE_BUILD +FROM gradle:8-jdk21 AS gradle_build # copy the build.gradle and src code to the container COPY src/ src/ @@ -15,11 +15,11 @@ RUN gradle build shadowJar # the second stage of our build just needs the compiled files -FROM openjdk:11-jre-slim +FROM eclipse-temurin:21-jre # copy only the artifacts we need from the first stage and discard the rest -COPY --from=GRADLE_BUILD /home/gradle/build/libs/chaincode.jar /chaincode.jar +COPY --from=gradle_build /home/gradle/build/libs/chaincode.jar /chaincode.jar -ENV PORT 9999 +ENV PORT=9999 EXPOSE 9999 # set the startup command to execute the jar diff --git a/examples/fabric-contract-example-as-service/build.gradle b/examples/fabric-contract-example-as-service/build.gradle index b787d94b7..a8d365247 100644 --- a/examples/fabric-contract-example-as-service/build.gradle +++ b/examples/fabric-contract-example-as-service/build.gradle @@ -1,31 +1,24 @@ plugins { - id 'com.github.johnrengelman.shadow' version '8.1.1' + id 'com.gradleup.shadow' version '8.3.6' id 'java' } -version '0.0.1' - -tasks.compileJava { - options.release.set(11) -} +version = '0.0.1' repositories { mavenCentral() maven { - url "https://www.jitpack.io" + url = "https://www.jitpack.io" } - maven { - url "https://hyperledger.jfrog.io/hyperledger/fabric-maven" - } - } dependencies { - compile 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.5.2' - compile 'org.json:json:20240303' - testImplementation 'org.junit.jupiter:junit-jupiter:5.11.0' - testImplementation 'org.assertj:assertj-core:3.26.3' - testImplementation 'org.mockito:mockito-core:5.13.0' + implementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.5.5' + implementation 'org.json:json:20250517' + testImplementation 'org.junit.jupiter:junit-jupiter:5.13.1' + testImplementation 'org.assertj:assertj-core:3.27.3' + testImplementation 'org.mockito:mockito-core:5.18.0' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } shadowJar { @@ -39,14 +32,14 @@ shadowJar { } } +compileJava { + options.release.set(11) + options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" << "-parameters" +} + test { useJUnitPlatform() testLogging { - events "passed", "skipped", "failed" + events "PASSED", "SKIPPED", "FAILED" } } - - -tasks.withType(JavaCompile) { - options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" << "-parameters" -} diff --git a/examples/fabric-contract-example-gradle-kotlin/build.gradle.kts b/examples/fabric-contract-example-gradle-kotlin/build.gradle.kts index 5cf57defb..92917bedc 100644 --- a/examples/fabric-contract-example-gradle-kotlin/build.gradle.kts +++ b/examples/fabric-contract-example-gradle-kotlin/build.gradle.kts @@ -14,11 +14,11 @@ plugins { version = "0.0.1" dependencies { - implementation("org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.5.2") - implementation("org.json:json:20240303") + implementation("org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.5.5") + implementation("org.json:json:20250517") implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") - testImplementation("org.junit.jupiter:junit-jupiter:5.11.0") + testImplementation("org.junit.jupiter:junit-jupiter:5.13.1") testImplementation("com.nhaarman.mockitokotlin2:mockito-kotlin:2.1.0") } @@ -27,9 +27,6 @@ repositories { maven { setUrl("https://jitpack.io") } - maven { - setUrl("https://hyperledger.jfrog.io/hyperledger/fabric-maven") - } } tasks { diff --git a/examples/fabric-contract-example-gradle/build.gradle b/examples/fabric-contract-example-gradle/build.gradle index ceb2a9a2a..a4b822229 100644 --- a/examples/fabric-contract-example-gradle/build.gradle +++ b/examples/fabric-contract-example-gradle/build.gradle @@ -1,31 +1,23 @@ plugins { - id 'com.github.johnrengelman.shadow' version '8.1.1' + id 'com.gradleup.shadow' version '8.3.6' id 'java' } -version '0.0.1' - -tasks.compileJava { - options.release.set(11) -} +version = '0.0.1' repositories { mavenCentral() maven { - url "https://www.jitpack.io" + url = "https://www.jitpack.io" } - maven { - url "https://hyperledger.jfrog.io/hyperledger/fabric-maven" - } - } dependencies { - compile 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.5.2' - compile 'org.json:json:20240303' - testImplementation 'org.junit.jupiter:junit-jupiter:5.11.0' - testImplementation 'org.assertj:assertj-core:3.26.3' - testImplementation 'org.mockito:mockito-core:5.13.0' + compile 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.5.5' + compile 'org.json:json:20250517' + testImplementation 'org.junit.jupiter:junit-jupiter:5.13.1' + testImplementation 'org.assertj:assertj-core:3.27.3' + testImplementation 'org.mockito:mockito-core:5.18.0' } shadowJar { @@ -39,14 +31,14 @@ shadowJar { } } +compileJava { + options.release.set(11) + options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" << "-parameters" +} + test { useJUnitPlatform() testLogging { - events "passed", "skipped", "failed" + events "PASSED", "SKIPPED", "FAILED" } } - - -tasks.withType(JavaCompile) { - options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" << "-parameters" -} diff --git a/examples/fabric-contract-example-maven/pom.xml b/examples/fabric-contract-example-maven/pom.xml index b022d5aa4..41d2202fc 100644 --- a/examples/fabric-contract-example-maven/pom.xml +++ b/examples/fabric-contract-example-maven/pom.xml @@ -7,20 +7,20 @@ - 1.8 + 21 UTF-8 UTF-8 - 2.5.4 + 2.5.5 - 1.3.14 + 1.5.15 1.7.5 - 5.3.0-RC1 - 1.3.0-RC1 + 5.13.1 + 1.13.1 @@ -29,10 +29,6 @@ jitpack.io https://www.jitpack.io - - artifactory - https://hyperledger.jfrog.io/hyperledger/fabric-maven - @@ -48,7 +44,7 @@ org.hyperledger.fabric fabric-protos - 0.3.3 + 0.3.7 compile @@ -92,7 +88,7 @@ org.mockito mockito-core - 2.10.0 + 5.18.0 diff --git a/examples/ledger-api/build.gradle b/examples/ledger-api/build.gradle index ceb2a9a2a..8f94a9b25 100644 --- a/examples/ledger-api/build.gradle +++ b/examples/ledger-api/build.gradle @@ -1,31 +1,23 @@ plugins { - id 'com.github.johnrengelman.shadow' version '8.1.1' + id 'com.gradleup.shadow' version '8.3.6' id 'java' } version '0.0.1' -tasks.compileJava { - options.release.set(11) -} - repositories { mavenCentral() maven { url "https://www.jitpack.io" } - maven { - url "https://hyperledger.jfrog.io/hyperledger/fabric-maven" - } - } dependencies { - compile 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.5.2' - compile 'org.json:json:20240303' - testImplementation 'org.junit.jupiter:junit-jupiter:5.11.0' - testImplementation 'org.assertj:assertj-core:3.26.3' - testImplementation 'org.mockito:mockito-core:5.13.0' + compile 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.5.5' + compile 'org.json:json:20250517' + testImplementation 'org.junit.jupiter:junit-jupiter:5.13.1' + testImplementation 'org.assertj:assertj-core:3.27.3' + testImplementation 'org.mockito:mockito-core:5.18.0' } shadowJar { @@ -39,14 +31,14 @@ shadowJar { } } +compileJava { + options.release.set(11) + options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" << "-parameters" +} + test { useJUnitPlatform() testLogging { - events "passed", "skipped", "failed" + events "PASSED", "SKIPPED", "FAILED" } } - - -tasks.withType(JavaCompile) { - options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" << "-parameters" -} diff --git a/fabric-chaincode-docker/Dockerfile b/fabric-chaincode-docker/Dockerfile index d8ae42298..eeaf43033 100644 --- a/fabric-chaincode-docker/Dockerfile +++ b/fabric-chaincode-docker/Dockerfile @@ -13,8 +13,8 @@ RUN curl -s "https://get.sdkman.io" | bash SHELL ["/bin/bash", "-c"] RUN source /root/.sdkman/bin/sdkman-init.sh \ - && sdk install gradle 8.11.1 \ - && sdk install maven 3.9.9 + && sdk install gradle 8.14.2 \ + && sdk install maven 3.9.10 FROM ${JAVA_IMAGE} AS dependencies diff --git a/fabric-chaincode-docker/README.md b/fabric-chaincode-docker/README.md new file mode 100644 index 000000000..4c87631da --- /dev/null +++ b/fabric-chaincode-docker/README.md @@ -0,0 +1,16 @@ +# Quick reference + +- **Maintained by**: + [The Fabric Java chaincode maintainers](https://github.com/hyperledger/fabric-chaincode-java) + +# Overview + +This image is used by the default [Hyperledger Fabric](https://hyperledger-fabric.readthedocs.io/) chaincode builder when deploying Java smart contracts. It is not intended for use independently of Hyperledger Fabric. + +# Image variants + +Detailed information on image tags, interoperability, and supported Java versions can be found in the [compatibility](https://github.com/hyperledger/fabric-chaincode-java/blob/main/COMPATIBILITY.md) documentation. + +# License + +This image is provided under the [Apache-2.0](https://github.com/hyperledger/fabric-chaincode-java/blob/main/LICENSE) license. diff --git a/fabric-chaincode-docker/build.gradle b/fabric-chaincode-docker/build.gradle index e5ba5d6c4..b5dbbeb5c 100644 --- a/fabric-chaincode-docker/build.gradle +++ b/fabric-chaincode-docker/build.gradle @@ -4,47 +4,41 @@ * SPDX-License-Identifier: Apache-2.0 */ -buildscript { - repositories { - maven { url "https://oss.sonatype.org/content/repositories/snapshots" } - maven { url "https://www.jitpack.io" } - mavenCentral() - gradlePluginPortal() - } - dependencies { - classpath 'com.bmuschko:gradle-docker-plugin:9.4.0' - } +plugins { + id 'com.bmuschko.docker-remote-api' version '9.4.0' } -apply plugin: 'com.bmuschko.docker-remote-api' +repositories { + mavenCentral() +} import com.bmuschko.gradle.docker.tasks.image.* -task copyLib (type: Copy) { +tasks.register('copyLib', Copy) { dependsOn ':fabric-chaincode-shim:build' from project(':fabric-chaincode-shim').configurations.runtimeClasspath into('build/distributions/chaincode-java/lib') } -task copyShimJar(type: Copy) { +tasks.register('copyShimJar', Copy) { dependsOn copyLib from project(':fabric-chaincode-shim').jar into('build/distributions/chaincode-java/lib') } -task copyStartScript(type: Copy) { +tasks.register('copyStartScript', Copy) { dependsOn copyShimJar - from ('start') - into ('build/distributions/chaincode-java') + from('start') + into('build/distributions/chaincode-java') } -task copyBuildScript(type: Copy) { +tasks.register('copyBuildScript', Copy) { dependsOn copyStartScript - from ('build.sh') - into ('build/distributions/chaincode-java') + from('build.sh') + into('build/distributions/chaincode-java') } -task copyAllDeps(type: Copy) { +tasks.register('copyAllDeps', Copy) { dependsOn copyBuildScript copy { from project(':fabric-chaincode-shim').getProjectDir() @@ -62,8 +56,8 @@ task copyAllDeps(type: Copy) { } } -task buildImage(type: DockerBuildImage) { +tasks.register('buildImage', DockerBuildImage) { dependsOn copyAllDeps inputDir = project.file('Dockerfile').parentFile - images = ['hyperledger/fabric-javaenv', 'hyperledger/fabric-javaenv:2.5', 'hyperledger/fabric-javaenv:amd64-2.5.5', 'hyperledger/fabric-javaenv:amd64-latest'] + images = ['hyperledger/fabric-javaenv', 'hyperledger/fabric-javaenv:2.5', 'hyperledger/fabric-javaenv:amd64-2.5.6', 'hyperledger/fabric-javaenv:amd64-latest'] } diff --git a/fabric-chaincode-integration-test/build.gradle b/fabric-chaincode-integration-test/build.gradle index 9d2b1fc73..240c506e0 100644 --- a/fabric-chaincode-integration-test/build.gradle +++ b/fabric-chaincode-integration-test/build.gradle @@ -1,7 +1,7 @@ dependencies { implementation project(':fabric-chaincode-docker') implementation project(':fabric-chaincode-shim') - implementation 'org.json:json:20240303' + implementation 'org.json:json:20250517' } @@ -12,17 +12,17 @@ dependencies { // Show test results. testLogging { events "passed", "skipped", "failed" - showExceptions true - showCauses true - showStandardStreams true - exceptionFormat "full" + showExceptions = true + showCauses = true + showStandardStreams = true + exceptionFormat = "full" } } -task getLatestDockerImages{ +tasks.register('getLatestDockerImages') { doLast { - exec { + providers.exec { workingDir "." commandLine "sh", "-c", "./getDockerImages.sh" } diff --git a/fabric-chaincode-integration-test/src/contracts/bare-gradle/build.gradle b/fabric-chaincode-integration-test/src/contracts/bare-gradle/build.gradle index b5ea23f8a..e7479c5cd 100644 --- a/fabric-chaincode-integration-test/src/contracts/bare-gradle/build.gradle +++ b/fabric-chaincode-integration-test/src/contracts/bare-gradle/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'com.gradleup.shadow' version '8.3.5' + id 'com.gradleup.shadow' version '8.3.6' id 'java' } @@ -17,15 +17,14 @@ compileJava { repositories { mavenCentral() - maven { url = "https://www.jitpack.io" } maven { url "$projectDir/repository" } } dependencies { - implementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.5.5' - implementation 'org.hyperledger.fabric:fabric-protos:0.3.3' + implementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.5.6' + implementation 'org.hyperledger.fabric:fabric-protos:0.3.7' } shadowJar { diff --git a/fabric-chaincode-integration-test/src/contracts/bare-maven/pom.xml b/fabric-chaincode-integration-test/src/contracts/bare-maven/pom.xml index 9740748dd..fccbc9e0c 100644 --- a/fabric-chaincode-integration-test/src/contracts/bare-maven/pom.xml +++ b/fabric-chaincode-integration-test/src/contracts/bare-maven/pom.xml @@ -12,7 +12,7 @@ UTF-8 - 2.5.5 + 2.5.6 diff --git a/fabric-chaincode-integration-test/src/contracts/fabric-ledger-api/build.gradle b/fabric-chaincode-integration-test/src/contracts/fabric-ledger-api/build.gradle index a8d488c30..97d990904 100644 --- a/fabric-chaincode-integration-test/src/contracts/fabric-ledger-api/build.gradle +++ b/fabric-chaincode-integration-test/src/contracts/fabric-ledger-api/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'com.gradleup.shadow' version '8.3.5' + id 'com.gradleup.shadow' version '8.3.6' id 'java' } @@ -17,15 +17,14 @@ compileJava { repositories { mavenCentral() - maven { url = "https://www.jitpack.io" } maven { url "$projectDir/repository" } } dependencies { - implementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.5.5' - implementation 'org.hyperledger.fabric:fabric-protos:0.3.3' + implementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.5.6' + implementation 'org.hyperledger.fabric:fabric-protos:0.3.7' } shadowJar { diff --git a/fabric-chaincode-integration-test/src/contracts/fabric-shim-api/build.gradle b/fabric-chaincode-integration-test/src/contracts/fabric-shim-api/build.gradle index b128a4c85..b59cca3cc 100644 --- a/fabric-chaincode-integration-test/src/contracts/fabric-shim-api/build.gradle +++ b/fabric-chaincode-integration-test/src/contracts/fabric-shim-api/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'com.gradleup.shadow' version '8.3.5' + id 'com.gradleup.shadow' version '8.3.6' id 'java' } @@ -17,17 +17,16 @@ compileJava { repositories { mavenCentral() - maven { url = "https://www.jitpack.io" } maven { url "$projectDir/repository" } } dependencies { - implementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.5.5' - implementation 'org.hyperledger.fabric:fabric-protos:0.3.3' - implementation 'commons-logging:commons-logging:1.2' - implementation 'com.google.code.gson:gson:2.10.1' + implementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.5.6' + implementation 'org.hyperledger.fabric:fabric-protos:0.3.7' + implementation 'commons-logging:commons-logging:1.3.5' + implementation 'com.google.code.gson:gson:2.13.1' } shadowJar { diff --git a/fabric-chaincode-integration-test/src/contracts/wrapper-maven/pom.xml b/fabric-chaincode-integration-test/src/contracts/wrapper-maven/pom.xml index f9e592382..894443ea7 100644 --- a/fabric-chaincode-integration-test/src/contracts/wrapper-maven/pom.xml +++ b/fabric-chaincode-integration-test/src/contracts/wrapper-maven/pom.xml @@ -12,7 +12,7 @@ UTF-8 - 2.5.5 + 2.5.6 diff --git a/fabric-chaincode-shim/build.gradle b/fabric-chaincode-shim/build.gradle index eff78a88c..8cff266f8 100644 --- a/fabric-chaincode-shim/build.gradle +++ b/fabric-chaincode-shim/build.gradle @@ -6,13 +6,14 @@ plugins { id 'maven-publish' - id 'jacoco' id 'signing' + id 'org.jreleaser' version '1.18.0' + id 'jacoco' id 'pmd' } pmd { - toolVersion = '7.7.0' + toolVersion = '7.14.0' ruleSetFiles = files('../pmd-ruleset.xml') ruleSets = [] // explicitly set to empty to avoid using the default configuration ignoreFailures = false @@ -26,48 +27,37 @@ configurations { } } -tasks.register('resolveAndLockAll') { - notCompatibleWithConfigurationCache("Filters configurations at execution time") - doFirst { - assert gradle.startParameter.writeDependencyLocks : "$path must be run from the command line with the `--write-locks` flag" - } - doLast { - configurations.findAll { it.canBeResolved }.each { it.resolve() } - } -} - tasks.withType(org.gradle.api.tasks.testing.Test) { systemProperty 'CORE_CHAINCODE_LOGGING_LEVEL', 'DEBUG' } dependencies { - implementation platform('com.google.protobuf:protobuf-bom:3.25.5') - implementation platform('io.grpc:grpc-bom:1.68.1') - implementation platform('io.opentelemetry:opentelemetry-bom:1.42.1') + implementation platform('com.google.protobuf:protobuf-bom:4.31.1') + implementation platform('io.grpc:grpc-bom:1.73.0') + implementation platform('io.opentelemetry:opentelemetry-bom:1.51.0') - implementation 'org.hyperledger.fabric:fabric-protos:0.3.3' - implementation 'org.bouncycastle:bcpkix-jdk18on:1.79' - implementation 'org.bouncycastle:bcprov-jdk18on:1.79' + implementation 'org.hyperledger.fabric:fabric-protos:0.3.7' + implementation 'org.bouncycastle:bcpkix-jdk18on:1.81' + implementation 'org.bouncycastle:bcprov-jdk18on:1.81' implementation 'io.github.classgraph:classgraph:4.8.179' - implementation 'com.github.everit-org.json-schema:org.everit.json.schema:1.14.4' - implementation 'org.json:json:20240303' + implementation 'com.github.erosb:everit-json-schema:1.14.6' + implementation 'org.json:json:20250517' implementation 'com.google.protobuf:protobuf-java-util' implementation 'io.grpc:grpc-netty-shaded' implementation 'io.grpc:grpc-protobuf' implementation 'io.grpc:grpc-stub' testImplementation 'io.grpc:grpc-inprocess' - // Required if using Java 11+ as no longer bundled in the core libraries - testImplementation 'javax.xml.bind:jaxb-api:2.3.1' implementation 'io.opentelemetry:opentelemetry-api' - implementation 'io.opentelemetry.proto:opentelemetry-proto:1.3.2-alpha' + implementation 'io.opentelemetry.proto:opentelemetry-proto:1.7.0-alpha' implementation 'io.opentelemetry:opentelemetry-sdk' implementation 'io.opentelemetry:opentelemetry-sdk-extension-autoconfigure' implementation 'io.opentelemetry:opentelemetry-sdk-trace' implementation 'io.opentelemetry:opentelemetry-exporter-otlp' implementation 'io.opentelemetry:opentelemetry-extension-trace-propagators' - implementation 'io.opentelemetry.instrumentation:opentelemetry-grpc-1.6:2.8.0-alpha' + implementation 'io.opentelemetry.semconv:opentelemetry-semconv:1.32.0' + implementation 'io.opentelemetry.instrumentation:opentelemetry-grpc-1.6:2.16.0-alpha' } sourceSets { @@ -148,7 +138,7 @@ jacocoTestCoverageVerification { test.finalizedBy(jacocoTestReport) test.finalizedBy(jacocoTestCoverageVerification) -task licenseCheck { +tasks.register('licenseCheck') { group = "license" description = "Checks the License part of each source file" @@ -157,34 +147,37 @@ task licenseCheck { def missing = new LinkedList() sourceSets.forEach { sourceSet -> - sourceSet.allSource.findAll { !it.path.contains("build") && !(it.path.contains("test") && it.path.contains("resources"))}.each { + sourceSet.allSource.findAll { + !it.path.contains("build") && + !(it.path.contains("test") && it.path.contains("resources")) + }.each { file -> - if (!file.name.contains("json")){ - BufferedReader r = new BufferedReader(new FileReader(file)) - def line, hasSPDX = false, hasTraditional = false - while ((line = r.readLine()) != null) { - if (line.contains("SPDX-License-Identifier")) { - hasSPDX = true - break - } - if (line.contains("http://www.apache.org/licenses/LICENSE-2.0")) { - hasTraditional = true - break + if (!file.name.contains("json")) { + BufferedReader r = new BufferedReader(new FileReader(file)) + def line, hasSPDX = false, hasTraditional = false + while ((line = r.readLine()) != null) { + if (line.contains("SPDX-License-Identifier")) { + hasSPDX = true + break + } + if (line.contains("http://www.apache.org/licenses/LICENSE-2.0")) { + hasTraditional = true + break + } } - } - if (!hasSPDX) { - if (hasTraditional) { - noSPDX.add(file) - } else { - missing.add(file) + if (!hasSPDX) { + if (hasTraditional) { + noSPDX.add(file) + } else { + missing.add(file) + } } } - } } } if (noSPDX.isEmpty()) { - println "All remaining files have Apache 2.0 headers" + println "All remaining files have Apache 2.0 headers." } else { println "We are standardizing with the SPDX style license headers." println "The following files contain the traditional license headers which are still valid:" @@ -223,17 +216,13 @@ javadoc { classpath = sourceSets.main.runtimeClasspath - javadoc.options.addStringOption('Xdoclint:none', '-quiet') + options.addStringOption('Xdoclint:none', '-quiet') + options.addStringOption('Xwerror', '-quiet') options.overview = "src/main/java/org/hyperledger/fabric/overview.html" -} -if (JavaVersion.current().isJava8Compatible()) { - project.tasks.withType(Javadoc) { - options.addStringOption('Xdoclint:all', '-quiet') - options.addStringOption('Xwerror', '-quiet') - } } +def final stagingDeployUrl = layout.buildDirectory.dir('staging-deploy') publishing { publications { @@ -246,10 +235,12 @@ publishing { name = 'JavaChaincodeShim' packaging = 'jar' description = 'Hyperledger Fabric Java Chaincode Shim' - url = 'http://www.hyperledger.org/' + url = 'https://hyperledger.github.io/fabric-chaincode-java/' scm { - url = 'https://github.com/hyperledger/fabric-chaincode-java.git' + connection = 'scm:git:https://github.com/hyperledger/fabric-chaincode-java.git' + developerConnection = 'scm:git:ssh://github.com:hyperledger/fabric-chaincode-java.git' + url = 'https://github.com/hyperledger/fabric-chaincode-java' } licenses { license { @@ -259,26 +250,16 @@ publishing { } developers { - developer { - id = 'gennadylaventman' - name = 'Gennady Laventman' - email = 'gennady@il.ibm.com' - } - developer { - id = 'luiss' - name = 'Luis Sanchez' - email = 'luiss@me.com' - } - developer { - id = 'C0rWin' - name = 'Artem Barger' - email = 'bartem@il.ibm.com' - } developer { id = 'denyeart' name = 'David Enyeart' email = 'enyeart@us.ibm.com' } + developer { + id = 'bestbeforetoday' + name = 'Mark S. Lewis' + email = 'Mark.S.Lewis@outlook.com' + } } } } @@ -287,17 +268,12 @@ publishing { repositories { maven { - name = "release" - url = "https://oss.sonatype.org/service/local/staging/deploy/maven2/" - credentials { - username = project.findProperty('ossrhUsername') - password = project.findProperty('ossrhPassword') - } - + name = "Staging" + url = stagingDeployUrl } maven { - name = "GitHubPackages" + name = "GitHub" url = "https://maven.pkg.github.com/hyperledger/fabric-chaincode-java" credentials { username = System.getenv("GITHUB_ACTOR") @@ -308,16 +284,33 @@ publishing { } signing { - println "Signing" - if (project.findProperty('signing.key')) { - def signingKey = project.findProperty('signing.key') - def signingPassword = project.findProperty('signing.password') - useInMemoryPgpKeys(signingKey, signingPassword) - - sign publishing.publications.shim - println "... signed" - } else { - println "... no keys to use " + required = { gradle.taskGraph.hasTask(":${project.name}:publishShimPublicationToStagingRepository") } + + def signingKey = findProperty('signingKey') + def signingPassword = findProperty('signingPassword') + useInMemoryPgpKeys(signingKey, signingPassword) + + sign publishing.publications.shim +} + +jreleaser { + gitRootSearch = true + deploy { + maven { + mavenCentral { + sonatype { + active = 'ALWAYS' + url = 'https://central.sonatype.com/api/v1/publisher' + sign = false + stagingRepository(file(stagingDeployUrl).toString()) + } + } + } + } + release { + github { + enabled = false + } } } @@ -325,8 +318,8 @@ signing { // otherwise this fails with a duplicates error. // (see https://github.com/gradle/gradle/issues/17236) -task sourcesJar(type: Jar) { - duplicatesStrategy = 'include' +tasks.register('sourcesJar', Jar) { + duplicatesStrategy = DuplicatesStrategy.INCLUDE archiveClassifier = 'sources' from sourceSets.main.allSource } @@ -343,40 +336,41 @@ build.dependsOn licenseCheck import org.gradle.api.tasks.testing.logging.TestExceptionFormat import org.gradle.api.tasks.testing.logging.TestLogEvent -tasks.withType(Test) { +tasks.withType(Test).configureEach { environment "CORE_PEER_LOCALMSPID", "mymsp" testLogging { // set options for log level LIFECYCLE events TestLogEvent.FAILED, - TestLogEvent.PASSED, - TestLogEvent.SKIPPED, - TestLogEvent.STANDARD_OUT - exceptionFormat TestExceptionFormat.FULL - showExceptions true - showCauses true - showStackTraces true + TestLogEvent.PASSED, + TestLogEvent.SKIPPED, + TestLogEvent.STANDARD_OUT + exceptionFormat = TestExceptionFormat.FULL + showExceptions = true + showCauses = true + showStackTraces = true // set options for log level DEBUG and INFO debug { events TestLogEvent.STARTED, - TestLogEvent.FAILED, - TestLogEvent.PASSED, - TestLogEvent.SKIPPED, - TestLogEvent.STANDARD_ERROR, - TestLogEvent.STANDARD_OUT - exceptionFormat TestExceptionFormat.FULL + TestLogEvent.FAILED, + TestLogEvent.PASSED, + TestLogEvent.SKIPPED, + TestLogEvent.STANDARD_ERROR, + TestLogEvent.STANDARD_OUT + exceptionFormat = TestExceptionFormat.FULL } info.events = debug.events info.exceptionFormat = debug.exceptionFormat - afterSuite { desc, result -> + afterSuite {desc, result -> if (!desc.parent) { // will match the outermost suite def output = "Results: ${result.resultType} (${result.testCount} tests, ${result.successfulTestCount} successes, ${result.failedTestCount} failures, ${result.skippedTestCount} skipped)" def startItem = '| ', endItem = ' |' def repeatLength = startItem.length() + output.length() + endItem.length() - println('\n' + ('-' * repeatLength) + '\n' + startItem + output + endItem + '\n' + ('-' * repeatLength)) + println('\n' + ('-' * repeatLength) + '\n' + startItem + output + endItem + '\n' + + ('-' * repeatLength)) } } } diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/ExecutionService.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/ExecutionService.java index 8c8596808..629f21bb5 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/ExecutionService.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/ExecutionService.java @@ -15,6 +15,7 @@ * *

Service that executes {@link InvocationRequest} (wrapped Init/Invoke + extra data) using routing information */ +@FunctionalInterface public interface ExecutionService { /** diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/impl/ContractInvocationRequest.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/impl/ContractInvocationRequest.java index 7a3e0ff36..82a0f9967 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/impl/ContractInvocationRequest.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/impl/ContractInvocationRequest.java @@ -15,7 +15,7 @@ import org.hyperledger.fabric.shim.ChaincodeStub; public final class ContractInvocationRequest implements InvocationRequest { - @SuppressWarnings("PMD.ProperLogger") // PMD 7.7.0 gives a false positive here + @SuppressWarnings("PMD.ProperLogger") // PMD 7.12.0 gives a false positive here private static final Log LOGGER = LogFactory.getLog(ContractInvocationRequest.class); private static final Pattern NS_REGEX = Pattern.compile(":"); diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/metadata/TypeSchema.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/metadata/TypeSchema.java index 8b11eccd9..dab261e54 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/metadata/TypeSchema.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/metadata/TypeSchema.java @@ -25,7 +25,7 @@ * *

Does not include the "schema" top level map */ -@SuppressWarnings({"PMD.LooseCoupling", "PMD.GodClass"}) +@SuppressWarnings("PMD.GodClass") public final class TypeSchema extends HashMap { private static final long serialVersionUID = 1L; private static final Logger LOGGER = Logger.getLogger(TypeSchema.class.getName()); diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/SerializerRegistryImpl.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/SerializerRegistryImpl.java index 728966f09..99a41e03d 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/SerializerRegistryImpl.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/SerializerRegistryImpl.java @@ -24,7 +24,7 @@ public class SerializerRegistryImpl { private static final Logger LOGGER = Logger.getLogger(SerializerRegistryImpl.class); - private final Class annotationClass = Serializer.class; + private static final Class ANNOTATION_CLASS = Serializer.class; // Could index these by name and or type. private final Map contents = new HashMap<>(); @@ -68,7 +68,7 @@ public void findAndSetContents() throws InstantiationException, IllegalAccessExc try (ScanResult scanResult = classGraph.scan()) { for (final ClassInfo classInfo : - scanResult.getClassesWithAnnotation(this.annotationClass.getCanonicalName())) { + scanResult.getClassesWithAnnotation(this.ANNOTATION_CLASS.getCanonicalName())) { LOGGER.debug(() -> "Found class with contract annotation: " + classInfo.getName()); final Class cls = (Class) classInfo.loadClass(); LOGGER.debug("Loaded class"); diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/Collection.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/Collection.java index 1f109da8d..42a261074 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/Collection.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/ledger/Collection.java @@ -6,6 +6,7 @@ package org.hyperledger.fabric.ledger; /** Place holder. */ +@SuppressWarnings("PMD.ImplicitFunctionalInterface") public interface Collection { /** Constant that can be used to refer to the 'Worldstate' collection explicitly. */ diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeServerProperties.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeServerProperties.java index 4352fe14a..8197be59e 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeServerProperties.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeServerProperties.java @@ -314,7 +314,7 @@ public void setTlsEnabled(final boolean tlsEnabled) { * * @throws IllegalArgumentException if any properties are not valid. */ - @SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"}) + @SuppressWarnings("PMD.CyclomaticComplexity") public void validate() { if (this.getServerAddress() == null) { throw new IllegalArgumentException("chaincodeServerProperties.getServerAddress() must be set"); diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ext/sbe/impl/StateBasedEndorsementImpl.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ext/sbe/impl/StateBasedEndorsementImpl.java index 1226a3cb7..56cae1a03 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ext/sbe/impl/StateBasedEndorsementImpl.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ext/sbe/impl/StateBasedEndorsementImpl.java @@ -23,7 +23,7 @@ /** Implements {@link StateBasedEndorsement}. */ public final class StateBasedEndorsementImpl implements StateBasedEndorsement { - @SuppressWarnings("PMD.ProperLogger") // PMD 7.7.0 reports a false positive + @SuppressWarnings("PMD.ProperLogger") // PMD 7.12.0 reports a false positive private static final Log LOGGER = LogFactory.getLog(StateBasedEndorsementImpl.class); private final Map orgs = new HashMap<>(); diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/InvocationTaskManager.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/InvocationTaskManager.java index aecc8e64d..bbed26d76 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/InvocationTaskManager.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/impl/InvocationTaskManager.java @@ -183,9 +183,6 @@ private void processChaincodeMessage(final ChaincodeMessage chaincodeMessage) { case READY: handleMsg(chaincodeMessage, msgType); break; - default: - LOGGER.warning(() -> String.format(CANNOT_HANDLE_FORMAT, chaincodeMessage.getTxid(), msgType)); - break; } } diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/traces/impl/OpenTelemetryTracesProvider.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/traces/impl/OpenTelemetryTracesProvider.java index 54a3034f0..4801ebe33 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/traces/impl/OpenTelemetryTracesProvider.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/traces/impl/OpenTelemetryTracesProvider.java @@ -13,7 +13,7 @@ import io.opentelemetry.context.Context; import io.opentelemetry.instrumentation.grpc.v1_6.GrpcTelemetry; import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; -import io.opentelemetry.semconv.ResourceAttributes; +import io.opentelemetry.semconv.ServiceAttributes; import java.util.HashMap; import java.util.Map; import java.util.Properties; @@ -32,7 +32,7 @@ public final class OpenTelemetryTracesProvider implements TracesProvider { @Override public void initialize(final Properties props) { String serviceName = props.getProperty(CORE_CHAINCODE_ID_NAME, "unknown"); - props.setProperty(ResourceAttributes.SERVICE_NAME.getKey(), serviceName); + props.setProperty(ServiceAttributes.SERVICE_NAME.getKey(), serviceName); OpenTelemetry openTelemetry = AutoConfiguredOpenTelemetrySdk.builder() .addPropertiesSupplier(() -> getOpenTelemetryProperties(props)) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index a4b76b953..1b33c55ba 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e2847c820..ff23a68d7 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index f5feea6d6..23d15a936 100755 --- a/gradlew +++ b/gradlew @@ -86,8 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s -' "$PWD" ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -115,7 +114,7 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar +CLASSPATH="\\\"\\\"" # Determine the Java command to use to start the JVM. @@ -206,7 +205,7 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. @@ -214,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/gradlew.bat b/gradlew.bat index 9b42019c7..5eed7ee84 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -70,11 +70,11 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar +set CLASSPATH= @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell