diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b25c8a08a2..7577181def 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -46,10 +46,19 @@ jobs: - uses: actions/checkout@v3 with: fetch-depth: 50 - - name: Set up Java ${{ matrix.java_version }}, ${{ matrix.java_distribution }} + - name: Set up Java ${{ matrix.java_version }}, oracle + if: ${{ matrix.oracle_java_website != '' }} + uses: oracle-actions/setup-java@1611a647972adb8b04779be3529a044d650fd510 # v1 + with: + website: ${{ matrix.oracle_java_website }} + release: ${{ matrix.java_version }} + - name: Set up Java 17 and ${{ matrix.non_ea_java_version }}, ${{ matrix.java_distribution }} uses: actions/setup-java@v3 with: - java-version: ${{ matrix.java_version }} + # The latest one will be the default, so we use Java 17 for launching Gradle + java-version: | + ${{ matrix.non_ea_java_version }} + 17 distribution: ${{ matrix.java_distribution }} architecture: x64 - name: Steps to reproduce @@ -68,6 +77,11 @@ jobs: properties: | testExtraJvmArgs=${{ matrix.testExtraJvmArgs }} testDisableCaching=${{ matrix.testDisableCaching }} + jdkBuildVersion=17 + jdkTestVersion=${{ matrix.java_version }} + jdkTestVendor=${{ matrix.java_vendor }} + # We provision JDKs with GitHub Actions for caching purposes, so Gradle should rather fail in case JDK is not found + org.gradle.java.installations.auto-download=false env: _JAVA_OPTIONS: ${{ matrix.extraJvmArgs }} GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_ACCESS_TOKEN }} diff --git a/.github/workflows/matrix.js b/.github/workflows/matrix.js index 20c32abeb7..1a75468db3 100644 --- a/.github/workflows/matrix.js +++ b/.github/workflows/matrix.js @@ -8,16 +8,18 @@ const matrix = new MatrixBuilder(); matrix.addAxis({ name: 'java_distribution', values: [ - {value: 'corretto', weight: 1}, - {value: 'liberica', weight: 1}, - {value: 'microsoft', weight: 1}, - {value: 'oracle', weight: 1}, - {value: 'semeru', weight: 4}, - {value: 'temurin', weight: 1}, - {value: 'zulu', weight: 1}, + {value: 'corretto', vendor: 'amazon', weight: 1}, + {value: 'liberica', vendor: 'bellsoft', weight: 1}, + {value: 'microsoft', vendor: 'microsoft', weight: 1}, + {value: 'oracle', vendor: 'oracle', weight: 1}, + {value: 'semeru', vendor: 'ibm', weight: 4}, + {value: 'temurin', vendor: 'eclipse', weight: 1}, + {value: 'zulu', vendor: 'azul', weight: 1}, ] }); +const eaJava = '21'; + matrix.addAxis({ name: 'java_version', // Strings allow versions like 18-ea @@ -25,6 +27,7 @@ matrix.addAxis({ '8', '11', '17', + eaJava, ] }); @@ -74,10 +77,13 @@ matrix.setNamePattern(['java_version', 'java_distribution', 'hash', 'os', 'tz', // Semeru uses OpenJ9 jit which has no option for making hash codes the same matrix.exclude({java_distribution: {value: 'semeru'}, hash: {value: 'same'}}); +// Semeru 8 fails when Semeru 17 is on the PATH (we use 17 for build) +matrix.exclude({java_distribution: {value: 'semeru'}, java_version: '8'}); // Microsoft Java has no distribution for 8 matrix.exclude({java_distribution: {value: 'microsoft'}, java_version: '8'}); // Oracle JDK is only supported for JDK 17 and later matrix.exclude({java_distribution: {value: 'oracle'}, java_version: ['8', '11']}); +matrix.imply({java_version: eaJava}, {java_distribution: {value: 'oracle'}}) // Ensure at least one job with "same" hashcode exists matrix.generateRow({hash: {value: 'same'}}); // Ensure at least one Windows and at least one Linux job is present (macOS is almost the same as Linux) @@ -90,6 +96,8 @@ matrix.generateRow({java_version: "8"}); matrix.generateRow({java_version: "11"}); // Ensure there will be at least one job with Java 17 matrix.generateRow({java_version: "17"}); +// Ensure there will be at least one job with Java EA +matrix.generateRow({java_version: eaJava}); const include = matrix.generateRows(process.env.MATRIX_JOBS || 5); if (include.length === 0) { throw new Error('Matrix list is empty'); @@ -124,9 +132,14 @@ include.forEach(v => { jvmArgs.push(`-Duser.country=${v.locale.country}`); jvmArgs.push(`-Duser.language=${v.locale.language}`); v.java_distribution = v.java_distribution.value; + v.java_vendor = v.java_distribution.vendor; + if (v.java_distribution === 'oracle') { + v.oracle_java_website = v.java_version === eaJava ? 'jdk.java.net' : 'oracle.com'; + } + v.non_ea_java_version = v.java_version === eaJava ? '' : v.java_version; if (v.java_distribution !== 'semeru' && Math.random() > 0.5) { // The following options randomize instruction selection in JIT compiler - // so it might reveal missing synchronization in TestNG code + // so it might reveal missing synchronization v.name += ', stress JIT'; v.testDisableCaching = 'JIT randomization should not be cached'; jvmArgs.push('-XX:+UnlockDiagnosticVMOptions'); diff --git a/.github/workflows/matrix_builder.js b/.github/workflows/matrix_builder.js index fd765117e8..0c17190ede 100644 --- a/.github/workflows/matrix_builder.js +++ b/.github/workflows/matrix_builder.js @@ -18,7 +18,7 @@ class Axis { } if (Array.isArray(filter)) { // e.g. row={os: 'windows'}; filter=[{os: 'linux'}, {os: 'linux'}] - return filter.find(v => Axis.matches(row, v)); + return filter.some(v => Axis.matches(row, v)); } if (typeof filter === 'object') { // e.g. row={jdk: {name: 'openjdk', version: 8}}; filter={jdk: {version: 8}} @@ -68,6 +68,7 @@ class MatrixBuilder { this.duplicates = {}; this.excludes = []; this.includes = []; + this.implications = []; this.failOnUnsatisfiableFilters = false; } @@ -80,13 +81,23 @@ class MatrixBuilder { } /** - * Specifies exclude filter (e.g. exclude a forbidden combination) + * Specifies exclude filter (e.g. exclude a forbidden combination). * @param filter */ exclude(filter) { this.excludes.push(filter); } + /** + * Adds implication like `antecedent -> consequent`. + * In other words, if `antecedent` holds, then `consequent` must also hold. + * @param antecedent + * @param consequent + */ + imply(antecedent, consequent) { + this.implications.push({antecedent: antecedent, consequent: consequent}); + } + addAxis({name, title, values}) { const axis = new Axis({name, title, values}); this.axes.push(axis); @@ -104,8 +115,10 @@ class MatrixBuilder { * @returns {boolean} */ matches(row) { - return (this.excludes.length === 0 || !this.excludes.find(f => Axis.matches(row, f))) && - (this.includes.length === 0 || this.includes.find(f => Axis.matches(row, f))); + return (this.excludes.length === 0 || !this.excludes.some(f => Axis.matches(row, f))) && + (this.includes.length === 0 || this.includes.some(f => Axis.matches(row, f))) && + (this.implications.length === 0 || ( + this.implications.every(i => !Axis.matches(row, i.antecedent) || Axis.matches(row, i.consequent)))); } failOnUnsatisfiableFilters(value) { @@ -125,7 +138,7 @@ class MatrixBuilder { let res; if (filter) { // If matching row already exists, no need to generate more - res = this.rows.find(v => Axis.matches(v, filter)); + res = this.rows.some(v => Axis.matches(v, filter)); if (res) { return res; } diff --git a/README.md b/README.md index 1255834304..711bc5f9b9 100644 --- a/README.md +++ b/README.md @@ -175,7 +175,12 @@ systemProp.https.proxyPassword=your_password ### Test builds -JMeter is built using Gradle. +JMeter is built using Gradle, and it uses [Gradle's Toolchains for JVM projects](https://docs.gradle.org/current/userguide/toolchains.html) +for provisioning JDKs. It means the code would search for the needed JDKs locally, or download them +if they are not found. + +By default, the code would use JDK 17 for build purposes, however it would set the target release to 8, +so the resulting artifacts would be compatible with Java 8. The following command builds and tests JMeter: @@ -183,6 +188,15 @@ The following command builds and tests JMeter: ./gradlew build ``` +If you want to use a custom JDK for building you can set `-PjdkBuildVersion=11`, +and you can select `-PjdkTestVersion=21` if you want to use a different JDK for testing. + +You can list the available build parameters by executing + +```sh +./gradlew parameters +``` + If the system does not have a GUI display then: ```sh @@ -196,7 +210,7 @@ The following command would compile the application and enable you to run `jmete from the `bin` directory. > **Note** that it completely refreshes `lib/` contents, -so it would remove custom plugins should you have them installed. +so it would remove custom plugins should you have them installed to `lib/`. However, it would keep `lib/ext/` plugins intact. ```sh ./gradlew createDist diff --git a/build-logic/basics/build.gradle.kts b/build-logic/basics/build.gradle.kts index d8c115622b..a6dfaea589 100644 --- a/build-logic/basics/build.gradle.kts +++ b/build-logic/basics/build.gradle.kts @@ -18,3 +18,7 @@ plugins { id("build-logic.kotlin-dsl-gradle-plugin") } + +dependencies { + api(projects.buildParameters) +} diff --git a/build-logic/basics/src/main/kotlin/ToolchainProperties.kt b/build-logic/basics/src/main/kotlin/ToolchainProperties.kt new file mode 100644 index 0000000000..d5b0c201e3 --- /dev/null +++ b/build-logic/basics/src/main/kotlin/ToolchainProperties.kt @@ -0,0 +1,37 @@ +/* + * 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. + */ + +import buildparameters.BuildParametersExtension +import org.gradle.api.JavaVersion + +class ToolchainProperties( + val version: Int, + val vendor: String?, + val implementation: String?, +) + +val BuildParametersExtension.buildJdk: ToolchainProperties? + get() = jdkBuildVersion.takeIf { it != 0 } + ?.let { ToolchainProperties(it, jdkBuildVendor.orNull, jdkBuildImplementation.orNull) } + +val BuildParametersExtension.buildJdkVersion: Int + get() = buildJdk?.version ?: JavaVersion.current().majorVersion.toInt() + +val BuildParametersExtension.testJdk: ToolchainProperties? + get() = jdkTestVersion.orNull?.takeIf { it != 0 } + ?.let { ToolchainProperties(it, jdkTestVendor.orNull, jdkTestImplementation.orNull) } + ?: buildJdk diff --git a/build-logic/basics/src/main/kotlin/configureToolchain.kt b/build-logic/basics/src/main/kotlin/configureToolchain.kt new file mode 100644 index 0000000000..d797e7c4d6 --- /dev/null +++ b/build-logic/basics/src/main/kotlin/configureToolchain.kt @@ -0,0 +1,41 @@ +/* + * 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. + */ + +import org.gradle.api.provider.Provider +import org.gradle.jvm.toolchain.JavaLanguageVersion +import org.gradle.jvm.toolchain.JavaLauncher +import org.gradle.jvm.toolchain.JavaToolchainService +import org.gradle.jvm.toolchain.JavaToolchainSpec +import org.gradle.jvm.toolchain.JvmImplementation +import org.gradle.jvm.toolchain.JvmVendorSpec + +fun JavaToolchainService.launcherFor(jdk: ToolchainProperties): Provider = launcherFor { + configureToolchain(jdk) +} + +fun JavaToolchainSpec.configureToolchain(jdk: ToolchainProperties?) { + if (jdk == null) { + return + } + languageVersion.set(JavaLanguageVersion.of(jdk.version)) + jdk.vendor?.let { + vendor.set(JvmVendorSpec.matching(it)) + } + if (jdk.implementation.equals("J9", ignoreCase = true)) { + implementation.set(JvmImplementation.J9) + } +} diff --git a/build-logic/build-parameters/build.gradle.kts b/build-logic/build-parameters/build.gradle.kts index b160323b60..bd0c6c6d80 100644 --- a/build-logic/build-parameters/build.gradle.kts +++ b/build-logic/build-parameters/build.gradle.kts @@ -29,10 +29,39 @@ buildParameters { defaultValue.set(true) description.set("Add mavenLocal() to repositories") } + bool("enableJavaFx") { + defaultValue.set(false) + description.set("Build and include classes that depend on JavaFX. Disabled by default since JavaFX is not included in the default Java distributions") + } bool("coverage") { defaultValue.set(false) description.set("Collect test coverage") } + integer("targetJavaVersion") { + defaultValue.set(8) + mandatory.set(true) + description.set("Java version for source and target compatibility") + } + integer("jdkBuildVersion") { + defaultValue.set(17) + mandatory.set(true) + description.set("JDK version to use for building JMeter. If the value is 0, then the current Java is used. (see https://docs.gradle.org/8.0/userguide/toolchains.html#sec:consuming)") + } + string("jdkBuildVendor") { + description.set("JDK vendor to use building JMeter (see https://docs.gradle.org/8.0/userguide/toolchains.html#sec:vendors)") + } + string("jdkBuildImplementation") { + description.set("Vendor-specific virtual machine implementation to use building JMeter (see https://docs.gradle.org/8.0/userguide/toolchains.html#selecting_toolchains_by_virtual_machine_implementation)") + } + integer("jdkTestVersion") { + description.set("JDK version to use for testing JMeter. If the value is 0, then the current Java is used. (see https://docs.gradle.org/8.0/userguide/toolchains.html#sec:consuming)") + } + string("jdkTestVendor") { + description.set("JDK vendor to use testing JMeter (see https://docs.gradle.org/8.0/userguide/toolchains.html#sec:vendors)") + } + string("jdkTestImplementation") { + description.set("Vendor-specific virtual machine implementation to use testing JMeter (see https://docs.gradle.org/8.0/userguide/toolchains.html#selecting_toolchains_by_virtual_machine_implementation)") + } bool("spotbugs") { defaultValue.set(false) description.set("Run SpotBugs verifications") diff --git a/build-logic/jvm/src/main/kotlin/build-logic.groovy.gradle.kts b/build-logic/jvm/src/main/kotlin/build-logic.groovy.gradle.kts index 976a9a3cd8..1acd72cc94 100644 --- a/build-logic/jvm/src/main/kotlin/build-logic.groovy.gradle.kts +++ b/build-logic/jvm/src/main/kotlin/build-logic.groovy.gradle.kts @@ -15,8 +15,20 @@ * limitations under the License. */ +import com.github.vlsi.gradle.dsl.configureEach + plugins { id("java") id("groovy") id("build-logic.test-spock") + id("com.github.vlsi.gradle-extensions") + id("build-logic.build-params") +} + +tasks.configureEach { + buildParameters.testJdk?.let { + javaLauncher.convention(javaToolchains.launcherFor(it)) + } + // Support jdk-release to configure the target Java release when compiling the bytecode + // See https://issues.apache.org/jira/browse/GROOVY-11105 } diff --git a/build-logic/jvm/src/main/kotlin/build-logic.java.gradle.kts b/build-logic/jvm/src/main/kotlin/build-logic.java.gradle.kts index df91b33dd1..01ad87f1dc 100644 --- a/build-logic/jvm/src/main/kotlin/build-logic.java.gradle.kts +++ b/build-logic/jvm/src/main/kotlin/build-logic.java.gradle.kts @@ -33,8 +33,9 @@ plugins { } java { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + toolchain { + configureToolchain(buildParameters.buildJdk) + } consistentResolution { useCompileClasspathVersions() } @@ -44,11 +45,25 @@ tasks.configureEach { // Use --release=8 for Java 10+ so the generated bytecode does not include methods introduced in Java 9+ options.release.set( provider { - 8.takeIf { javaCompiler.get().metadata.languageVersion.asInt() > 9 } + buildParameters.targetJavaVersion.takeIf { + javaCompiler.get().metadata.languageVersion.asInt() > 9 + } } ) } +tasks.configureEach { + buildParameters.testJdk?.let { + javaLauncher.convention(javaToolchains.launcherFor(it)) + } +} + +tasks.configureEach { + buildParameters.buildJdk?.let { + javaLauncher.convention(javaToolchains.launcherFor(it)) + } +} + dependencies { findProject(":src:bom")?.let { api(platform(it)) @@ -116,7 +131,7 @@ tasks.configureEach { val lastEditYear: String by rootProject.extra bottom = "Copyright © 1998-$lastEditYear Apache Software Foundation. All Rights Reserved." - if (JavaVersion.current() >= JavaVersion.VERSION_1_9) { + if (buildParameters.buildJdkVersion > 8) { addBooleanOption("html5", true) links("https://docs.oracle.com/en/java/javase/11/docs/api/") } else { diff --git a/build-logic/jvm/src/main/kotlin/build-logic.kotlin.gradle.kts b/build-logic/jvm/src/main/kotlin/build-logic.kotlin.gradle.kts index 628bbda55e..ca509a7c33 100644 --- a/build-logic/jvm/src/main/kotlin/build-logic.kotlin.gradle.kts +++ b/build-logic/jvm/src/main/kotlin/build-logic.kotlin.gradle.kts @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { id("java-library") + id("build-logic.build-params") id("build-logic.java") id("build-logic.test-base") id("com.github.autostyle") @@ -36,6 +37,9 @@ kotlin { if (props.bool("kotlin.explicitApi", default = true)) { explicitApi() } + jvmToolchain { + configureToolchain(buildParameters.buildJdk) + } } tasks.configureEach { @@ -44,7 +48,19 @@ tasks.configureEach { apiVersion = "kotlin.api".v } freeCompilerArgs += "-Xjvm-default=all" - jvmTarget = java.targetCompatibility.toString() + val jdkRelease = buildParameters.targetJavaVersion.let { + when { + it < 9 -> "1.8" + else -> it.toString() + } + } + // jdk-release requires Java 9+ + buildParameters.buildJdkVersion + .takeIf { it > 8 } + ?.let { + freeCompilerArgs += "-Xjdk-release=$jdkRelease" + } + kotlinOptions.jvmTarget = jdkRelease } } diff --git a/build-logic/jvm/src/main/kotlin/build-logic.test-base.gradle.kts b/build-logic/jvm/src/main/kotlin/build-logic.test-base.gradle.kts index 1f92a9c96c..830174dca2 100644 --- a/build-logic/jvm/src/main/kotlin/build-logic.test-base.gradle.kts +++ b/build-logic/jvm/src/main/kotlin/build-logic.test-base.gradle.kts @@ -17,13 +17,12 @@ import com.github.vlsi.gradle.dsl.configureEach import com.github.vlsi.gradle.properties.dsl.props -import org.gradle.api.JavaVersion import org.gradle.api.tasks.testing.Test import org.gradle.api.tasks.testing.logging.TestExceptionFormat -import org.gradle.kotlin.dsl.project plugins { id("java-library") + id("build-logic.build-params") } dependencies { @@ -37,6 +36,9 @@ tasks.configureEach { exceptionFormat = TestExceptionFormat.FULL showStandardStreams = true } + buildParameters.testJdk?.let { + javaLauncher.convention(javaToolchains.launcherFor(it)) + } // Pass the property to tests fun passProperty(name: String, default: String? = null) { val value = System.getProperty(name) ?: default @@ -57,9 +59,22 @@ tasks.configureEach { } passProperty("java.awt.headless") passProperty("skip.test_TestDNSCacheManager.testWithCustomResolverAnd1Server") - // Spock tests use cglib proxies that access ClassLoader.defineClass reflectively + // Enable testing ByteBuddy with EA Java versions + passProperty("net.bytebuddy.experimental", "true") + // Spock tests use cglib proxies that access ClassLoader.defineClass reflectively, + // So we pass --add-opens // See https://github.com/apache/jmeter/pull/5763 - if (JavaVersion.current().isJava9Compatible) { - jvmArgs("--add-opens=java.base/java.lang=ALL-UNNAMED") - } + jvmArgumentProviders += AddOpensArgumentsProvider(javaLauncher.map { it.metadata.languageVersion }) +} + +class AddOpensArgumentsProvider( + @Input val javaLanguageVersion: Provider +): CommandLineArgumentProvider { + override fun asArguments(): Iterable = + if (javaLanguageVersion.get().asInt() <= 8) { + // Jave 1.8 does not need add-opens, so we omit it + listOf() + } else { + listOf("--add-opens=java.base/java.lang=ALL-UNNAMED") + } } diff --git a/build-logic/root-build/src/main/kotlin/build-logic.root-build.gradle.kts b/build-logic/root-build/src/main/kotlin/build-logic.root-build.gradle.kts index 7fcb96ff8d..fd2f72337e 100644 --- a/build-logic/root-build/src/main/kotlin/build-logic.root-build.gradle.kts +++ b/build-logic/root-build/src/main/kotlin/build-logic.root-build.gradle.kts @@ -66,3 +66,9 @@ if (buildParameters.coverage) { } } } + +tasks.register("parameters") { + group = HelpTasksPlugin.HELP_GROUP + description = "Displays the supported build parameters." + dependsOn(gradle.includedBuild("build-logic").task(":build-parameters:parameters")) +} diff --git a/build-logic/verification/src/main/kotlin/build-logic.checkerframework.gradle.kts b/build-logic/verification/src/main/kotlin/build-logic.checkerframework.gradle.kts index 1b682cd747..88ac070c2e 100644 --- a/build-logic/verification/src/main/kotlin/build-logic.checkerframework.gradle.kts +++ b/build-logic/verification/src/main/kotlin/build-logic.checkerframework.gradle.kts @@ -15,10 +15,10 @@ * limitations under the License. */ -import org.gradle.api.JavaVersion import org.gradle.kotlin.dsl.dependencies plugins { + id("build-logic.build-params") id("org.checkerframework") } @@ -28,14 +28,14 @@ dependencies { ?.let { val checkerframeworkVersion = it.get() "checkerFramework"("org.checkerframework:checker:$checkerframeworkVersion") - if (JavaVersion.current() == JavaVersion.VERSION_1_8) { + if (buildParameters.buildJdkVersion == 8) { // only needed for JDK 8 "checkerFrameworkAnnotatedJDK"("org.checkerframework:jdk8:$checkerframeworkVersion") } } ?: run { val checkerframeworkVersion = "3.34.0" "checkerFramework"("org.checkerframework:checker:$checkerframeworkVersion") - if (JavaVersion.current() == JavaVersion.VERSION_1_8) { + if (buildParameters.buildJdkVersion == 8) { // only needed for JDK 8 "checkerFrameworkAnnotatedJDK"("org.checkerframework:jdk8:$checkerframeworkVersion") } diff --git a/build-logic/verification/src/main/kotlin/build-logic.style.gradle.kts b/build-logic/verification/src/main/kotlin/build-logic.style.gradle.kts index c36a060738..fa56eaa38f 100644 --- a/build-logic/verification/src/main/kotlin/build-logic.style.gradle.kts +++ b/build-logic/verification/src/main/kotlin/build-logic.style.gradle.kts @@ -28,7 +28,7 @@ if (!buildParameters.skipAutostyle) { val skipCheckstyle = buildParameters.skipCheckstyle || run { logger.info("Checkstyle requires Java 11+") - !JavaVersion.current().isJava11Compatible + buildParameters.buildJdkVersion < 11 } if (!skipCheckstyle) { diff --git a/gradle.md b/gradle.md index 048b50580e..24b0aed5e1 100644 --- a/gradle.md +++ b/gradle.md @@ -24,7 +24,7 @@ Useful commands (`gw` comes from https://github.com/dougborg/gdub, otherwise `./ ## List available build parameters # List all build parameters - gw :build-logic:build-parameters:parameters + gw parameters ## Cleaning build directories diff --git a/settings.gradle.kts b/settings.gradle.kts index 1c613ef91b..b28f8fce77 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -27,6 +27,7 @@ pluginManagement { plugins { id("com.gradle.enterprise") version "3.13.2" id("com.gradle.common-custom-user-data-gradle-plugin") version "1.10" + id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0" } dependencyResolutionManagement { @@ -164,6 +165,10 @@ val expectedSha512 = mapOf( to "okhttp-4.1.0.jar", "93E7A41BE44CC17FB500EA5CD84D515204C180AEC934491D11FC6A71DAEA761FB0EECEF865D6FD5C3D88AAF55DCE3C2C424BE5BA5D43BEBF48D05F1FA63FA8A7" to "okio-2.2.2.jar", + "B9F87DECE28EABCCEDA58C77C3B602AEAE7A8AEF3D30DA838F4924A620B18C05D9DF86C5876BDE8AB5597C8C0CE808AD083CAF89C3A5AAC60C1E980C6C144A17" + to "foojay-resolver-0.5.0.jar", + "10BF91C79AB151B684834E3CA8BA7D7E19742A3EEB580BDE690FBA433F9FFFE3ABBD79ED3FE3F97986C3A2BADC4D14E28835A8EF89167B4B9CC6014242338769" + to "gson-2.9.1.jar", settings.extra["com.github.vlsi.checksum-dependency.sha512"].toString() to "checksum-dependency-plugin.jar" ) diff --git a/src/bom-testing/build.gradle.kts b/src/bom-testing/build.gradle.kts index 272decda05..bd4ecf3265 100644 --- a/src/bom-testing/build.gradle.kts +++ b/src/bom-testing/build.gradle.kts @@ -39,6 +39,7 @@ dependencies { // to make runtime classpath consistent with the compile one. api("com.github.tomakehurst:wiremock-jre8:2.35.0") api("junit:junit:4.13.2") + api("net.bytebuddy:byte-buddy:1.14.5") api("nl.jqno.equalsverifier:equalsverifier:3.14.1") // activemq-all should not be used as it provides secondary slf4j binding api("org.apache.activemq:activemq-broker:5.16.6") diff --git a/src/components/build.gradle.kts b/src/components/build.gradle.kts index 272bf4cdb1..05a51f2efe 100644 --- a/src/components/build.gradle.kts +++ b/src/components/build.gradle.kts @@ -16,6 +16,7 @@ */ plugins { + id("build-logic.build-params") id("build-logic.jvm-published-library") } @@ -88,25 +89,7 @@ dependencies { testImplementation(testFixtures(projects.src.testkitWiremock)) } -fun String?.toBool(nullAs: Boolean, blankAs: Boolean, default: Boolean) = - when { - this == null -> nullAs - isBlank() -> blankAs - default -> !equals("false", ignoreCase = true) - else -> equals("true", ignoreCase = true) - } - -fun classExists(name: String) = - try { - Class.forName(name) - true - } catch (e: Throwable) { - false - } - -if (!(project.findProperty("enableJavaFx") as? String) - .toBool(nullAs = classExists("javafx.application.Platform"), blankAs = true, default = false) -) { +if (!buildParameters.enableJavaFx) { // JavaFX is not present in Maven Central, so exclude the file unless explicitly asked by // -PenableJavaFx logger.lifecycle("RenderInBrowser is excluded from compilation. If you want to compile it, add -PenableJavaFx") diff --git a/src/dist/build.gradle.kts b/src/dist/build.gradle.kts index 000f95af26..a41d732dd7 100644 --- a/src/dist/build.gradle.kts +++ b/src/dist/build.gradle.kts @@ -632,6 +632,9 @@ val runGui by tasks.registering(JavaExec::class) { group = "Development" description = "Builds and starts JMeter GUI" dependsOn(createDist) + buildParameters.testJdk?.let { + javaLauncher.set(javaToolchains.launcherFor(it)) + } workingDir = File(project.rootDir, "bin") mainClass.set("org.apache.jmeter.NewDriver") diff --git a/xdocs/changes.xml b/xdocs/changes.xml index 799b20e8a8..d87170a6fe 100644 --- a/xdocs/changes.xml +++ b/xdocs/changes.xml @@ -102,6 +102,7 @@ Summary Non-functional changes
  • 6000Add release-drafter for populating GitHub releases info based on the merged PRs
  • +
  • 5989Use Gradle toolchains for JDK provisioning, enable building and testing with different JDKs, start testing with Java 21