From f6bcee4cea392f5bdf18b3abe5b93ad64584c83c Mon Sep 17 00:00:00 2001 From: Andras Katona Date: Fri, 31 Jan 2025 15:25:59 +0100 Subject: [PATCH] Java 17 support Signed-off-by: Andras Katona --- .github/workflows/ci.yaml | 4 ++-- README.md | 4 ++-- build.gradle | 22 +++++++++++++++---- .../BrokerCapacityConfigFileResolver.java | 6 +++-- .../config/BrokerSetFileResolver.java | 6 +++-- .../AbstractBrokerFailureDetector.java | 3 ++- .../analyzer/RemoveDisksTest.java | 2 +- gradle/findbugs-exclude.xml | 4 ++++ 8 files changed, 37 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index fb450d9c81..73030409ae 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -17,7 +17,7 @@ jobs: strategy: fail-fast: false matrix: - java-ver: [11] + java-ver: [11, 17] java-dist: ['microsoft', 'temurin'] steps: - uses: actions/checkout@v4 @@ -39,7 +39,7 @@ jobs: strategy: fail-fast: false matrix: - java-ver: [11] + java-ver: [11, 17] java-dist: ['microsoft', 'temurin'] steps: - uses: actions/checkout@v4 diff --git a/README.md b/README.md index 7a396320e0..0292258c9c 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ Cruise Control for Apache Kafka * The `kafka_2_0_to_2_3` and `kafka_0_11_and_1_0` branches compile with `Scala 2.11`. * The branch `migrate_to_kafka_2_4` compiles with `Scala 2.12`. * The branch `migrate_to_kafka_2_5` compile with `Scala 2.13`. -* This project requires Java 11. +* This project requires Java 11, also compatible with Java 17. #### Known Compatibility Issues #### * Support for Apache Kafka `2.0`, `2.1`, `2.2`, and `2.3` requires [KAFKA-8875](https://issues.apache.org/jira/browse/KAFKA-8875) hotfix. @@ -77,7 +77,7 @@ Cruise Control for Apache Kafka && git tag -a 0.1.10 -m "Init local version."` 1. This step is required if `CruiseControlMetricsReporter` is used for metrics collection (i.e. the default for Cruise Control). The metrics reporter periodically samples the Kafka raw metrics on the broker and sends them to a Kafka topic. - * `./gradlew jar` (Note: This project requires Java 11) + * `./gradlew jar` (Note: This project requires Java 11 or 17) * Copy `./cruise-control-metrics-reporter/build/libs/cruise-control-metrics-reporter-A.B.C.jar` (Where `A.B.C` is the version of the Cruise Control) to your Kafka server dependency jar folder. For Apache Kafka, the folder would be `core/build/dependant-libs-SCALA_VERSION/` (for a Kafka source checkout) or `libs/` (for a Kafka release download). diff --git a/build.gradle b/build.gradle index 32406db499..4479642083 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ plugins { id "idea" id "jacoco" // Java Code Coverage plugin id "com.github.ben-manes.versions" version "0.42.0" - id "com.github.spotbugs" version "6.0.6" apply false + id "com.github.spotbugs" version "6.0.25" apply false id "checkstyle" id "org.openapi.generator" version "5.3.0" } @@ -45,6 +45,18 @@ project.ext { buildVersionFileName = "cruise-control-version.properties" commitId = project.hasProperty('commitId') ? commitId : null scalaBinaryVersion = getScalaBinaryVersion(scalaVersion) + + defaultTestJvmArgs = [] + // "JEP 403: Strongly Encapsulate JDK Internals" causes some tests to fail when they try + // to access internals (often via mocking libraries). We use `--add-opens` as a workaround + if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_16)) + defaultTestJvmArgs.addAll( + "--add-opens=java.base/java.lang.reflect=ALL-UNNAMED", + "--add-opens=java.base/java.lang=ALL-UNNAMED", + "--add-opens=java.base/java.time=ALL-UNNAMED", + "--add-opens=java.base/java.util.concurrent=ALL-UNNAMED", + "--add-opens=java.base/java.util=ALL-UNNAMED" + ) } allprojects { @@ -104,7 +116,7 @@ subprojects { } spotbugs { - toolVersion = '4.7.1' + toolVersion = '4.8.6' excludeFilter = file("$rootDir/gradle/findbugs-exclude.xml") ignoreFailures = false jvmArgs = [ '-Xms512m' ] @@ -137,6 +149,8 @@ subprojects { } test { + jvmArgs += defaultTestJvmArgs + useJUnit {} testLogging { events "passed", "failed", "skipped" @@ -175,7 +189,7 @@ project(':cruise-control-core') { implementation "org.apache.logging.log4j:log4j-slf4j-impl:2.17.2" implementation 'org.apache.commons:commons-math3:3.6.1' api "org.eclipse.jetty:jetty-servlet:${jettyVersion}" - implementation 'com.google.code.findbugs:jsr305:3.0.2' + implementation 'com.github.spotbugs:spotbugs-annotations:4.8.6' api "io.vertx:vertx-core:${vertxVersion}" api "io.vertx:vertx-web:${vertxVersion}" @@ -311,7 +325,7 @@ project(':cruise-control') { testImplementation project(path: ':cruise-control-core', configuration: 'testOutput') testImplementation "org.scala-lang:scala-library:$scalaVersion" testImplementation 'junit:junit:4.13.2' - testImplementation 'org.easymock:easymock:4.3' + testImplementation 'org.easymock:easymock:5.5.0' testImplementation "org.apache.kafka:kafka_$scalaBinaryVersion:$kafkaVersion:test" testImplementation "org.apache.kafka:kafka-clients:$kafkaVersion:test" testImplementation 'commons-io:commons-io:2.11.0' diff --git a/cruise-control/src/main/java/com/linkedin/kafka/cruisecontrol/config/BrokerCapacityConfigFileResolver.java b/cruise-control/src/main/java/com/linkedin/kafka/cruisecontrol/config/BrokerCapacityConfigFileResolver.java index 098b137ec1..2e50bf492d 100644 --- a/cruise-control/src/main/java/com/linkedin/kafka/cruisecontrol/config/BrokerCapacityConfigFileResolver.java +++ b/cruise-control/src/main/java/com/linkedin/kafka/cruisecontrol/config/BrokerCapacityConfigFileResolver.java @@ -298,8 +298,10 @@ private void loadCapacities() throws FileNotFoundException { Set brokerCapacities = ((BrokerCapacities) gson.fromJson(reader, BrokerCapacities.class)).brokerCapacities; capacitiesForBrokers = new HashMap<>(); Set numCoresConfigConsistency = new HashSet<>(); - for (BrokerCapacity bc : brokerCapacities) { - capacitiesForBrokers.put(bc.brokerId, getBrokerCapacityInfo(bc, numCoresConfigConsistency)); + if (brokerCapacities != null) { + for (BrokerCapacity bc : brokerCapacities) { + capacitiesForBrokers.put(bc.brokerId, getBrokerCapacityInfo(bc, numCoresConfigConsistency)); + } } } finally { try { diff --git a/cruise-control/src/main/java/com/linkedin/kafka/cruisecontrol/config/BrokerSetFileResolver.java b/cruise-control/src/main/java/com/linkedin/kafka/cruisecontrol/config/BrokerSetFileResolver.java index e5fb752763..6d098f2ad7 100644 --- a/cruise-control/src/main/java/com/linkedin/kafka/cruisecontrol/config/BrokerSetFileResolver.java +++ b/cruise-control/src/main/java/com/linkedin/kafka/cruisecontrol/config/BrokerSetFileResolver.java @@ -84,8 +84,10 @@ private Map> loadBrokerSetData() throws IOException { final BrokerSets brokerSets = gson.fromJson(reader, BrokerSets.class); final Set brokerSetSet = brokerSets.brokerSets; final Map> brokerIdsByBrokerSetId = new HashMap<>(); - for (BrokerSet brokerSet : brokerSetSet) { - brokerIdsByBrokerSetId.put(brokerSet.brokerSetId, brokerSet.brokerIds); + if (brokerSetSet != null) { + for (BrokerSet brokerSet : brokerSetSet) { + brokerIdsByBrokerSetId.put(brokerSet.brokerSetId, brokerSet.brokerIds); + } } return brokerIdsByBrokerSetId; } diff --git a/cruise-control/src/main/java/com/linkedin/kafka/cruisecontrol/detector/AbstractBrokerFailureDetector.java b/cruise-control/src/main/java/com/linkedin/kafka/cruisecontrol/detector/AbstractBrokerFailureDetector.java index a24e464a02..b7658a88d6 100644 --- a/cruise-control/src/main/java/com/linkedin/kafka/cruisecontrol/detector/AbstractBrokerFailureDetector.java +++ b/cruise-control/src/main/java/com/linkedin/kafka/cruisecontrol/detector/AbstractBrokerFailureDetector.java @@ -15,6 +15,7 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.nio.file.NoSuchFileException; import java.nio.file.attribute.PosixFilePermission; import java.util.HashMap; import java.util.HashSet; @@ -118,7 +119,7 @@ String loadPersistedFailedBrokerList() { String failedBrokerListString = null; try { failedBrokerListString = readFileToString(_failedBrokersFile, StandardCharsets.UTF_8); - } catch (FileNotFoundException fnfe) { + } catch (FileNotFoundException | NoSuchFileException e) { // This means no previous failures have ever been persisted in the file. failedBrokerListString = ""; } catch (IOException ioe) { diff --git a/cruise-control/src/test/java/com/linkedin/kafka/cruisecontrol/analyzer/RemoveDisksTest.java b/cruise-control/src/test/java/com/linkedin/kafka/cruisecontrol/analyzer/RemoveDisksTest.java index ee428ed7da..544fd1c3c4 100644 --- a/cruise-control/src/test/java/com/linkedin/kafka/cruisecontrol/analyzer/RemoveDisksTest.java +++ b/cruise-control/src/test/java/com/linkedin/kafka/cruisecontrol/analyzer/RemoveDisksTest.java @@ -98,7 +98,7 @@ public static Collection buildParameters() { new IntraBrokerDiskCapacityGoal(true), cluster, kafkaCruiseControlConfig, - replicaLoad != TestConstants.LARGE_BROKER_CAPACITY / 2 * balancingConstraint.capacityThreshold(Resource.DISK) + Math.abs(replicaLoad - TestConstants.LARGE_BROKER_CAPACITY / 2 * balancingConstraint.capacityThreshold(Resource.DISK)) > .0000001 }); } diff --git a/gradle/findbugs-exclude.xml b/gradle/findbugs-exclude.xml index e49a950ce1..c559def91d 100644 --- a/gradle/findbugs-exclude.xml +++ b/gradle/findbugs-exclude.xml @@ -79,6 +79,10 @@ + + + +