diff --git a/.github/actions/java-gradle/post-merge/action.yml b/.github/actions/java-gradle/post-merge/action.yml index 9135ebbe62..b638ddc9da 100644 --- a/.github/actions/java-gradle/post-merge/action.yml +++ b/.github/actions/java-gradle/post-merge/action.yml @@ -35,7 +35,6 @@ runs: with: distribution: "temurin" java-version: "17" - cache: "gradle" - name: Setup Gradle uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0 @@ -44,16 +43,17 @@ runs: - name: Build for publishing shell: bash + working-directory: foreign/java run: | echo "📦 Building Java SDK for publishing..." - foreign/java/dev-support/checks/build.sh build -x test -x checkstyleMain -x checkstyleTest + gradle build -x test -x checkstyleMain -x checkstyleTest BUILD_EXIT_CODE=$? # List artifacts only if build succeeded if [ $BUILD_EXIT_CODE -eq 0 ]; then echo "" echo "Build artifacts:" - find foreign/java -path "*/build/libs/*.jar" -type f 2>/dev/null | head -20 || echo "No jar artifacts found in build/libs directories" + find . -path "*/build/libs/*.jar" -type f 2>/dev/null | head -20 || echo "No jar artifacts found in build/libs directories" else echo "❌ Build failed with exit code $BUILD_EXIT_CODE" exit $BUILD_EXIT_CODE @@ -61,6 +61,7 @@ runs: - name: Publish to Maven Nexus shell: bash + working-directory: foreign/java env: NEXUS_USER: ${{ env.NEXUS_USER }} NEXUS_PW: ${{ env.NEXUS_PW }} @@ -72,7 +73,7 @@ runs: echo "" # Extract version from build.gradle.kts - gradle_version=$(gradle -p foreign/java/java-sdk properties -q | grep "version:" | cut -d: -f2 | tr -d ' ') + gradle_version=$(gradle -p java-sdk properties -q | grep "version:" | cut -d: -f2 | tr -d ' ') echo "Version from gradle: $gradle_version" echo "Input version: ${{ inputs.version }}" @@ -92,7 +93,7 @@ runs: # Show what would be published echo "" echo "Artifacts that would be published:" - find foreign/java -path "*/build/libs/*.jar" -type f 2>/dev/null | while read jar; do + find . -path "*/build/libs/*.jar" -type f 2>/dev/null | while read jar; do echo " - $(basename $jar)" done else @@ -106,7 +107,7 @@ runs: echo "" # Run the publish task - foreign/java/dev-support/checks/build.sh build -x test -x checkstyleMain -x checkstyleTest sign publish + gradle build -x test -x checkstyleMain -x checkstyleTest sign publish PUBLISH_EXIT_CODE=$? if [ $PUBLISH_EXIT_CODE -eq 0 ]; then diff --git a/.github/actions/java-gradle/pre-merge/action.yml b/.github/actions/java-gradle/pre-merge/action.yml index b362a8729c..7a424f109f 100644 --- a/.github/actions/java-gradle/pre-merge/action.yml +++ b/.github/actions/java-gradle/pre-merge/action.yml @@ -26,36 +26,51 @@ inputs: runs: using: "composite" steps: - - name: Setup Java - uses: actions/setup-java@v4 + - name: Setup Java with cache + uses: ./.github/actions/utils/setup-java-with-cache with: - distribution: "temurin" - java-version: "17" - cache: "gradle" + gradle-cache-disabled: "true" - - name: Setup Gradle - uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0 - with: - gradle-version: '9.2.1' + - name: Lint SDK + if: inputs.task == 'lint' + shell: bash + working-directory: foreign/java + run: | + echo "::group::Linting foreign/java" + gradle check -x test + echo "::endgroup::" - - name: Lint + - name: Lint examples if: inputs.task == 'lint' shell: bash + working-directory: examples/java run: | - foreign/java/dev-support/checks/build.sh check -x test + echo "::group::Linting examples/java" + gradle check -x test + echo "::endgroup::" + + - name: Lint BDD + if: inputs.task == 'lint' + shell: bash + working-directory: bdd/java + run: | + echo "::group::Linting bdd/java" + gradle check -x test + echo "::endgroup::" - name: Build shell: bash if: inputs.task == 'build' + working-directory: foreign/java run: | - foreign/java/dev-support/checks/build.sh build -x test -x checkstyleMain -x checkstyleTest -x spotlessCheck + gradle build -x test -x checkstyleMain -x checkstyleTest -x spotlessCheck BUILD_EXIT_CODE=$? # List artifacts only if build succeeded if [ $BUILD_EXIT_CODE -eq 0 ]; then echo "" echo "Build artifacts:" - find foreign/java -path "*/build/libs/*.jar" -type f 2>/dev/null | head -20 || echo "No jar artifacts found in build/libs directories" + find . -path "*/build/libs/*.jar" -type f 2>/dev/null | head -20 || echo "No jar artifacts found in build/libs directories" fi # Exit with build exit code @@ -76,10 +91,10 @@ runs: - name: Test if: inputs.task == 'test' shell: bash + working-directory: foreign/java env: USE_EXTERNAL_SERVER: true - run: | - foreign/java/dev-support/checks/build.sh test + run: gradle test - name: Copy test reports if: ${{ !cancelled() && inputs.task == 'test' }} diff --git a/.github/actions/utils/setup-java-with-cache/action.yml b/.github/actions/utils/setup-java-with-cache/action.yml new file mode 100644 index 0000000000..ac9332a1e8 --- /dev/null +++ b/.github/actions/utils/setup-java-with-cache/action.yml @@ -0,0 +1,70 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# NOTE: this action sets up the Java toolchain + Gradle with caching, +# it is a convenience wrapper, so that we can use it in all workflows. + +name: setup-java-with-cache +description: Setup Java toolchain and Gradle with caching +inputs: + java-version: + description: "Java version to use" + required: false + default: "17" + java-distribution: + description: "Java distribution to use" + required: false + default: "temurin" + gradle-version: + description: "Gradle version to use" + required: false + default: "9.2.1" + gradle-cache-disabled: + description: "Whether to disable Gradle caching" + required: false + default: "false" + +runs: + using: "composite" + steps: + - name: Setup Java (with cache) + if: inputs.gradle-cache-disabled != 'true' + uses: actions/setup-java@v4 + with: + distribution: ${{ inputs.java-distribution }} + java-version: ${{ inputs.java-version }} + cache: gradle + + - name: Setup Java (no cache) + if: inputs.gradle-cache-disabled == 'true' + uses: actions/setup-java@v4 + with: + distribution: ${{ inputs.java-distribution }} + java-version: ${{ inputs.java-version }} + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0 + with: + gradle-version: ${{ inputs.gradle-version }} + cache-disabled: ${{ inputs.gradle-cache-disabled }} + + - name: Verify Java installation + run: | + echo "Java setup complete" + java --version + gradle --version + shell: bash diff --git a/.github/workflows/_test_examples.yml b/.github/workflows/_test_examples.yml index 0cd4dae1fa..6ffe4a4268 100644 --- a/.github/workflows/_test_examples.yml +++ b/.github/workflows/_test_examples.yml @@ -71,19 +71,11 @@ jobs: path: ~/.cache/pip key: pip-${{ runner.os }}-${{ hashFiles('foreign/python/pyproject.toml') }} - - name: Setup Java + - name: Setup Java with cache for examples if: inputs.component == 'examples-suite' && inputs.task == 'examples-java' - uses: actions/setup-java@v4 + uses: ./.github/actions/utils/setup-java-with-cache with: - distribution: "temurin" - java-version: "17" - cache: "gradle" - - - name: Setup Gradle - if: inputs.component == 'examples-suite' && inputs.task == 'examples-java' - uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0 - with: - gradle-version: "9.2.1" + gradle-cache-disabled: "true" - name: Setup Go with cache for examples if: inputs.component == 'examples-suite' && inputs.task == 'examples-go' diff --git a/bdd/java/build.gradle.kts b/bdd/java/build.gradle.kts index 44a0f25726..78f09eda2c 100644 --- a/bdd/java/build.gradle.kts +++ b/bdd/java/build.gradle.kts @@ -19,6 +19,7 @@ plugins { java + id("com.diffplug.spotless") version "8.1.0" } repositories { @@ -33,6 +34,18 @@ dependencies { testImplementation("org.junit.platform:junit-platform-suite:1.11.0") } +spotless { + java { + palantirJavaFormat() + endWithNewline() + trimTrailingWhitespace() + importOrder("", "\n", "javax|java", "\n", "\\#") + removeUnusedImports() + forbidWildcardImports() + formatAnnotations() + } +} + tasks.test { useJUnitPlatform() } diff --git a/bdd/java/src/test/java/org/apache/iggy/bdd/BasicMessagingSteps.java b/bdd/java/src/test/java/org/apache/iggy/bdd/BasicMessagingSteps.java index 334eeef293..0ad53dad0f 100644 --- a/bdd/java/src/test/java/org/apache/iggy/bdd/BasicMessagingSteps.java +++ b/bdd/java/src/test/java/org/apache/iggy/bdd/BasicMessagingSteps.java @@ -54,10 +54,8 @@ public void runningServer() { context.serverAddr = getenvOrDefault("IGGY_TCP_ADDRESS", "127.0.0.1:8090"); HostPort hostPort = HostPort.parse(context.serverAddr); - IggyTcpClient client = IggyTcpClient.builder() - .host(hostPort.host) - .port(hostPort.port) - .build(); + IggyTcpClient client = + IggyTcpClient.builder().host(hostPort.host).port(hostPort.port).build(); client.connect(); client.system().ping(); @@ -99,14 +97,16 @@ public void streamHasName(String streamName) { @When("I create a topic with name {string} in stream {int} with {int} partitions") public void createTopic(String topicName, int streamId, int partitions) { - TopicDetails topic = getClient().topics().createTopic( - (long) streamId, - (long) partitions, - CompressionAlgorithm.None, - BigInteger.ZERO, - BigInteger.ZERO, - Optional.empty(), - topicName); + TopicDetails topic = getClient() + .topics() + .createTopic( + (long) streamId, + (long) partitions, + CompressionAlgorithm.None, + BigInteger.ZERO, + BigInteger.ZERO, + Optional.empty(), + topicName); context.lastTopicId = topic.id(); context.lastTopicName = topic.name(); @@ -136,11 +136,9 @@ public void sendMessages(int messageCount, int streamId, int topicId, int partit messages.add(Message.of(content)); } - getClient().messages().sendMessages( - (long) streamId, - (long) topicId, - Partitioning.partitionId((long) partitionId), - messages); + getClient() + .messages() + .sendMessages((long) streamId, (long) topicId, Partitioning.partitionId((long) partitionId), messages); if (!messages.isEmpty()) { context.lastSentMessage = "test message " + (messageCount - 1); @@ -154,14 +152,16 @@ public void messagesSentSuccessfully() { @When("I poll messages from stream {int}, topic {int}, partition {int} starting from offset {int}") public void pollMessages(int streamId, int topicId, int partitionId, int startOffset) { - context.lastPolledMessages = getClient().messages().pollMessages( - (long) streamId, - (long) topicId, - Optional.of((long) partitionId), - 0L, - PollingStrategy.offset(BigInteger.valueOf(startOffset)), - 100L, - true); + context.lastPolledMessages = getClient() + .messages() + .pollMessages( + (long) streamId, + (long) topicId, + Optional.of((long) partitionId), + 0L, + PollingStrategy.offset(BigInteger.valueOf(startOffset)), + 100L, + true); } @Then("I should receive {int} messages") diff --git a/examples/java/build.gradle.kts b/examples/java/build.gradle.kts index 86c563a46c..258a90978b 100644 --- a/examples/java/build.gradle.kts +++ b/examples/java/build.gradle.kts @@ -20,7 +20,6 @@ plugins { java id("com.diffplug.spotless") version "8.1.0" - checkstyle } repositories { @@ -36,19 +35,16 @@ dependencies { spotless { java { palantirJavaFormat() - removeUnusedImports() - trimTrailingWhitespace() endWithNewline() - formatAnnotations() + trimTrailingWhitespace() importOrder("", "\n", "javax|java", "\n", "\\#") + removeUnusedImports() + forbidWildcardImports() + formatAnnotations() toggleOffOn() } } -checkstyle { - toolVersion = "12.2.0" -} - tasks.withType { dependsOn("spotlessApply") } diff --git a/foreign/java/dev-support/checks/build.sh b/foreign/java/dev-support/checks/build.sh deleted file mode 100755 index a055f79146..0000000000 --- a/foreign/java/dev-support/checks/build.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" -cd "$DIR/../.." || exit 1 - -task="${1:-build}" -shift 1 -gradle "$task" "$@" -exit $? diff --git a/scripts/run-java-examples-from-readme.sh b/scripts/run-java-examples-from-readme.sh index 22a462f63c..bd91d00e04 100755 --- a/scripts/run-java-examples-from-readme.sh +++ b/scripts/run-java-examples-from-readme.sh @@ -1,5 +1,6 @@ #!/bin/bash +# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information @@ -16,6 +17,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. +# set -euo pipefail @@ -26,7 +28,7 @@ set -euo pipefail # If not provided, uses the default target # # This script scans examples/java/README.md for commands starting with -# `./gradlew` and executes them in order. If any command fails, the script +# `gradle` and executes them in order. If any command fails, the script # stops immediately and prints the relevant iggy-server logs. readonly LOG_FILE="iggy-server.log"