diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e12f48838b..8d91824be0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,29 +29,29 @@ jobs: - name: Set up Gradle uses: gradle/actions/setup-gradle@v5 - - name: Run unit tests + - name: Run unit tests (Java 23) env: USER: unittest USE_DOCKER_SERVICE: false - run: ./gradlew --no-daemon test -x spotlessCheck -x spotlessApply -x spotlessJava -P edgeDepsTest + run: ./gradlew --no-daemon test -x spotlessCheck -x spotlessApply -x spotlessJava -P edgeDepsTest -PtestJavaVersion=23 - name: Run independent resource tuner test env: USER: unittest USE_DOCKER_SERVICE: false - run: ./gradlew --no-daemon temporal-sdk:testResourceIndependent -x spotlessCheck -x spotlessApply -x spotlessJava -P edgeDepsTest + run: ./gradlew --no-daemon temporal-sdk:testResourceIndependent -x spotlessCheck -x spotlessApply -x spotlessJava -P edgeDepsTest -PtestJavaVersion=23 - name: Run Spring Boot 3 compatibility tests env: USER: unittest USE_DOCKER_SERVICE: false - run: ./gradlew --no-daemon :temporal-spring-boot-autoconfigure:test -x spotlessCheck -x spotlessApply -x spotlessJava -P edgeDepsTest -P springBoot3Test + run: ./gradlew --no-daemon :temporal-spring-boot-autoconfigure:test -x spotlessCheck -x spotlessApply -x spotlessJava -P edgeDepsTest -P springBoot3Test -PtestJavaVersion=23 - name: Run Spring Boot 4 compatibility tests env: USER: unittest USE_DOCKER_SERVICE: false - run: ./gradlew --no-daemon :temporal-spring-boot-autoconfigure:test -x spotlessCheck -x spotlessApply -x spotlessJava -P edgeDepsTest -P springBoot4Test + run: ./gradlew --no-daemon :temporal-spring-boot-autoconfigure:test -x spotlessCheck -x spotlessApply -x spotlessJava -P edgeDepsTest -P springBoot4Test -PtestJavaVersion=23 - name: Publish Test Report uses: mikepenz/action-junit-report@v6 @@ -75,8 +75,8 @@ jobs: uses: actions/setup-java@v5 with: java-version: | - 23 11 + 23 distribution: "temurin" - name: Set up Gradle @@ -113,25 +113,29 @@ jobs: --dynamic-config-value 'component.callbacks.allowedAddresses=[{"Pattern":"localhost:7243","AllowInsecure":true}]' & sleep 10s - - name: Run unit tests + # Can't actually run tests against Java 8 because Mockito 5 requires Java 11+. + # We therefore have to rely on the fact that the code has been compiled with + # `-release 8` which guarantees that the code is technically (bytecode + API + # usage) compatible with Java 8. + - name: Run unit tests (Java 11) env: USER: unittest TEMPORAL_SERVICE_ADDRESS: localhost:7233 USE_DOCKER_SERVICE: true - run: ./gradlew --no-daemon test -x spotlessCheck -x spotlessApply -x spotlessJava + run: ./gradlew --no-daemon test -x spotlessCheck -x spotlessApply -x spotlessJava -PtestJavaVersion=11 - - name: Run Jackson 3 converter tests + - name: Run Jackson 3 converter tests (Java 17) env: USER: unittest USE_DOCKER_SERVICE: false - run: ./gradlew --no-daemon :temporal-sdk:jackson3Tests -x spotlessCheck -x spotlessApply -x spotlessJava + run: ./gradlew --no-daemon :temporal-sdk:jackson3Tests -x spotlessCheck -x spotlessApply -x spotlessJava -PtestJavaVersion=17 - - name: Run virtual thread tests + - name: Run virtual thread tests (Java 21) env: USER: unittest TEMPORAL_SERVICE_ADDRESS: localhost:7233 USE_DOCKER_SERVICE: true - run: ./gradlew --no-daemon :temporal-sdk:virtualThreadTests -x spotlessCheck -x spotlessApply -x spotlessJava + run: ./gradlew --no-daemon :temporal-sdk:virtualThreadTests -x spotlessCheck -x spotlessApply -x spotlessJava -PtestJavaVersion=21 - name: Publish Test Report uses: mikepenz/action-junit-report@v6 @@ -154,7 +158,7 @@ jobs: - name: Set up Java uses: actions/setup-java@v5 with: - java-version: "11" + java-version: "23" distribution: "temurin" - name: Set up Gradle diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 4a23592c74..e9ca3e3b22 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -19,14 +19,14 @@ jobs: - name: Set up Java uses: actions/setup-java@v5 with: - java-version: '11' - distribution: 'temurin' + java-version: "23" + distribution: "temurin" - name: Set up Gradle uses: gradle/actions/setup-gradle@v5 - name: Run Tests - run: ./gradlew test -x spotlessCheck -x spotlessApply -Pjacoco + run: ./gradlew test -x spotlessCheck -x spotlessApply -Pjacoco -PtestJavaVersion=23 continue-on-error: true - name: Run Test Coverage diff --git a/.github/workflows/nightly-throughput-stress.yml b/.github/workflows/nightly-throughput-stress.yml index 8b57f5ab75..04a08d451c 100644 --- a/.github/workflows/nightly-throughput-stress.yml +++ b/.github/workflows/nightly-throughput-stress.yml @@ -89,14 +89,14 @@ jobs: - name: Set up Java uses: actions/setup-java@v5 with: - java-version: "11" + java-version: "23" distribution: "temurin" - name: Set up Gradle uses: gradle/actions/setup-gradle@v4 - name: Build SDK - run: ./gradlew build -x test -x virtualThreadTests + run: ./gradlew build -x test -x virtualThreadTests -PtestJavaVersion=23 - name: Install Temporal CLI uses: temporalio/setup-temporal@v0 diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml index 7b23be0647..68ad4cf156 100644 --- a/.github/workflows/prepare-release.yml +++ b/.github/workflows/prepare-release.yml @@ -94,7 +94,7 @@ jobs: - name: Set up Java uses: actions/setup-java@v5 with: - java-version: "11" + java-version: "23" distribution: "temurin" - name: Set up Gradle diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml index e4cc424e42..d2e2d5c8cc 100644 --- a/.github/workflows/publish-snapshot.yml +++ b/.github/workflows/publish-snapshot.yml @@ -38,7 +38,7 @@ jobs: - name: Set up Java uses: actions/setup-java@v5 with: - java-version: '11' + java-version: '23' distribution: 'temurin' - name: Set up Gradle diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index db02fef53b..5b0c1a0fd7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,14 +2,14 @@ This doc is intended for contributors to `sdk-java` (hopefully that's you!) -**Note:** All contributors also need to fill out the -[Temporal Contributor License Agreement](https://gist.github.com/samarabbas/7dcd41eb1d847e12263cc961ccfdb197) +**Note:** All contributors also need to fill out the +[Temporal Contributor License Agreement](https://gist.github.com/samarabbas/7dcd41eb1d847e12263cc961ccfdb197) before we can merge in any of your changes ## Development Environment -* Java 21+ -* Docker to run Temporal Server +- Java 23+ +- Docker to run Temporal Server ## Build @@ -31,13 +31,15 @@ commit messages. Read it, follow it, learn it, love it. ## Running features tests in CI For each PR we run the java tests from the [features repo](https://github.com/temporalio/features/). This requires -your branch to have tags. Without tags, the features tests in CI will fail with a message like +your branch to have tags. Without tags, the features tests in CI will fail with a message like + ``` > Configure project :sdk-java fatal: No names found, cannot describe anything. ``` + This can be done resolved by running `git fetch --tags` on your branch. Note, make sure your fork has tags copied from -the main repo. +the main repo. ## Test and Build @@ -62,6 +64,7 @@ Build with: ``` ## Note on Rosetta + Newer Apple Silicon macs do not ship with Rosetta by default, and the version of `protoc-gen-rpc-java` we use (1.34.1) does not ship Apple Silicon binaries. So Gradle is set to hardcode the download of the x86_64 binaries on MacOS, but this depends on Rosetta to function. Make sure Rosetta is installed with diff --git a/build.gradle b/build.gradle index 9d9df68fa0..3f7ad9187f 100644 --- a/build.gradle +++ b/build.gradle @@ -1,12 +1,5 @@ -buildscript { - ext { - palantirGitVersionVersion = "${JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_11) ? '0.15.0' : '0.13.0'}" - } -} - plugins { id 'net.ltgt.errorprone' version '4.1.0' apply false - id 'com.palantir.git-version' version "${palantirGitVersionVersion}" apply false id 'io.github.gradle-nexus.publish-plugin' version '1.3.0' id 'com.diffplug.spotless' version '7.0.2' apply false id 'com.github.nbaztec.coveralls-jacoco' version "1.2.20" apply false @@ -79,9 +72,7 @@ ext { apply from: "$rootDir/gradle/versioning.gradle" apply from: "$rootDir/gradle/java.gradle" -if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_11)) { - apply from: "$rootDir/gradle/linting.gradle" -} +apply from: "$rootDir/gradle/linting.gradle" apply from: "$rootDir/gradle/errorprone.gradle" apply from: "$rootDir/gradle/publishing.gradle" apply from: "$rootDir/gradle/dependencyManagement.gradle" diff --git a/gradle/java.gradle b/gradle/java.gradle index fbf17a925a..37db264a55 100644 --- a/gradle/java.gradle +++ b/gradle/java.gradle @@ -15,7 +15,7 @@ subprojects { compileJava { options.encoding = 'UTF-8' options.compilerArgs << '-Xlint:none' << '-Xlint:deprecation' << '-Werror' << '-parameters' - if (JavaVersion.current().isJava9Compatible() && !project.hasProperty("edgeDepsTest") && !project.hasProperty("nativeBuild")) { + if (!project.hasProperty("edgeDepsTest") && !project.hasProperty("nativeBuild")) { // https://stackoverflow.com/a/43103115/525203 options.compilerArgs.addAll(['--release', '8']) } @@ -24,7 +24,7 @@ subprojects { compileTestJava { options.encoding = 'UTF-8' options.compilerArgs << '-Xlint:none' << '-Xlint:deprecation' << '-Werror' << '-parameters' - if (JavaVersion.current().isJava9Compatible() && !project.hasProperty("edgeDepsTest") && !project.hasProperty("nativeBuild")) { + if (!project.hasProperty("edgeDepsTest") && !project.hasProperty("nativeBuild")) { // https://stackoverflow.com/a/43103115/525203 options.compilerArgs.addAll(['--release', '8']) } @@ -34,21 +34,19 @@ subprojects { options.encoding = 'UTF-8' options.addStringOption('Xdoclint:reference', '-quiet') options.addBooleanOption('Werror', true) - if (JavaVersion.current().isJava9Compatible()) { - options.addBooleanOption('html5', true) - } - if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_1_9) && - !JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_13)) { - //https://stackoverflow.com/questions/53732632/gradle-javadoc-search-redirects-to-undefined-url - //the flag is removed in java13: https://bugs.openjdk.java.net/browse/JDK-8215582 - options.addBooleanOption('-no-module-directories', true) - } + options.addBooleanOption('html5', true) } // add a collection to track failedTests ext.failedTests = [] test { + if (project.hasProperty("testJavaVersion")) { + javaLauncher = javaToolchains.launcherFor { + languageVersion = JavaLanguageVersion.of(project.property("testJavaVersion") as int) + } + } + testLogging { events 'passed', 'skipped', 'failed' exceptionFormat 'full' diff --git a/mise.toml b/mise.toml new file mode 100644 index 0000000000..dbdf2a1ebd --- /dev/null +++ b/mise.toml @@ -0,0 +1,15 @@ +# TIP +# +# For the best SDK development experience, make to hava all of the following +# JDKs installed on your machine (`mise install java@[version]`): +# - `java@temurin-11` +# - `java@temurin-17` +# - `java@temurin-23` +# +# Java 21+ is required for anything that requires gradle. +# +# If you find out that gradle isn't automatically picking it up older JDKs as +# toolchains, see https://mise.jdx.dev/lang/java.html#gradle-toolchains-detection. + +[tools] +java = "temurin-23" diff --git a/temporal-kotlin/build.gradle b/temporal-kotlin/build.gradle index d542da8d1e..fac9bfb043 100644 --- a/temporal-kotlin/build.gradle +++ b/temporal-kotlin/build.gradle @@ -12,7 +12,7 @@ tasks.withType(KotlinCompile).all { kotlinOptions { freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn" jvmTarget = project.hasProperty("edgeDepsTest") ? JavaVersion.VERSION_21 : JavaVersion.VERSION_1_8 - languageVersion = "${project.hasProperty("edgeDepsTest") ? '1.8' : (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_16) ? '1.5' : '1.4')}" + languageVersion = "${project.hasProperty("edgeDepsTest") ? '1.8' : '1.5'}" } } diff --git a/temporal-sdk/build.gradle b/temporal-sdk/build.gradle index 3f86322317..d80285ac94 100644 --- a/temporal-sdk/build.gradle +++ b/temporal-sdk/build.gradle @@ -66,28 +66,10 @@ dependencies { } tasks.named('compileJava17Java') { - // Gradle toolchains are too strict and require the JDK to match the specified version exactly. - // This is a workaround to use a JDK 17+ compiler. - // - // See also: https://github.com/gradle/gradle/issues/16256 - if (!JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_17)) { - javaCompiler = javaToolchains.compilerFor { - languageVersion = JavaLanguageVersion.of(17) - } - } options.release = 17 } tasks.named('compileJava21Java') { - // Gradle toolchains are too strict and require the JDK to match the specified version exactly. - // This is a workaround to use a JDK 21+ compiler. - // - // See also: https://github.com/gradle/gradle/issues/16256 - if (!JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_21)) { - javaCompiler = javaToolchains.compilerFor { - languageVersion = JavaLanguageVersion.of(21) - } - } options.release = 21 } @@ -142,9 +124,7 @@ test { // the present-java17-but-absent-jackson3 behavior (NoClassDefFoundError) in the same // test that tests the Java 8 stub behavior (UnsupportedOperationException). tasks.withType(Test).configureEach { - if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_17)) { - dependsOn compileJava17Java - } + dependsOn compileJava17Java doFirst { int launcherMajorVersion = javaLauncher.get().metadata.languageVersion.asInt() if (launcherMajorVersion >= 17) { diff --git a/temporal-workflowcheck/samples/gradle/build.gradle b/temporal-workflowcheck/samples/gradle/build.gradle index 3c99253540..0631d8f554 100644 --- a/temporal-workflowcheck/samples/gradle/build.gradle +++ b/temporal-workflowcheck/samples/gradle/build.gradle @@ -29,10 +29,10 @@ dependencies { tasks.register('workflowcheck', JavaExec) { // Set the classpath to the workflowcheck dependency classpath = configurations.workflowcheckDependency - // // Java 17+ is required for workflowcheck - // javaLauncher = javaToolchains.launcherFor { - // languageVersion = JavaLanguageVersion.of(17) - // } + // Java 17+ is required for workflowcheck + javaLauncher = javaToolchains.launcherFor { + languageVersion = JavaLanguageVersion.of(17) + } // The argument to workflowcheck is the classpath mainClass = 'io.temporal.workflowcheck.Main' args = ['check', sourceSets.main.runtimeClasspath.files.join(File.pathSeparator)]