diff --git a/.scalafix.conf b/.scalafix.conf index 4235cba3d..4e124d45b 100644 --- a/.scalafix.conf +++ b/.scalafix.conf @@ -4,4 +4,6 @@ rules = [ ProcedureSyntax RedundantSyntax ] -ExplicitResultTypes.memberVisibility = [Public] \ No newline at end of file +ExplicitResultTypes.memberVisibility = [Public] +# Needed for Scalafix 0.14.7 and Scala 3.9. Remove after upgrading Scalafix. +ExplicitResultTypes.fetchScala3CompilerArtifactsOnVersionMismatch = true \ No newline at end of file diff --git a/build.sbt b/build.sbt index 67aa79950..7544f2018 100644 --- a/build.sbt +++ b/build.sbt @@ -2,7 +2,7 @@ import scala.language.postfixOps import scala.language.implicitConversions import scala.sys.process.* -ThisBuild / scalaVersion := "3.3.8" +ThisBuild / scalaVersion := "3.9.0" ThisBuild / organization := "eu.neverblink.jelly" ThisBuild / homepage := Some(uri("https://w3id.org/jelly/jelly-jvm")) ThisBuild / licenses := List("Apache-2.0" -> uri("https://www.apache.org/licenses/LICENSE-2.0")) diff --git a/crunchy-protoc-plugin/src/main/scala/eu/neverblink/protoc/java/gen/EnumGenerator.scala b/crunchy-protoc-plugin/src/main/scala/eu/neverblink/protoc/java/gen/EnumGenerator.scala index ef387577b..641ca7e39 100644 --- a/crunchy-protoc-plugin/src/main/scala/eu/neverblink/protoc/java/gen/EnumGenerator.scala +++ b/crunchy-protoc-plugin/src/main/scala/eu/neverblink/protoc/java/gen/EnumGenerator.scala @@ -229,7 +229,7 @@ class EnumGenerator(val info: EnumInfo): .sorted .toArray val createCaseIfs = (len: Int) => { - info.values.stream.filter(value => value.getName.length eq len).forEach(value => { + info.values.stream.filter(value => value.getName.length == len).forEach(value => { forName .beginControlFlow("if ($S == value)", value.getName) .addStatement("return $N", NamingUtil.filterKeyword(value.getName)) diff --git a/crunchy-protoc-plugin/src/main/scala/eu/neverblink/protoc/java/gen/RequestInfo.scala b/crunchy-protoc-plugin/src/main/scala/eu/neverblink/protoc/java/gen/RequestInfo.scala index 1ab924ff0..976b426b6 100644 --- a/crunchy-protoc-plugin/src/main/scala/eu/neverblink/protoc/java/gen/RequestInfo.scala +++ b/crunchy-protoc-plugin/src/main/scala/eu/neverblink/protoc/java/gen/RequestInfo.scala @@ -350,10 +350,10 @@ object RequestInfo: // Used for the return type in the method, e.g., Optional private def getOptionalReturnType: TypeName = if (isRepeated) - return ParameterizedTypeName.get(ClassName.get(classOf[Optional[_]]), getRepeatedStoreType) + return ParameterizedTypeName.get(ClassName.get(classOf[Optional[?]]), getRepeatedStoreType) val typeName = getTypeName if (!isPrimitive || (typeName eq TypeName.BOOLEAN)) - return ParameterizedTypeName.get(ClassName.get(classOf[Optional[_]]), typeName.box) + return ParameterizedTypeName.get(ClassName.get(classOf[Optional[?]]), typeName.box) if (typeName eq TypeName.INT) return TypeName.get(classOf[OptionalInt]) if (typeName eq TypeName.LONG) return TypeName.get(classOf[OptionalLong]) if (typeName eq TypeName.FLOAT) return TypeName.get(classOf[OptionalDouble]) @@ -453,6 +453,6 @@ object RequestInfo: def getFields: Seq[RequestInfo.FieldInfo] = parentTypeInfo.fields .filter(field => field.descriptor.hasOneofIndex) - .filter(field => field.descriptor.getOneofIndex eq oneOfIndex) + .filter(field => field.descriptor.getOneofIndex == oneOfIndex) .toSeq } diff --git a/docs/docs/index.md b/docs/docs/index.md index 4a9d07ecf..b14084410 100644 --- a/docs/docs/index.md +++ b/docs/docs/index.md @@ -75,13 +75,13 @@ The following table shows the compatibility of the Jelly-JVM implementation with {: .jelly-table-tight } | Jelly-JVM | Java | Scala | RDF4J | Jena | Pekko | Neo4j | -|:-----------------------------------------------------------------------------------------------------------------------------------------------:|:----:|:-------------------------:|:-----------:|:-------------------------------------:|:-----------------------------------------------------------------------:|:-----------------------------------------------------:| -| [4.0.x](https://w3id.org/jelly/jelly-jvm/4.0.x)–[**{{ jvm_package_version() }}**](https://w3id.org/jelly/jelly-jvm/{{ jvm_package_version() }}) | 21+[^3] | 3.3.x (LTS)[^2] | 6.x.x | 5.4.x–6.x.x | 1.1.x–1.2.x | {{ neo4j_version('min') }}–{{ neo4j_version('max') }} | -| [3.7.x](https://w3id.org/jelly/jelly-jvm/3.7.x) | 17+ | 3.3.x (LTS)[^2] | 4.3.x–5.x.x | 5.x.x–6.x.x | 1.1.x–1.2.x | 5.1.0–5.26.0 | -| [3.5.x](https://w3id.org/jelly/jelly-jvm/3.5.x)–[3.6.x](https://w3id.org/jelly/jelly-jvm/3.6.x) | 17+ | 3.3.x (LTS)[^2] | 4.3.x–5.x.x | 5.x.x | 1.1.x–1.2.x | 5.1.0–5.26.0 | -| [3.0.x](https://w3id.org/jelly/jelly-jvm/3.0.x)–[3.4.x](https://w3id.org/jelly/jelly-jvm/3.4.x) | 17+ | 3.3.x (LTS)[^2] | 5.x.x | 5.x.x | 1.1.x | – | -| [2.0.x](https://w3id.org/jelly/jelly-jvm/2.0.x)–[2.10.x](https://w3id.org/jelly/jelly-jvm/2.10.x) | 17+ | 3.3.x (LTS) | 5.x.x | 5.x.x | 1.1.x | – | -| [1.0.x](https://w3id.org/jelly/jelly-jvm/1.0.x) | 11+ | 3.3.x (LTS)
2.13.x[^1] | 4.x.x | 4.x.x | 1.0.x | – | +|:-----------------------------------------------------------------------------------------------------------------------------------------------:|:----:|:----------------------------------------------------------------------------------------------------------------:|:-----------:|:-------------------------------------:|:-----------------------------------------------------------------------:|:-----------------------------------------------------:| +| [4.0.x](https://w3id.org/jelly/jelly-jvm/4.0.x)–[**{{ jvm_package_version() }}**](https://w3id.org/jelly/jelly-jvm/{{ jvm_package_version() }}) | 21+[^3] | 3.9.x (LTS)[^2] | 6.x.x | 5.4.x–6.x.x | 1.1.x–1.2.x | {{ neo4j_version('min') }}–{{ neo4j_version('max') }} | +| [3.7.x](https://w3id.org/jelly/jelly-jvm/3.7.x) | 17+ | 3.3.x (LTS)[^2] | 4.3.x–5.x.x | 5.x.x–6.x.x | 1.1.x–1.2.x | 5.1.0–5.26.0 | +| [3.5.x](https://w3id.org/jelly/jelly-jvm/3.5.x)–[3.6.x](https://w3id.org/jelly/jelly-jvm/3.6.x) | 17+ | 3.3.x (LTS)[^2] | 4.3.x–5.x.x | 5.x.x | 1.1.x–1.2.x | 5.1.0–5.26.0 | +| [3.0.x](https://w3id.org/jelly/jelly-jvm/3.0.x)–[3.4.x](https://w3id.org/jelly/jelly-jvm/3.4.x) | 17+ | 3.3.x (LTS)[^2] | 5.x.x | 5.x.x | 1.1.x | – | +| [2.0.x](https://w3id.org/jelly/jelly-jvm/2.0.x)–[2.10.x](https://w3id.org/jelly/jelly-jvm/2.10.x) | 17+ | 3.3.x (LTS) | 5.x.x | 5.x.x | 1.1.x | – | +| [1.0.x](https://w3id.org/jelly/jelly-jvm/1.0.x) | 11+ | 3.3.x (LTS)
2.13.x[^1] | 4.x.x | 4.x.x | 1.0.x | – | See the **[compatibility policy](user/compatibility.md)** for more details and the **[release notes on GitHub](https://github.com/Jelly-RDF/jelly-jvm/releases)**. @@ -121,5 +121,5 @@ The development of the Jelly protocol, its implementations, and supporting tooli ![European Funds for Smart Economy, Republic of Poland, Co-funded by the European Union](assets/featured/feng_rp_eu.png) [^1]: Scala 2.13-compatible builds of Jelly-JVM are available for Jelly-JVM 1.0.x. Scala 2 support was removed in subsequent versions. [See more details](https://w3id.org/jelly/jelly-jvm/1.0.x/user/scala2). -[^2]: Scala version applies **only** to the `jelly-pekko-*` modules. The other modules **do not depend** on Scala and are compatible with any version of Java 21+. +[^2]: Scala version applies **only** to the `jelly-pekko-*` modules. The other modules **do not depend** on Scala. [^3]: The `jelly-rdf4j-*` modules require **Java 25+**, because RDF4J 6 does. All other modules run on Java 21+. Building Jelly-JVM from source requires JDK 25+ in all cases. diff --git a/examples/src/main/scala/eu/neverblink/jelly/examples/PekkoGrpc.scala b/examples/src/main/scala/eu/neverblink/jelly/examples/PekkoGrpc.scala index 3928f5356..0d9d02337 100644 --- a/examples/src/main/scala/eu/neverblink/jelly/examples/PekkoGrpc.scala +++ b/examples/src/main/scala/eu/neverblink/jelly/examples/PekkoGrpc.scala @@ -63,8 +63,8 @@ object PekkoGrpc extends shared.ScalaExample: .withFallback(ConfigFactory.defaultApplication()) // We will need two Pekko actor systems to run the streams – one for the server and one for the client - val serverActorSystem: ActorSystem[_] = ActorSystem(Behaviors.empty, "ServerSystem") - val clientActorSystem: ActorSystem[_] = ActorSystem(Behaviors.empty, "ClientSystem", config) + val serverActorSystem: ActorSystem[?] = ActorSystem(Behaviors.empty, "ServerSystem") + val clientActorSystem: ActorSystem[?] = ActorSystem(Behaviors.empty, "ClientSystem", config) // Our mock dataset that we will send around in the streams val dataset: Dataset = @@ -73,7 +73,7 @@ object PekkoGrpc extends shared.ScalaExample: /** Main method that starts the server and the client. */ def main(args: Array[String]): Unit = - given system: ActorSystem[_] = serverActorSystem + given system: ActorSystem[?] = serverActorSystem given ExecutionContext = system.executionContext // Start the server @@ -95,7 +95,7 @@ object PekkoGrpc extends shared.ScalaExample: /** The client part of the example. */ private def runClient(): Unit = - given system: ActorSystem[_] = clientActorSystem + given system: ActorSystem[?] = clientActorSystem given ExecutionContext = system.executionContext // Create a gRPC client @@ -192,7 +192,7 @@ object PekkoGrpc extends shared.ScalaExample: * You will also need to implement this trait in your own service. It defines the logic with * which the server will handle incoming streams and subscriptions. */ - class ExampleJellyService(using system: ActorSystem[_]) extends RdfStreamService: + class ExampleJellyService(using system: ActorSystem[?]) extends RdfStreamService: given ExecutionContext = system.executionContext /** Handler for clients publishing RDF streams to the server. diff --git a/jmh/src/main/scala/eu/neverblink/jelly/jmh/RdfStreamFrameDecodeBench.scala b/jmh/src/main/scala/eu/neverblink/jelly/jmh/RdfStreamFrameDecodeBench.scala index b915a5e38..e4eade69a 100644 --- a/jmh/src/main/scala/eu/neverblink/jelly/jmh/RdfStreamFrameDecodeBench.scala +++ b/jmh/src/main/scala/eu/neverblink/jelly/jmh/RdfStreamFrameDecodeBench.scala @@ -11,7 +11,7 @@ import org.openjdk.jmh.infra.Blackhole object RdfStreamFrameDecodeBench: @State(Scope.Benchmark) class BenchInput: - var toDecode: Array[RdfStreamFrame] = _ + var toDecode: Array[RdfStreamFrame] = scala.compiletime.uninitialized @Setup(Level.Trial) def setup(): Unit = diff --git a/jmh/src/main/scala/eu/neverblink/jelly/jmh/RdfTripleRecursiveBench.scala b/jmh/src/main/scala/eu/neverblink/jelly/jmh/RdfTripleRecursiveBench.scala index 69552de76..ead4163e8 100644 --- a/jmh/src/main/scala/eu/neverblink/jelly/jmh/RdfTripleRecursiveBench.scala +++ b/jmh/src/main/scala/eu/neverblink/jelly/jmh/RdfTripleRecursiveBench.scala @@ -10,7 +10,7 @@ object RdfTripleRecursiveBench: class BenchInput: val random = new scala.util.Random(123) - var toParse: Array[Byte] = _ + var toParse: Array[Byte] = scala.compiletime.uninitialized val size = 1000 diff --git a/jmh/src/main/scala/eu/neverblink/jelly/jmh/ReadStringBench.scala b/jmh/src/main/scala/eu/neverblink/jelly/jmh/ReadStringBench.scala index 8c8e64136..386dcc329 100644 --- a/jmh/src/main/scala/eu/neverblink/jelly/jmh/ReadStringBench.scala +++ b/jmh/src/main/scala/eu/neverblink/jelly/jmh/ReadStringBench.scala @@ -6,11 +6,11 @@ import org.openjdk.jmh.annotations.* object ReadStringBench: @State(Scope.Benchmark) class BenchInput: - var toParse: Array[Byte] = _ + var toParse: Array[Byte] = scala.compiletime.uninitialized val size = 1000 - var inputStream: CodedInputStream = _ + var inputStream: CodedInputStream = scala.compiletime.uninitialized @Setup(Level.Trial) def setup(): Unit = diff --git a/jmh/src/main/scala/eu/neverblink/jelly/jmh/sparql/SparqlDecodeBench.scala b/jmh/src/main/scala/eu/neverblink/jelly/jmh/sparql/SparqlDecodeBench.scala index cb3db6196..5b43a59d2 100644 --- a/jmh/src/main/scala/eu/neverblink/jelly/jmh/sparql/SparqlDecodeBench.scala +++ b/jmh/src/main/scala/eu/neverblink/jelly/jmh/sparql/SparqlDecodeBench.scala @@ -45,13 +45,13 @@ object SparqlDecodeBench: "realistic-mixed", ), ) - var preset: String = _ + var preset: String = scala.compiletime.uninitialized @Param(Array("4096")) - var valuesPerFrame: Int = _ + var valuesPerFrame: Int = scala.compiletime.uninitialized - var bytes: Array[Byte] = _ - var frames: Array[SparqlResultsFrame] = _ + var bytes: Array[Byte] = scala.compiletime.uninitialized + var frames: Array[SparqlResultsFrame] = scala.compiletime.uninitialized @Setup(Level.Trial) def setup(): Unit = diff --git a/jmh/src/main/scala/eu/neverblink/jelly/jmh/sparql/SparqlEncodeBench.scala b/jmh/src/main/scala/eu/neverblink/jelly/jmh/sparql/SparqlEncodeBench.scala index 7cd76940e..b901130bb 100644 --- a/jmh/src/main/scala/eu/neverblink/jelly/jmh/sparql/SparqlEncodeBench.scala +++ b/jmh/src/main/scala/eu/neverblink/jelly/jmh/sparql/SparqlEncodeBench.scala @@ -37,12 +37,12 @@ object SparqlEncodeBench: "realistic-mixed", ), ) - var preset: String = _ + var preset: String = scala.compiletime.uninitialized @Param(Array("4096")) - var valuesPerFrame: Int = _ + var valuesPerFrame: Int = scala.compiletime.uninitialized - var data: SparqlBenchData.Data = _ + var data: SparqlBenchData.Data = scala.compiletime.uninitialized @Setup(Level.Trial) def setup(): Unit = diff --git a/jmh/src/main/scala/eu/neverblink/jelly/jmh/sparql/SparqlSizeReport.scala b/jmh/src/main/scala/eu/neverblink/jelly/jmh/sparql/SparqlSizeReport.scala index 30687a2a8..6288b5b1e 100644 --- a/jmh/src/main/scala/eu/neverblink/jelly/jmh/sparql/SparqlSizeReport.scala +++ b/jmh/src/main/scala/eu/neverblink/jelly/jmh/sparql/SparqlSizeReport.scala @@ -114,7 +114,8 @@ object SparqlSizeReport: private def run(config: Config): Unit = JenaSystem.init() - val names = if config.presets.nonEmpty then config.presets else SparqlDataGen.presetNames + val names = if config.presets.nonEmpty then config.presets + else SparqlDataGen.presetNames :+ "weather" config.dumpDir.foreach { dir => Files.createDirectories(dir) @@ -131,7 +132,8 @@ object SparqlSizeReport: var filesWritten = 0 for name <- names do - val data = SparqlBenchData.load(name) + val data = if name == "weather" then SparqlBenchData.loadWeather(throughputRows) + else SparqlBenchData.load(name) val outputs = serialize(data, config.maxValuesPerFrame) config.dumpDir.foreach { dir => diff --git a/pekko-grpc/src/main/scala/eu/neverblink/jelly/grpc/RdfStreamServer.scala b/pekko-grpc/src/main/scala/eu/neverblink/jelly/grpc/RdfStreamServer.scala index 3f3b93222..c575814e6 100644 --- a/pekko-grpc/src/main/scala/eu/neverblink/jelly/grpc/RdfStreamServer.scala +++ b/pekko-grpc/src/main/scala/eu/neverblink/jelly/grpc/RdfStreamServer.scala @@ -50,12 +50,12 @@ object RdfStreamServer: * actor system */ final class RdfStreamServer(options: RdfStreamServer.Options, streamService: RdfStreamService)(using - system: ActorSystem[_], + system: ActorSystem[?], ): given ExecutionContext = system.executionContext private val logger = LoggerFactory.getLogger(getClass) - private var binding: Option[ServerBinding] = _ + private var binding: Option[ServerBinding] = scala.compiletime.uninitialized /** Start this server. * @return diff --git a/pekko-grpc/src/main/scala/eu/neverblink/jelly/grpc/RdfStreamServiceHandler.scala b/pekko-grpc/src/main/scala/eu/neverblink/jelly/grpc/RdfStreamServiceHandler.scala index 7ebddf31c..476414456 100644 --- a/pekko-grpc/src/main/scala/eu/neverblink/jelly/grpc/RdfStreamServiceHandler.scala +++ b/pekko-grpc/src/main/scala/eu/neverblink/jelly/grpc/RdfStreamServiceHandler.scala @@ -117,10 +117,14 @@ object RdfStreamServiceHandler { (reader, writer) => (method match { case "SubscribeRdf" => - GrpcMarshalling.unmarshal(request.entity)(RdfStreamSubscribeSerializer, mat, reader) + GrpcMarshalling.unmarshal(request.entity)(using + RdfStreamSubscribeSerializer, + mat, + reader, + ) .map(implementation.subscribeRdf) .map(e => - GrpcMarshalling.marshalStream(e, eHandler)( + GrpcMarshalling.marshalStream(e, eHandler)(using RdfStreamFrameSerializer, writer, system, @@ -128,15 +132,25 @@ object RdfStreamServiceHandler { ) case "PublishRdf" => - GrpcMarshalling.unmarshalStream(request.entity)(RdfStreamFrameSerializer, mat, reader) + GrpcMarshalling.unmarshalStream(request.entity)(using + RdfStreamFrameSerializer, + mat, + reader, + ) .flatMap(implementation.publishRdf) .map(e => - GrpcMarshalling.marshal(e, eHandler)(RdfStreamReceivedSerializer, writer, system), + GrpcMarshalling.marshal(e, eHandler)(using + RdfStreamReceivedSerializer, + writer, + system, + ), ) case m => Future.failed(new NotImplementedError(s"Not implemented: $m")) }) - .recoverWith(GrpcExceptionHandler.from(eHandler(system.classicSystem))(system, writer)), + .recoverWith( + GrpcExceptionHandler.from(eHandler(system.classicSystem))(using system, writer), + ), ).getOrElse(unsupportedMediaType) Function.unlift((req: model.HttpRequest) => diff --git a/pekko-grpc/src/test/scala/eu/neverblink/jelly/grpc/GrpcSpec.scala b/pekko-grpc/src/test/scala/eu/neverblink/jelly/grpc/GrpcSpec.scala index b9938fdd3..23ffef07f 100644 --- a/pekko-grpc/src/test/scala/eu/neverblink/jelly/grpc/GrpcSpec.scala +++ b/pekko-grpc/src/test/scala/eu/neverblink/jelly/grpc/GrpcSpec.scala @@ -48,10 +48,10 @@ class GrpcSpec extends AnyWordSpec, Matchers, ScalaFutures, BeforeAndAfterAll: .withFallback(ConfigFactory.defaultApplication()) val testKit: ActorTestKit = ActorTestKit(conf) - val serverSystem: ActorSystem[_] = testKit.system + val serverSystem: ActorSystem[?] = testKit.system class TestService(storedData: Map[String, Seq[RdfStreamFrame]]) extends RdfStreamService: - given system: ActorSystem[_] = serverSystem + given system: ActorSystem[?] = serverSystem given ExecutionContext = system.executionContext var receivedData: mutable.Map[String, Seq[RdfStreamFrame]] = mutable.Map() @@ -105,7 +105,7 @@ class GrpcSpec extends AnyWordSpec, Matchers, ScalaFutures, BeforeAndAfterAll: (name, confKey, service, bound) }) - given clientSystem: ActorSystem[_] = ActorSystem(Behaviors.empty, "TestClient", conf) + given clientSystem: ActorSystem[?] = ActorSystem(Behaviors.empty, "TestClient", conf) override def afterAll(): Unit = ActorTestKit.shutdown(clientSystem) diff --git a/project/plugins.sbt b/project/plugins.sbt index 7c16ad747..7bba1f33b 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -6,5 +6,3 @@ addSbtPlugin("org.scoverage" % "sbt-scoverage" % "2.4.4") addSbtPlugin("com.github.sbt" % "sbt-jacoco" % "3.6.0") addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.14.7") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.6.2") - -addDependencyTreePlugin