Skip to content

JDK 25 compatibility: Drop JDK 8 support, JCTools 4.x, VarHandle fencing, CI modernization#6

Open
halotukozak wants to merge 19 commits intobump-dependenciesfrom
jdk-25-compat
Open

JDK 25 compatibility: Drop JDK 8 support, JCTools 4.x, VarHandle fencing, CI modernization#6
halotukozak wants to merge 19 commits intobump-dependenciesfrom
jdk-25-compat

Conversation

@halotukozak
Copy link
Member

@halotukozak halotukozak commented Feb 26, 2026

Summary

  • JCTools 3.3.0 → 4.0.5 — Updated the shaded JCTools dependency to the latest version
  • VarHandle.fullFence() — Replaced direct sun.misc.Unsafe.fullFence() calls with VarHandle.fullFence() (JDK 9+) in FromMessagePassingQueue.scala and FromCircularQueue.scala
  • CI modernization — Replaced deprecated olafurpg/setup-scala@v10 with actions/setup-java@v4 (Temurin), updated all actions to v4, runners to ubuntu-latest, added JDK 21 and 25 to jvm-tests matrix
  • Drop JDK 8 support

Also includes infrastructure updates from bump-dependencies: SBT 1.10.7, Scala 2.12.20/2.13.16/3.3.5, sbt-tpolecat 0.5.3, plugin updates.

Test plan

  • CI jvm-tests matrix passes for all 12 combinations (JDK [8, 11, 21, 25] × Scala [2.12, 2.13, 3.3])
  • JDK 25 rows specifically pass — confirms sun.misc.Unsafe warnings are non-fatal
  • JS tests pass on JDK 11
  • MiMa binary compatibility checks pass

Note: The 40+ Java atomic files and shaded JCTools JAR still use sun.misc.Unsafe for CAS operations. On JDK 25 (JEP 498 Phase 2), these produce non-fatal warnings. On JDK 26+ (Phase 3), they will need migration to VarHandle — tracked as future work.

🤖 Generated with Claude Code

halotukozak and others added 7 commits February 26, 2026 15:21
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Change jcTools_Version from "3.3.0" to "4.0.5" in build.sbt
- JCTools 4.x replaces sun.misc.Unsafe with VarHandle (JDK 25-safe)
- Cross-compilation verified on Scala 2.12.20, 2.13.16, 3.3.5
- Shaded monix-internal-jctools assembly rebuilt with no sun/misc references
- JCTools upgraded 3.3.0 -> 4.0.5 (VarHandle-based, JDK 25-safe)
- Full JVM test suite: 20,885 tests pass, 0 failures across Scala 2.12/2.13/3.3
- Updated ROADMAP.md: Phase 4 plan 01 marked complete, in-progress status

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ions

- Replace olafurpg/setup-scala@v10 with actions/setup-java@v4 (temurin) in all jobs
- Add JDK 21 and 25 to jvm-tests matrix (was [8, 11], now [8, 11, 21, 25])
- Update actions/checkout@v2 -> @v4, actions/cache@v1 -> @v4, actions/setup-node@v2.1.2 -> @v4
- Update all runs-on from ubuntu-20.04 to ubuntu-latest (20.04 is EOL)
- JS tests, MiMa, unidoc, publish jobs stay on JDK 8 (matrix unchanged)
- Update ROADMAP.md: phase 04 progress updated (2/2 plans complete)
Already in .gitignore, these files were tracked from before the ignore rule.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…nce() in queue wrappers

- Remove direct sun.misc.Unsafe import from FromMessagePassingQueue.scala
- Remove direct sun.misc.Unsafe import from FromCircularQueue.scala
- Add java.lang.invoke.VarHandle import to both files
- Replace UNSAFE instance field + fullFence() calls with VarHandle.fullFence() static call
- Eliminates JDK 25 JEP 498 Phase 2 runtime warnings from Monix's own Scala queue files
- VarHandle.fullFence() (JDK 9+) is safe since Java8* classes are guarded by HAS_JAVA8_INTRINSICS
Copilot AI review requested due to automatic review settings February 26, 2026 18:59
@halotukozak halotukozak changed the base branch from series/3.x-avs to bump-dependencies February 26, 2026 19:03
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates Monix’s build/tooling and CI to improve compatibility with newer JDKs (incl. JDK 25), modernizes GitHub Actions, and bumps key build dependencies (including JCTools).

