Skip to content

Added Scala 3 support#1904

Open
rozza wants to merge 1 commit intomongodb:mainfrom
rozza:JAVA-5261
Open

Added Scala 3 support#1904
rozza wants to merge 1 commit intomongodb:mainfrom
rozza:JAVA-5261

Conversation

@rozza
Copy link
Member

@rozza rozza commented Mar 3, 2026

Added Macro support for Scala 3
Split Scala code to Scala 2 and Scala 3 specific code Updated evergreen to test Scala 3
Updated spotless Scala configuration to default to Scala 2 Added custom spotless Scala configuration for Scala 3 in bson-scala Updated test code work both with Scala 2 and Scala 3

JAVA-5261

@rozza rozza force-pushed the JAVA-5261 branch 6 times, most recently from 6dd3f40 to 71cab33 Compare March 3, 2026 16:03
@rozza
Copy link
Member Author

rozza commented Mar 3, 2026

Added Macro support for Scala 3
Split Scala code to Scala 2 and Scala 3 specific code
Updated evergreen to test Scala 3
Updated spotless Scala configuration to default to Scala 2
Added custom spotless Scala configuration for Scala 3 in bson-scala
Updated test code work both with Scala 2 and Scala 3

JAVA-5261
- name: "scala-test-task"

- matrix_name: "scala-tests-3"
matrix_spec: { auth: "noauth", ssl: "nossl", jdk: [ "jdk17", "jdk21" ], version: [ "8.0" ], topology: "replicaset",
Copy link
Member Author

Choose a reason for hiding this comment

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

Scala 3 currently supports Java 8.

However, with Java 8 some of the test Models caused scalatest-Junit to fail with invalid class name.

Unfortunately, the fix is to upgrade scalatest but doing that limits the base version of the SDK - so I opted not test against Java 8, rather than set a hard base of 17.


scalaVersions?.forEach { version ->
require(version.matches(Regex("\\d\\.\\d{2}"))) { "Scala version '$version' must be in the format X.YY" }
require(version.matches(Regex("^[23].*"))) { "Scala version '$version' not supported." }
Copy link
Member Author

Choose a reason for hiding this comment

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

This is to ensure the bom is correctly configured.

Where as Scala 2.11, 2.12, 2.13 are all major releases. Scala 3 has gone for the traditional Major.Minor.Patch formatting.

This means the postfix for artifacts for scala 3 is just _3 where as Scala 2 variants are _2.11, _2.12 etc. eg: mongo-scala-driver_2.11

case BsonType.DOCUMENT => readDocument(reader, decoderContext, clazz, typeArgs)
case BsonType.ARRAY => readArray(reader, decoderContext, clazz, typeArgs)
case BsonType.NULL =>
case BsonType.NULL =>
Copy link
Member Author

Choose a reason for hiding this comment

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

Scalafmt changes only and a move to scala2 source directory

*
* @see [[MacroCodec]] for the runtime base trait that the generated codec extends.
*/
private[bson] object CaseClassCodec {
Copy link
Member Author

Choose a reason for hiding this comment

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

This is the core of the CaseClassCodec Macro. It follows the same patterns as the Scala 2 version.

Scala 3 totally rewrote the Macros in a non compatible way. So this version is updated for the new Scala 3 macros and compile time reflection.

@@ -0,0 +1,141 @@
/*
Copy link
Member Author

Choose a reason for hiding this comment

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

Scala 3 versions of Document and BaseBsonDocument using Scala 3 specific classes.

Much the same as the Scala 2.13 version. But I didn't want to split out joint Scala 2.13 & Scala 3 code as the source directories are confusing enough.

scala {
target("**/*.scala")
scalafmt().configFile(rootProject.file("config/scala/scalafmt.conf"))
targetExclude("**/scala-3/**")
Copy link
Member Author

Choose a reason for hiding this comment

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

The default excludes all scala-3 code.

// ============================================
val compileOptions = mutableListOf("-target:jvm-1.8")
when (scalaVersion) {
"3" -> {
Copy link
Member Author

Choose a reason for hiding this comment

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

This adds the Scala 3 code base with its own specific sourcesets.


package org.mongodb.scala.documentation

import java.util.concurrent.CountDownLatch
Copy link
Member Author

Choose a reason for hiding this comment

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

All these test changes were needed to ensure the tests work in both Scala 2 and Scala 3.

Implicit conversions now have to be explicitly imported in Scala 3. Some Scala 3 language based implicits where previously used (eg maxTime auto conversion to Duration). This is now explicit so that it can work across versions.

Partial functions are required to be ( varname: Type) => where as previously they could be without parenthesis.

Functions that are defined with parenthesis, must include them in Scala 3 eg: collection.watch was fine in Scala 2, but now must be collection.watch().


abstract class BaseSpec extends AnyFlatSpec with Matchers {}
abstract class BaseSpec extends AnyFlatSpec with Matchers {
val DEFAULT_EXCLUSIONS: Set[String] =
Copy link
Member Author

Choose a reason for hiding this comment

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

I DRY'd up the default exclusions. Depending on the version of Scala depends on the name of some of the auto added methods to java / scala classes when relfecting on the methods in the API.

org.gradle.jvmargs=-Dfile.encoding=UTF-8 -Duser.country=US -Duser.language=en
## NOTE: This property is also used to generate scala compile versions in BOM.
supportedScalaVersions=2.13,2.12,2.11
supportedScalaVersions=3,2.13,2.12,2.11
Copy link
Member Author

Choose a reason for hiding this comment

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

🎉

@rozza rozza marked this pull request as ready for review March 4, 2026 10:11
@rozza rozza requested a review from a team as a code owner March 4, 2026 10:11
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.

1 participant