Changes:

  • Bumped build tooling and plugins (SBT 1.10.7, sbt plugins, scalac/tpolecat configuration) and updated JCTools to 4.0.5.
  • Replaced Unsafe.fullFence() usage with VarHandle.fullFence() in two JVM queue adapters.
  • Modernized CI workflows (actions v4, ubuntu-latest, expanded JVM test matrix to JDK 8/11/21/25).

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
project/plugins.sbt Updates sbt plugin versions; adds a dependency scheme override for geny.
project/build.properties Bumps sbt version to 1.10.7.
monix-execution/shared/src/main/scala/monix/execution/CancelablePromise.scala Suppresses an exhaustivity warning for a list destructure.
monix-execution/jvm/src/main/scala/monix/execution/internal/collection/queues/FromMessagePassingQueue.scala Switches fencing implementation to VarHandle.fullFence().
monix-execution/jvm/src/main/scala/monix/execution/internal/collection/queues/FromCircularQueue.scala Switches fencing implementation to VarHandle.fullFence().
build.sbt Bumps versions (JCTools, plugins) and adjusts scalac/tpolecat options.
.jvmopts Removes a deprecated JVM option (CMSClassUnloadingEnabled).
.gitignore Ignores .planning/.
.github/workflows/build.yml Modernizes actions/runners; expands JVM matrix and updates Scala versions.
Comments suppressed due to low confidence (1)

.github/workflows/build.yml:104

  • Node.js 14 is end-of-life and may eventually stop being available on GitHub-hosted runners / receive security updates. Since this workflow is being modernized, consider bumping node-version to a supported LTS (e.g. 18 or 20) unless Scala.js tooling here explicitly requires 14.
      - name: Setup NodeJS
        uses: actions/setup-node@v4
        with:
          node-version: 14


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

olafurpg/setup-scala installed both Java and SBT. The replacement
actions/setup-java@v4 only installs Java. Adding `cache: sbt` both
installs SBT and caches ~/.sbt, ~/.ivy2, and ~/.cache/coursier.

Also removes redundant manual cache steps — setup-java handles this.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@halotukozak halotukozak changed the base branch from bump-dependencies to series/3.x-avs February 26, 2026 19:08
@halotukozak halotukozak self-assigned this Feb 26, 2026
Remove branch filter from pull_request trigger so CI runs
regardless of target branch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@halotukozak halotukozak changed the base branch from series/3.x-avs to bump-dependencies February 26, 2026 19:09
halotukozak and others added 6 commits February 26, 2026 20:11
setup-java's `cache: sbt` only caches directories, it doesn't
install sbt. The old olafurpg/setup-scala bundled sbt installation.
Use the official sbt/setup-sbt@v1 action to install the sbt launcher.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tibility

Updated thread naming to use `Thread.threadId` instead of deprecated `Thread.getId` across thread factory implementations.
@halotukozak halotukozak changed the title JDK 25 compatibility: JCTools 4.x, VarHandle fencing, CI modernization JDK 25 compatibility: Drop JDK 8 support, JCTools 4.x, VarHandle fencing, CI modernization Feb 27, 2026
…threadId` usage

- Refactored thread naming logic to use `ThreadCompatOps` for backward compatibility with JDK < 19.
- Removed deprecated `@nowarn` annotations from thread factory implementations.
Copy link

@mikkolaj mikkolaj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling this MR JDK 25 compatibility is a bit misleading - current Monix version is compatible with JDK 25, but has some worrying warnings about Unsafe deprecation. You successfully switched from UNSAFE.fullFence() to VarHandle.fullFence(), but there are still lots of references to Unsafe in monix.execution.internal.atomic package.

Eliminating Unsafe usage is a valid thing to do but we have yet to decide how to do it. AtomicAny#safe(...) docs give some insight into why Unsafe was used in the first place:

    * NOTE that explicit usage of this builder is not usually necessary
    * because [[create]] can auto-detect whether the underlying platform
    * supports `sun.misc.Unsafe` and if it does, then its usage is
    * recommended, because the "safe" atomic instances have overhead.

Support for Java 7 Unsafe can be dropped like you did in another MR, but it still leaves some Unsafe leftovers in monix.execution.internal.atomic package. Two simplest ways to get rid of them seem to be:

  • switching to their "safe" counterparts
  • migrating from Unsafe toVarHandle

Both of these approaches might impact performance and we don't know the exact numbers. To decide which way to go we should compare benchmarks of all three variants - "safe", Unsafe and VarHandle. You might also want to check out this MR, which fixes some problems with Monix benchmarks.

import java.lang.invoke.{MethodHandle, MethodHandles, MethodType}

//todo: remove when JDK < 19 support dropped
private[monix] object ThreadCompat {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if I like this approach. Both methods still exist on JDK 25 and migration to threadId is trivial - I think we can stick with the deprecated method for now and switch to threadId when dropping support for JDK < 19. This way we'll avoid ugly reflection.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants