diff --git a/akka-http-bench-jmh/src/main/scala/akka/BenchRunner.scala b/akka-http-bench-jmh/src/main/scala/akka/BenchRunner.scala index 29b6ba421bc..bfece46b1ff 100644 --- a/akka-http-bench-jmh/src/main/scala/akka/BenchRunner.scala +++ b/akka-http-bench-jmh/src/main/scala/akka/BenchRunner.scala @@ -25,7 +25,7 @@ object BenchRunner { val opts = new CommandLineOptions(args2: _*) val results = new Runner(opts).run() - val report = results.asScala.map { result: RunResult => + val report = results.asScala.map { (result: RunResult) => val bench = result.getParams.getBenchmark val params = result.getParams.getParamsKeys.asScala.map(key => s"$key=${result.getParams.getParam(key)}").mkString("_") val score = result.getAggregatedResult.getPrimaryResult.getScore.round diff --git a/akka-http/src/main/scala/akka/http/scaladsl/server/util/ConstructFromTuple.scala b/akka-http/src/main/scala/akka/http/scaladsl/server/util/ConstructFromTuple.scala index 38372113632..a178afb0f8c 100644 --- a/akka-http/src/main/scala/akka/http/scaladsl/server/util/ConstructFromTuple.scala +++ b/akka-http/src/main/scala/akka/http/scaladsl/server/util/ConstructFromTuple.scala @@ -7,6 +7,7 @@ package akka.http.scaladsl.server.util /** * Constructor for instances of type `R` which can be created from a tuple of type `T`. */ +@FunctionalInterface trait ConstructFromTuple[T, R] extends (T => R) object ConstructFromTuple extends ConstructFromTupleInstances diff --git a/build.sbt b/build.sbt index 54d8736a830..e2da72befab 100644 --- a/build.sbt +++ b/build.sbt @@ -289,11 +289,10 @@ lazy val httpJmhBench = project("akka-http-bench-jmh") .enablePlugins(JmhPlugin) .enablePlugins(NoPublish) // don't release benchs .disablePlugins(MimaPlugin) - .enablePlugins(NoScala3) // FIXME lazy val httpMarshallersScala = project("akka-http-marshallers-scala") .settings(commonSettings) - .enablePlugins(NoPublish, NoScala3 /*FIXME */ /*, AggregatePRValidation*/) + .enablePlugins(NoPublish /*, AggregatePRValidation*/) .disablePlugins(MimaPlugin) .aggregate(httpSprayJson, httpXml) @@ -311,7 +310,7 @@ lazy val httpSprayJson = lazy val httpMarshallersJava = project("akka-http-marshallers-java") .settings(commonSettings) - .enablePlugins(NoPublish, NoScala3 /*FIXME */ /*, AggregatePRValidation*/) + .enablePlugins(NoPublish /*, AggregatePRValidation*/) .disablePlugins(MimaPlugin) .aggregate(httpJackson) @@ -412,7 +411,6 @@ lazy val httpScalafixTests = lazy val docs = project("docs") .enablePlugins(AkkaParadoxPlugin, NoPublish, PublishRsyncPlugin) - .enablePlugins(NoScala3) // FIXME .disablePlugins(MimaPlugin) .addAkkaModuleDependency("akka-stream", "provided", AkkaDependency.docs) .addAkkaModuleDependency("akka-actor-typed", "provided", AkkaDependency.docs) @@ -430,12 +428,17 @@ lazy val docs = project("docs") scalacOptions ++= Seq( // Make sure we don't accidentally keep documenting deprecated calls "-Xfatal-warnings", - // In docs adding an unused variable can be helpful, for example - // to show its type - "-Xlint:-unused", // Does not appear to lead to problems "-Wconf:msg=The outer reference in this type test cannot be checked at run time:s", ), + scalacOptions ++= ( + if (scalaVersion.value.startsWith("3")) Seq.empty + else Seq( + // In docs adding an unused variable can be helpful, for example + // to show its type + "-Xlint:-unused" + ) + ), scalacOptions --= Seq( // Code after ??? can be considered 'dead', but still useful for docs "-Ywarn-dead-code", @@ -501,7 +504,7 @@ lazy val compatibilityTests = Project("akka-http-compatibility-tests", file("akk ) lazy val billOfMaterials = Project("bill-of-materials", file("akka-http-bill-of-materials")) - .enablePlugins(BillOfMaterialsPlugin, NoScala3 /* FIXME */) + .enablePlugins(BillOfMaterialsPlugin) .disablePlugins(MimaPlugin) .settings( name := "akka-http-bom", diff --git a/docs/src/test/scala/docs/http/scaladsl/Http2ClientApp.scala b/docs/src/test/scala/docs/http/scaladsl/Http2ClientApp.scala index 3191e2a8bb4..6d2fc3ec17e 100644 --- a/docs/src/test/scala/docs/http/scaladsl/Http2ClientApp.scala +++ b/docs/src/test/scala/docs/http/scaladsl/Http2ClientApp.scala @@ -19,6 +19,7 @@ import com.typesafe.config.ConfigFactory import scala.annotation.nowarn import scala.concurrent.duration._ +import scala.concurrent.ExecutionContext import scala.concurrent.Future import scala.concurrent.Promise @@ -33,8 +34,8 @@ object Http2ClientApp extends App { """ ).withFallback(ConfigFactory.defaultApplication()) - implicit val system = ActorSystem("Http2ClientApp", config) - implicit val ec = system.dispatcher + implicit val system: ActorSystem = ActorSystem("Http2ClientApp", config) + implicit val ec: ExecutionContext = system.dispatcher // #response-future-association val dispatch = singleRequest(Http().connectionTo("doc.akka.io").http2()) diff --git a/docs/src/test/scala/docs/http/scaladsl/HttpClientExampleSpec.scala b/docs/src/test/scala/docs/http/scaladsl/HttpClientExampleSpec.scala index eab588f72ca..ac6c89c33c5 100644 --- a/docs/src/test/scala/docs/http/scaladsl/HttpClientExampleSpec.scala +++ b/docs/src/test/scala/docs/http/scaladsl/HttpClientExampleSpec.scala @@ -27,7 +27,7 @@ class HttpClientExampleSpec extends AnyWordSpec with Matchers with CompileOnlySp import akka.stream.scaladsl.{ FileIO, Framing } import akka.util.ByteString - implicit val system = ActorSystem() + implicit val system: ActorSystem = ActorSystem() val response: HttpResponse = ??? @@ -43,6 +43,7 @@ class HttpClientExampleSpec extends AnyWordSpec with Matchers with CompileOnlySp "manual-entity-consume-example-2" in compileOnlySpec { //#manual-entity-consume-example-2 + import scala.concurrent.ExecutionContext import scala.concurrent.Future import scala.concurrent.duration._ @@ -50,8 +51,8 @@ class HttpClientExampleSpec extends AnyWordSpec with Matchers with CompileOnlySp import akka.http.scaladsl.model._ import akka.util.ByteString - implicit val system = ActorSystem() - implicit val dispatcher = system.dispatcher + implicit val system: ActorSystem = ActorSystem() + implicit val dispatcher: ExecutionContext = system.dispatcher case class ExamplePerson(name: String) def parse(line: ByteString): ExamplePerson = ??? @@ -78,6 +79,7 @@ class HttpClientExampleSpec extends AnyWordSpec with Matchers with CompileOnlySp "manual-entity-consume-example-3" in compileOnlySpec { //#manual-entity-consume-example-3 + import scala.concurrent.ExecutionContext import scala.concurrent.Future import akka.NotUsed @@ -87,13 +89,13 @@ class HttpClientExampleSpec extends AnyWordSpec with Matchers with CompileOnlySp import akka.util.ByteString import akka.stream.scaladsl.{ Flow, Sink, Source } - implicit val system = ActorSystem() - implicit val dispatcher = system.dispatcher + implicit val system: ActorSystem = ActorSystem() + implicit val dispatcher: ExecutionContext = system.dispatcher case class ExamplePerson(name: String) def parse(line: ByteString): Option[ExamplePerson] = - line.utf8String.split(" ").headOption.map(ExamplePerson) + line.utf8String.split(" ").headOption.map(ExamplePerson.apply) val requests: Source[HttpRequest, NotUsed] = Source .fromIterator(() => @@ -126,12 +128,14 @@ class HttpClientExampleSpec extends AnyWordSpec with Matchers with CompileOnlySp "manual-entity-discard-example-1" in compileOnlySpec { //#manual-entity-discard-example-1 + import scala.concurrent.ExecutionContext + import akka.actor.ActorSystem import akka.http.scaladsl.model.HttpMessage.DiscardedEntity import akka.http.scaladsl.model._ - implicit val system = ActorSystem() - implicit val dispatcher = system.dispatcher + implicit val system: ActorSystem = ActorSystem() + implicit val dispatcher: ExecutionContext = system.dispatcher val response1: HttpResponse = ??? // obtained from an HTTP call (see examples below) @@ -141,6 +145,7 @@ class HttpClientExampleSpec extends AnyWordSpec with Matchers with CompileOnlySp //#manual-entity-discard-example-1 } "manual-entity-discard-example-2" in compileOnlySpec { + import scala.concurrent.ExecutionContext import scala.concurrent.Future import akka.Done @@ -148,8 +153,8 @@ class HttpClientExampleSpec extends AnyWordSpec with Matchers with CompileOnlySp import akka.http.scaladsl.model._ import akka.stream.scaladsl.Sink - implicit val system = ActorSystem() - implicit val dispatcher = system.dispatcher + implicit val system: ActorSystem = ActorSystem() + implicit val dispatcher: ExecutionContext = system.dispatcher //#manual-entity-discard-example-2 val response1: HttpResponse = ??? // obtained from an HTTP call (see examples below) @@ -171,7 +176,7 @@ class HttpClientExampleSpec extends AnyWordSpec with Matchers with CompileOnlySp import akka.stream.{ OverflowStrategy, QueueOfferResult } - implicit val system = ActorSystem() + implicit val system: ActorSystem = ActorSystem() import system.dispatcher // to get an implicit ExecutionContext into scope val QueueSize = 10 @@ -218,7 +223,7 @@ class HttpClientExampleSpec extends AnyWordSpec with Matchers with CompileOnlySp import akka.http.scaladsl.model.Multipart.FormData import akka.http.scaladsl.marshalling.Marshal - implicit val system = ActorSystem() + implicit val system: ActorSystem = ActorSystem() import system.dispatcher // to get an implicit ExecutionContext into scope case class FileToUpload(name: String, location: Path) @@ -303,9 +308,10 @@ class HttpClientExampleSpec extends AnyWordSpec with Matchers with CompileOnlySp import akka.http.scaladsl.unmarshalling.Unmarshal import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ import spray.json.DefaultJsonProtocol._ + import spray.json.RootJsonFormat case class Pet(name: String) - implicit val petFormat = jsonFormat1(Pet) + implicit val petFormat: RootJsonFormat[Pet] = jsonFormat1(Pet.apply) val pet: Future[Pet] = Unmarshal(response).to[Pet] //#unmarshal-response-body @@ -313,7 +319,7 @@ class HttpClientExampleSpec extends AnyWordSpec with Matchers with CompileOnlySp "single-request-in-actor-example" in compileOnlySpec { //#single-request-in-actor-example - import akka.actor.{ Actor, ActorLogging } + import akka.actor.{ Actor, ActorLogging, ActorSystem } import akka.http.scaladsl.Http import akka.http.scaladsl.model._ import akka.util.ByteString @@ -324,7 +330,7 @@ class HttpClientExampleSpec extends AnyWordSpec with Matchers with CompileOnlySp import akka.pattern.pipe import context.dispatcher - implicit val system = context.system + implicit val system: ActorSystem = context.system val http = Http(system) override def preStart() = { diff --git a/docs/src/test/scala/docs/http/scaladsl/HttpServerExampleSpec.scala b/docs/src/test/scala/docs/http/scaladsl/HttpServerExampleSpec.scala index cb999db9ce8..2be4b7635b3 100644 --- a/docs/src/test/scala/docs/http/scaladsl/HttpServerExampleSpec.scala +++ b/docs/src/test/scala/docs/http/scaladsl/HttpServerExampleSpec.scala @@ -7,8 +7,11 @@ package docs.http.scaladsl import akka.event.LoggingAdapter import akka.http.scaladsl.Http import akka.http.scaladsl.model.StatusCodes -import akka.http.scaladsl.server.Route +import akka.http.scaladsl.server.{ Directive, Route } +import akka.http.scaladsl.server.directives.FormFieldDirectives.FieldSpec +import akka.http.scaladsl.server.util.ConstructFromTuple import akka.testkit.TestActors + import scala.annotation.nowarn import docs.CompileOnlySpec @@ -262,8 +265,7 @@ class HttpServerExampleSpec extends AnyWordSpec with Matchers pathEnd { concat( put { - // form extraction from multipart or www-url-encoded forms - formFields("email", "total".as[Money]).as(Order) { order => + formFields("email", "total".as[Money]).as(Order.apply _) { (order: Order) => complete { // complete with serialized Future result (myDbActor ? Update(order)).mapTo[TransactionResult] @@ -285,7 +287,7 @@ class HttpServerExampleSpec extends AnyWordSpec with Matchers get { // parameters to case class extraction parameters("size".as[Int], "color".optional, "dangerous".withDefault("no")) - .as(OrderItem) { orderItem => + .as(OrderItem.apply _) { (orderItem: OrderItem) => // ... route using case class instance created from // required and optional query parameters complete("") // #hide @@ -309,20 +311,21 @@ class HttpServerExampleSpec extends AnyWordSpec with Matchers import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ import spray.json.DefaultJsonProtocol._ + import spray.json.RootJsonFormat - implicit val system = ActorSystem() + implicit val system: ActorSystem = ActorSystem() // needed for the future flatMap/onComplete in the end - implicit val executionContext = system.dispatcher + implicit val executionContext: ExecutionContext = system.dispatcher final case class Bid(userId: String, bid: Int) // these are from spray-json - implicit val bidFormat = jsonFormat2(Bid) + implicit val bidFormat: RootJsonFormat[Bid] = jsonFormat2(Bid.apply) val route = path("bid") { put { - entity(as[Bid]) { bid => + entity(as[Bid]) { (bid: Bid) => // incoming entity is fully consumed and converted into a Bid complete("The bid was: " + bid) } @@ -371,7 +374,7 @@ class HttpServerExampleSpec extends AnyWordSpec with Matchers val route = (put & path("lines")) { withoutSizeLimit { - extractRequest { r: HttpRequest => + extractRequest { (r: HttpRequest) => val finishedWriting = r.discardEntityBytes().future // we only want to respond once the incoming data has been handled: @@ -422,11 +425,11 @@ class HttpServerExampleSpec extends AnyWordSpec with Matchers import spray.json.DefaultJsonProtocol._ import spray.json._ - implicit val system = ActorSystem() + implicit val system: ActorSystem = ActorSystem() //#dynamic-routing-example case class MockDefinition(path: String, requests: Seq[JsValue], responses: Seq[JsValue]) - implicit val format = jsonFormat3(MockDefinition) + implicit val format: RootJsonFormat[MockDefinition] = jsonFormat3(MockDefinition.apply) @volatile var state = Map.empty[String, Map[JsValue, JsValue]] diff --git a/docs/src/test/scala/docs/http/scaladsl/HttpServerWithActorInteraction.scala b/docs/src/test/scala/docs/http/scaladsl/HttpServerWithActorInteraction.scala index f0a677178ff..3b55f221fb6 100644 --- a/docs/src/test/scala/docs/http/scaladsl/HttpServerWithActorInteraction.scala +++ b/docs/src/test/scala/docs/http/scaladsl/HttpServerWithActorInteraction.scala @@ -13,6 +13,7 @@ import akka.http.scaladsl.model.StatusCodes import akka.http.scaladsl.server.Directives._ import akka.util.Timeout import spray.json.DefaultJsonProtocol._ +import spray.json.RootJsonFormat import scala.concurrent.duration._ import scala.concurrent.{ ExecutionContext, Future } @@ -44,8 +45,8 @@ object HttpServerWithActorInteraction { } // these are from spray-json - implicit val bidFormat = jsonFormat2(Auction.Bid) - implicit val bidsFormat = jsonFormat1(Auction.Bids) + implicit val bidFormat: RootJsonFormat[Auction.Bid] = jsonFormat2(Auction.Bid.apply) + implicit val bidsFormat: RootJsonFormat[Auction.Bids] = jsonFormat1(Auction.Bids.apply) def main(args: Array[String]): Unit = { implicit val system: ActorSystem[Auction.Message] = ActorSystem(Auction.apply, "auction") @@ -69,7 +70,7 @@ object HttpServerWithActorInteraction { implicit val timeout: Timeout = 5.seconds // query the actor for the current auction state - val bids: Future[Bids] = (auction ? GetBids).mapTo[Bids] + val bids: Future[Bids] = auction.ask(GetBids(_)) complete(bids) } ) diff --git a/docs/src/test/scala/docs/http/scaladsl/HttpServerWithActorsSample.scala b/docs/src/test/scala/docs/http/scaladsl/HttpServerWithActorsSample.scala index 780d1913d29..d4b8896630d 100644 --- a/docs/src/test/scala/docs/http/scaladsl/HttpServerWithActorsSample.scala +++ b/docs/src/test/scala/docs/http/scaladsl/HttpServerWithActorsSample.scala @@ -53,6 +53,7 @@ object HttpServerWithActorsSample { import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport import spray.json.DefaultJsonProtocol import spray.json.DeserializationException + import spray.json.JsonFormat import spray.json.JsString import spray.json.JsValue import spray.json.RootJsonFormat @@ -75,7 +76,7 @@ object HttpServerWithActorsSample { } } - implicit val jobFormat = jsonFormat4(Job) + implicit val jobFormat: RootJsonFormat[Job] = jsonFormat4(Job.apply) } //#akka-typed-json diff --git a/docs/src/test/scala/docs/http/scaladsl/SprayJsonExample.scala b/docs/src/test/scala/docs/http/scaladsl/SprayJsonExample.scala index 58f9ed6f65b..9872dbbcdcf 100644 --- a/docs/src/test/scala/docs/http/scaladsl/SprayJsonExample.scala +++ b/docs/src/test/scala/docs/http/scaladsl/SprayJsonExample.scala @@ -15,17 +15,19 @@ import akka.http.scaladsl.model.StatusCodes // "com.typesafe.akka" %% "akka-http-spray-json" % "10.1.7" import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ import spray.json.DefaultJsonProtocol._ +import spray.json.RootJsonFormat import scala.io.StdIn +import scala.concurrent.ExecutionContext import scala.concurrent.Future object SprayJsonExample { // needed to run the route - implicit val system = ActorSystem(Behaviors.empty, "SprayExample") + implicit val system: ActorSystem[_] = ActorSystem(Behaviors.empty, "SprayExample") // needed for the future map/flatmap in the end and future in fetchItem and saveOrder - implicit val executionContext = system.executionContext + implicit val executionContext: ExecutionContext = system.executionContext var orders: List[Item] = Nil @@ -34,18 +36,15 @@ object SprayJsonExample { final case class Order(items: List[Item]) // formats for unmarshalling and marshalling - implicit val itemFormat = jsonFormat2(Item) - implicit val orderFormat = jsonFormat1(Order) + implicit val itemFormat: RootJsonFormat[Item] = jsonFormat2(Item.apply) + implicit val orderFormat: RootJsonFormat[Order] = jsonFormat1(Order.apply) // (fake) async database query api def fetchItem(itemId: Long): Future[Option[Item]] = Future { orders.find(o => o.id == itemId) } def saveOrder(order: Order): Future[Done] = { - orders = order match { - case Order(items) => items ::: orders - case _ => orders - } + orders = order.items ::: orders Future { Done } } diff --git a/docs/src/test/scala/docs/http/scaladsl/SprayJsonExampleSpec.scala b/docs/src/test/scala/docs/http/scaladsl/SprayJsonExampleSpec.scala index e9c36c83f62..e4cc43b14b7 100644 --- a/docs/src/test/scala/docs/http/scaladsl/SprayJsonExampleSpec.scala +++ b/docs/src/test/scala/docs/http/scaladsl/SprayJsonExampleSpec.scala @@ -25,8 +25,8 @@ class SprayJsonExampleSpec extends AnyWordSpec with Matchers { // collect your json format instances into a support trait: trait JsonSupport extends SprayJsonSupport with DefaultJsonProtocol { - implicit val itemFormat = jsonFormat2(Item) - implicit val orderFormat = jsonFormat1(Order) // contains List[Item] + implicit val itemFormat: RootJsonFormat[Item] = jsonFormat2(Item.apply) + implicit val orderFormat: RootJsonFormat[Order] = jsonFormat1(Order.apply) // contains List[Item] } // use it wherever json (un)marshalling is needed diff --git a/docs/src/test/scala/docs/http/scaladsl/SprayJsonPrettyMarshalSpec.scala b/docs/src/test/scala/docs/http/scaladsl/SprayJsonPrettyMarshalSpec.scala index 32acfabd5d9..70bff1eb231 100644 --- a/docs/src/test/scala/docs/http/scaladsl/SprayJsonPrettyMarshalSpec.scala +++ b/docs/src/test/scala/docs/http/scaladsl/SprayJsonPrettyMarshalSpec.scala @@ -20,8 +20,8 @@ class SprayJsonPrettyMarshalSpec extends RoutingSpec with CompileOnlySpec { object PrettyJsonFormatSupport { import DefaultJsonProtocol._ - implicit val printer = PrettyPrinter - implicit val prettyPrintedItemFormat = jsonFormat2(PrettyPrintedItem) + implicit val printer: JsonPrinter = PrettyPrinter + implicit val prettyPrintedItemFormat: RootJsonFormat[PrettyPrintedItem] = jsonFormat2(PrettyPrintedItem.apply) } // use it wherever json (un)marshalling is needed diff --git a/docs/src/test/scala/docs/http/scaladsl/server/CaseClassExtractionExamplesSpec.scala b/docs/src/test/scala/docs/http/scaladsl/server/CaseClassExtractionExamplesSpec.scala index 9261da478c6..b8bd9d82816 100644 --- a/docs/src/test/scala/docs/http/scaladsl/server/CaseClassExtractionExamplesSpec.scala +++ b/docs/src/test/scala/docs/http/scaladsl/server/CaseClassExtractionExamplesSpec.scala @@ -68,7 +68,7 @@ class CaseClassExtractionExamplesSpec extends RoutingSpec with Inside { "example 4 test" in { val route = (path("color" / Segment) & - parameters("r".as[Int], "g".as[Int], "b".as[Int])).as(Color) { color => + parameters("r".as[Int], "g".as[Int], "b".as[Int])).as(Color.apply _) { color => // ... route working with the `color` instance doSomethingWith(color) // #hide } diff --git a/docs/src/test/scala/docs/http/scaladsl/server/ExceptionHandlerExamplesSpec.scala b/docs/src/test/scala/docs/http/scaladsl/server/ExceptionHandlerExamplesSpec.scala index eabdff8b6ef..20cc8ec5a19 100644 --- a/docs/src/test/scala/docs/http/scaladsl/server/ExceptionHandlerExamplesSpec.scala +++ b/docs/src/test/scala/docs/http/scaladsl/server/ExceptionHandlerExamplesSpec.scala @@ -31,7 +31,7 @@ object MyExplicitExceptionHandler { object MyApp extends App { - implicit val system = ActorSystem() + implicit val system: ActorSystem = ActorSystem() val route: Route = handleExceptions(myExceptionHandler) { @@ -66,7 +66,7 @@ object MyImplicitExceptionHandler { object MyApp extends App { - implicit val system = ActorSystem() + implicit val system: ActorSystem = ActorSystem() val route: Route = // ... some route structure @@ -150,7 +150,7 @@ object RespondWithHeaderExceptionHandlerExample { } object MyApp extends App { - implicit val system = ActorSystem() + implicit val system: ActorSystem = ActorSystem() Http().newServerAt("localhost", 8080).bind(route) } diff --git a/docs/src/test/scala/docs/http/scaladsl/server/RejectionHandlerExamplesSpec.scala b/docs/src/test/scala/docs/http/scaladsl/server/RejectionHandlerExamplesSpec.scala index 28835b82fd1..a56ae4e9f18 100644 --- a/docs/src/test/scala/docs/http/scaladsl/server/RejectionHandlerExamplesSpec.scala +++ b/docs/src/test/scala/docs/http/scaladsl/server/RejectionHandlerExamplesSpec.scala @@ -41,7 +41,7 @@ object MyRejectionHandler { .handleNotFound { complete((NotFound, "Not here!")) } .result() - implicit val system = ActorSystem() + implicit val system: ActorSystem = ActorSystem() val route: Route = handleRejections(myRejectionHandler) { // ... some route structure @@ -60,7 +60,7 @@ object HandleNotFoundWithThePath { import akka.http.scaladsl.server._ import Directives._ - implicit def myRejectionHandler = + implicit def myRejectionHandler: RejectionHandler = RejectionHandler.newBuilder() .handleNotFound { extractUnmatchedPath { p => @@ -98,7 +98,7 @@ class RejectionHandlerExamplesSpec extends RoutingSpec with CompileOnlySpec { import akka.http.scaladsl.model._ import akka.http.scaladsl.server.RejectionHandler - implicit def myRejectionHandler = + implicit def myRejectionHandler: RejectionHandler = RejectionHandler.default .mapRejectionResponse { case res @ HttpResponse(_, _, ent: HttpEntity.Strict, _) => @@ -132,7 +132,7 @@ class RejectionHandlerExamplesSpec extends RoutingSpec with CompileOnlySpec { import akka.http.scaladsl.model._ import akka.http.scaladsl.server.RejectionHandler - implicit def myRejectionHandler = + implicit def myRejectionHandler: RejectionHandler = RejectionHandler.default .mapRejectionResponse { case res @ HttpResponse(_, _, ent: HttpEntity.Strict, _) => @@ -168,7 +168,7 @@ class RejectionHandlerExamplesSpec extends RoutingSpec with CompileOnlySpec { import akka.http.scaladsl.server._ import akka.http.scaladsl.model.StatusCodes.BadRequest - implicit def myRejectionHandler = RejectionHandler.newBuilder().handle { + implicit def myRejectionHandler: RejectionHandler = RejectionHandler.newBuilder().handle { case MissingCookieRejection(_) => complete(HttpResponse(BadRequest, entity = "No cookies, no service!!!")) }.result() diff --git a/docs/src/test/scala/docs/http/scaladsl/server/TestKitFragmentSpec.scala b/docs/src/test/scala/docs/http/scaladsl/server/TestKitFragmentSpec.scala index bddd3dda15a..d2e38a4329e 100644 --- a/docs/src/test/scala/docs/http/scaladsl/server/TestKitFragmentSpec.scala +++ b/docs/src/test/scala/docs/http/scaladsl/server/TestKitFragmentSpec.scala @@ -58,6 +58,6 @@ class TestKitTimeoutSpec extends AnyWordSpec with ScalatestRouteTest { import akka.http.scaladsl.testkit.RouteTestTimeout import akka.testkit.TestDuration - implicit val timeout = RouteTestTimeout(5.seconds.dilated) + implicit val timeout: RouteTestTimeout = RouteTestTimeout(5.seconds.dilated) //#timeout-setting } diff --git a/docs/src/test/scala/docs/http/scaladsl/server/TestKitWithActorSpec.scala b/docs/src/test/scala/docs/http/scaladsl/server/TestKitWithActorSpec.scala index 70186970c25..41b2c6cca3a 100644 --- a/docs/src/test/scala/docs/http/scaladsl/server/TestKitWithActorSpec.scala +++ b/docs/src/test/scala/docs/http/scaladsl/server/TestKitWithActorSpec.scala @@ -8,8 +8,9 @@ package docs.http.scaladsl.server import scala.concurrent.duration._ import scala.util.{ Failure, Success } +import akka.{ actor => untyped } import akka.actor.testkit.typed.scaladsl.TestProbe -import akka.actor.typed.{ ActorRef, Scheduler } +import akka.actor.typed.{ ActorRef, ActorSystem, Scheduler } import akka.actor.typed.scaladsl.AskPattern._ import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.testkit.ScalatestRouteTest @@ -24,7 +25,7 @@ object RouteUnderTest { // Your route under test, scheduler is only needed as ask is used def route(someActor: ActorRef[Ping])(implicit scheduler: Scheduler, timeout: Timeout) = get { path("ping") { - complete(someActor ? Ping) + complete(someActor ? Ping.apply) } } } @@ -35,9 +36,9 @@ class TestKitWithActorSpec extends AnyWordSpec with Matchers with ScalatestRoute // This test does not use the classic APIs, // so it needs to adapt the system: import akka.actor.typed.scaladsl.adapter._ - implicit val typedSystem = system.toTyped - implicit val timeout = Timeout(500.milliseconds) - implicit val scheduler = system.scheduler + implicit val typedSystem: ActorSystem[_] = system.toTyped + implicit val timeout: Timeout = Timeout(500.milliseconds) + implicit val scheduler: untyped.Scheduler = system.scheduler "The service" should { "return a 'PONG!' response for GET requests to /ping" in { diff --git a/docs/src/test/scala/docs/http/scaladsl/server/directives/BasicDirectivesExamplesSpec.scala b/docs/src/test/scala/docs/http/scaladsl/server/directives/BasicDirectivesExamplesSpec.scala index d472270f713..2b73aeaeb5d 100644 --- a/docs/src/test/scala/docs/http/scaladsl/server/directives/BasicDirectivesExamplesSpec.scala +++ b/docs/src/test/scala/docs/http/scaladsl/server/directives/BasicDirectivesExamplesSpec.scala @@ -681,7 +681,7 @@ class BasicDirectivesExamplesSpec extends RoutingSpec with CompileOnlySpec { "extractSettings-examples" in { //#extractSettings-examples val route = - extractSettings { settings: RoutingSettings => + extractSettings { (settings: RoutingSettings) => complete(s"RoutingSettings.renderVanityFooter = ${settings.renderVanityFooter}") } @@ -699,7 +699,7 @@ class BasicDirectivesExamplesSpec extends RoutingSpec with CompileOnlySpec { val route = tunedSettings { - extractSettings { settings: RoutingSettings => + extractSettings { (settings: RoutingSettings) => complete(s"RoutingSettings.fileGetConditional = ${settings.fileGetConditional}") } } diff --git a/docs/src/test/scala/docs/http/scaladsl/server/directives/CodingDirectivesExamplesSpec.scala b/docs/src/test/scala/docs/http/scaladsl/server/directives/CodingDirectivesExamplesSpec.scala index 06cbc480498..810bc908d6e 100644 --- a/docs/src/test/scala/docs/http/scaladsl/server/directives/CodingDirectivesExamplesSpec.scala +++ b/docs/src/test/scala/docs/http/scaladsl/server/directives/CodingDirectivesExamplesSpec.scala @@ -79,7 +79,7 @@ class CodingDirectivesExamplesSpec extends RoutingSpec with CompileOnlySpec { //#decodeRequest val route = decodeRequest { - entity(as[String]) { content: String => + entity(as[String]) { (content: String) => complete(s"Request content: '$content'") } } @@ -100,7 +100,7 @@ class CodingDirectivesExamplesSpec extends RoutingSpec with CompileOnlySpec { //#decodeRequestWith val route = decodeRequestWith(Coders.Gzip) { - entity(as[String]) { content: String => + entity(as[String]) { (content: String) => complete(s"Request content: '$content'") } } @@ -121,7 +121,7 @@ class CodingDirectivesExamplesSpec extends RoutingSpec with CompileOnlySpec { //#decodeRequestWith val route = decodeRequestWith(Coders.Gzip, Coders.NoCoding) { - entity(as[String]) { content: String => + entity(as[String]) { (content: String) => complete(s"Request content: '$content'") } } diff --git a/docs/src/test/scala/docs/http/scaladsl/server/directives/FileUploadDirectivesExamplesSpec.scala b/docs/src/test/scala/docs/http/scaladsl/server/directives/FileUploadDirectivesExamplesSpec.scala index 387a574bb30..22e47d45e0c 100644 --- a/docs/src/test/scala/docs/http/scaladsl/server/directives/FileUploadDirectivesExamplesSpec.scala +++ b/docs/src/test/scala/docs/http/scaladsl/server/directives/FileUploadDirectivesExamplesSpec.scala @@ -25,7 +25,7 @@ class FileUploadDirectivesExamplesSpec extends RoutingSpec with CompileOnlySpec """ // test touches disk, so give it some time - implicit val routeTimeout = RouteTestTimeout(7.seconds.dilated) + implicit val routeTimeout: RouteTestTimeout = RouteTestTimeout(7.seconds.dilated) "storeUploadedFile" in { //#storeUploadedFile diff --git a/docs/src/test/scala/docs/http/scaladsl/server/directives/FutureDirectivesExamplesSpec.scala b/docs/src/test/scala/docs/http/scaladsl/server/directives/FutureDirectivesExamplesSpec.scala index 9dd19e3b7b4..0476b632f53 100644 --- a/docs/src/test/scala/docs/http/scaladsl/server/directives/FutureDirectivesExamplesSpec.scala +++ b/docs/src/test/scala/docs/http/scaladsl/server/directives/FutureDirectivesExamplesSpec.scala @@ -20,12 +20,12 @@ import docs.CompileOnlySpec class FutureDirectivesExamplesSpec extends RoutingSpec with CompileOnlySpec { object TestException extends Throwable - implicit val myExceptionHandler = + implicit val myExceptionHandler: ExceptionHandler = ExceptionHandler { case TestException => complete(InternalServerError -> "Unsuccessful future!") } - implicit val responseTimeout = Timeout(2, TimeUnit.SECONDS) + implicit val responseTimeout: Timeout = Timeout(2, TimeUnit.SECONDS) "onComplete" in { //#onComplete diff --git a/docs/src/test/scala/docs/http/scaladsl/server/directives/JsonStreamingExamplesSpec.scala b/docs/src/test/scala/docs/http/scaladsl/server/directives/JsonStreamingExamplesSpec.scala index fec58f8cf97..e273bcd0de5 100644 --- a/docs/src/test/scala/docs/http/scaladsl/server/directives/JsonStreamingExamplesSpec.scala +++ b/docs/src/test/scala/docs/http/scaladsl/server/directives/JsonStreamingExamplesSpec.scala @@ -30,11 +30,13 @@ class JsonStreamingExamplesSpec extends RoutingSpec with CompileOnlySpec { def getTweets = Source(tweets) //#tweet-format + import spray.json.RootJsonFormat + object MyTweetJsonProtocol extends akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport with spray.json.DefaultJsonProtocol { - implicit val tweetFormat = jsonFormat2(Tweet.apply) + implicit val tweetFormat: RootJsonFormat[Tweet] = jsonFormat2(Tweet.apply) } //#tweet-format @@ -86,7 +88,7 @@ class JsonStreamingExamplesSpec extends RoutingSpec with CompileOnlySpec { // {"example":1000} val newline = ByteString("\n") - implicit val jsonStreamingSupport = EntityStreamingSupport.json() + implicit val jsonStreamingSupport: EntityStreamingSupport = EntityStreamingSupport.json() .withFramingRenderer(Flow[ByteString].map(bs => bs ++ newline)) val route = @@ -120,7 +122,7 @@ class JsonStreamingExamplesSpec extends RoutingSpec with CompileOnlySpec { } // [2] enable csv streaming: - implicit val csvStreaming = EntityStreamingSupport.csv() + implicit val csvStreaming: EntityStreamingSupport = EntityStreamingSupport.csv() val route = path("tweets") { @@ -176,11 +178,13 @@ class JsonStreamingExamplesSpec extends RoutingSpec with CompileOnlySpec { //#measurement-model //#measurement-format + import spray.json.RootJsonFormat + object MyMeasurementJsonProtocol extends akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport with spray.json.DefaultJsonProtocol { - implicit val measurementFormat = jsonFormat2(Measurement.apply) + implicit val measurementFormat: RootJsonFormat[Measurement] = jsonFormat2(Measurement.apply) } //#measurement-format @@ -190,7 +194,7 @@ class JsonStreamingExamplesSpec extends RoutingSpec with CompileOnlySpec { import MyMeasurementJsonProtocol._ // [2] enable Json Streaming - implicit val jsonStreamingSupport = EntityStreamingSupport.json() + implicit val jsonStreamingSupport: EntityStreamingSupport = EntityStreamingSupport.json() // prepare your persisting logic here val persistMetrics = Flow[Measurement] @@ -207,7 +211,7 @@ class JsonStreamingExamplesSpec extends RoutingSpec with CompileOnlySpec { .runFold(0) { (cnt, _) => cnt + 1 } complete { - measurementsSubmitted.map(n => Map("msg" -> s"""Total metrics received: $n""")) + measurementsSubmitted.map(n => s"""Total metrics received: $n""") } } } @@ -224,7 +228,7 @@ class JsonStreamingExamplesSpec extends RoutingSpec with CompileOnlySpec { Post("/metrics", entity = data) ~> route ~> check { status should ===(StatusCodes.OK) - responseAs[String] should ===("""{"msg":"Total metrics received: 2"}""") + responseAs[String] should ===("Total metrics received: 2") } // the FramingWithContentType will reject any content type that it does not understand: diff --git a/docs/src/test/scala/docs/http/scaladsl/server/directives/JsonStreamingFullExamples.scala b/docs/src/test/scala/docs/http/scaladsl/server/directives/JsonStreamingFullExamples.scala index abdd8964e35..f8d1be77636 100644 --- a/docs/src/test/scala/docs/http/scaladsl/server/directives/JsonStreamingFullExamples.scala +++ b/docs/src/test/scala/docs/http/scaladsl/server/directives/JsonStreamingFullExamples.scala @@ -22,6 +22,7 @@ class JsonStreamingFullExamples extends AnyWordSpec { import akka.stream.scaladsl.Source import spray.json.DefaultJsonProtocol + import scala.concurrent.ExecutionContext import scala.io.StdIn import scala.util.Random @@ -31,21 +32,21 @@ class JsonStreamingFullExamples extends AnyWordSpec { import spray.json._ - implicit val userFormat = jsonFormat2(User) + implicit val userFormat: JsonFormat[User] = jsonFormat2(User.apply) val `vnd.example.api.v1+json` = MediaType.applicationWithFixedCharset("vnd.example.api.v1+json", HttpCharsets.`UTF-8`) val ct = ContentType.apply(`vnd.example.api.v1+json`) implicit def userMarshaller: ToEntityMarshaller[User] = Marshaller.oneOf( - Marshaller.withFixedContentType(`vnd.example.api.v1+json`) { organisation => - HttpEntity(`vnd.example.api.v1+json`, organisation.toJson.compactPrint) + Marshaller.withFixedContentType(`vnd.example.api.v1+json`) { (user: User) => + HttpEntity(`vnd.example.api.v1+json`, user.toJson.compactPrint) }) } object ApiServer extends App with UserProtocol { - implicit val system = ActorSystem("api") - implicit val executionContext = system.dispatcher + implicit val system: ActorSystem = ActorSystem("api") + implicit val executionContext: ExecutionContext = system.dispatcher implicit val jsonStreamingSupport: JsonEntityStreamingSupport = EntityStreamingSupport.json() .withContentType(ct) diff --git a/docs/src/test/scala/docs/http/scaladsl/server/directives/MarshallingDirectivesExamplesSpec.scala b/docs/src/test/scala/docs/http/scaladsl/server/directives/MarshallingDirectivesExamplesSpec.scala index 58b3a8cd634..d1b35abffc2 100644 --- a/docs/src/test/scala/docs/http/scaladsl/server/directives/MarshallingDirectivesExamplesSpec.scala +++ b/docs/src/test/scala/docs/http/scaladsl/server/directives/MarshallingDirectivesExamplesSpec.scala @@ -9,15 +9,16 @@ import akka.http.scaladsl.model.MediaTypes.`application/json` import akka.http.scaladsl.model._ import akka.http.scaladsl.server.RoutingSpec import docs.CompileOnlySpec -import spray.json.{ DefaultJsonProtocol, JsValue } //#person-case-class case class Person(name: String, favoriteNumber: Int) //#person-case-class //#person-json-support +import spray.json.{ DefaultJsonProtocol, RootJsonFormat } + object PersonJsonSupport extends DefaultJsonProtocol with SprayJsonSupport { - implicit val PortofolioFormats = jsonFormat2(Person) + implicit val personFormat: RootJsonFormat[Person] = jsonFormat2(Person.apply) } //#person-json-support @@ -43,6 +44,7 @@ class MarshallingDirectivesExamplesSpec extends RoutingSpec with CompileOnlySpec "example-entity-with-raw-json" in { //#example-entity-with-raw-json + import spray.json.JsValue import PersonJsonSupport._ val route = post { diff --git a/docs/src/test/scala/docs/http/scaladsl/server/directives/MiscDirectivesExamplesSpec.scala b/docs/src/test/scala/docs/http/scaladsl/server/directives/MiscDirectivesExamplesSpec.scala index 1a604ffada0..b5770334101 100644 --- a/docs/src/test/scala/docs/http/scaladsl/server/directives/MiscDirectivesExamplesSpec.scala +++ b/docs/src/test/scala/docs/http/scaladsl/server/directives/MiscDirectivesExamplesSpec.scala @@ -6,9 +6,10 @@ package docs.http.scaladsl.server.directives import akka.http.scaladsl.model._ import akka.http.scaladsl.server._ +import akka.util.ByteString import headers._ -import java.net.InetAddress +import java.net.InetAddress import docs.CompileOnlySpec class MiscDirectivesExamplesSpec extends RoutingSpec with CompileOnlySpec { @@ -122,7 +123,7 @@ class MiscDirectivesExamplesSpec extends RoutingSpec with CompileOnlySpec { // tests: def entityOfSize(size: Int) = - HttpEntity(ContentTypes.`text/plain(UTF-8)`, "0" * size) + HttpEntity(ContentTypes.`text/plain(UTF-8)`, List.fill(size)('0').mkString) Post("/abc", entityOfSize(500)) ~> route ~> check { status shouldEqual StatusCodes.OK @@ -143,7 +144,7 @@ class MiscDirectivesExamplesSpec extends RoutingSpec with CompileOnlySpec { // tests: def entityOfSize(size: Int) = - HttpEntity(ContentTypes.`text/plain(UTF-8)`, "0" * size) + HttpEntity(ContentTypes.`text/plain(UTF-8)`, List.fill(size)('0').mkString) Post("/abc", entityOfSize(500)) ~> route ~> check { status shouldEqual StatusCodes.OK @@ -168,7 +169,7 @@ class MiscDirectivesExamplesSpec extends RoutingSpec with CompileOnlySpec { // tests: def entityOfSize(size: Int) = - HttpEntity(ContentTypes.`text/plain(UTF-8)`, "0" * size) + HttpEntity(ContentTypes.`text/plain(UTF-8)`, List.fill(size)('0').mkString) Post("/abc", entityOfSize(800)) ~> route ~> check { status shouldEqual StatusCodes.OK } @@ -190,7 +191,7 @@ class MiscDirectivesExamplesSpec extends RoutingSpec with CompileOnlySpec { // tests: def entityOfSize(size: Int) = - HttpEntity(ContentTypes.`text/plain(UTF-8)`, "0" * size) + HttpEntity(ContentTypes.`text/plain(UTF-8)`, List.fill(size)('0').mkString) // will work even if you have configured akka.http.parsing.max-content-length = 500 Post("/abc", entityOfSize(501)) ~> route ~> check { diff --git a/docs/src/test/scala/docs/http/scaladsl/server/directives/PathDirectivesExamplesSpec.scala b/docs/src/test/scala/docs/http/scaladsl/server/directives/PathDirectivesExamplesSpec.scala index 0552770f969..faa6f9cb2a8 100644 --- a/docs/src/test/scala/docs/http/scaladsl/server/directives/PathDirectivesExamplesSpec.scala +++ b/docs/src/test/scala/docs/http/scaladsl/server/directives/PathDirectivesExamplesSpec.scala @@ -15,7 +15,7 @@ class PathDirectivesExamplesSpec extends RoutingSpec with CompileOnlySpec { "foo" / "bar" / "X" ~ IntNumber.? / ("edit" | "create") val route: Route = - path(matcher) { i: Option[Int] => + path(matcher) { (i: Option[Int]) => complete(s"Matched X${i.getOrElse("")}") } //#path-matcher diff --git a/docs/src/test/scala/docs/http/scaladsl/server/directives/RouteDirectivesExamplesSpec.scala b/docs/src/test/scala/docs/http/scaladsl/server/directives/RouteDirectivesExamplesSpec.scala index 3324e0d9176..3dd47a51734 100644 --- a/docs/src/test/scala/docs/http/scaladsl/server/directives/RouteDirectivesExamplesSpec.scala +++ b/docs/src/test/scala/docs/http/scaladsl/server/directives/RouteDirectivesExamplesSpec.scala @@ -17,7 +17,7 @@ import akka.http.scaladsl.model._ //#complete-examples import akka.http.scaladsl.model.ContentTypes._ -import akka.http.scaladsl.model.headers.`Content-Type` +import akka.http.scaladsl.model.headers.`Access-Control-Allow-Origin` //#complete-examples @@ -48,10 +48,10 @@ class RouteDirectivesExamplesSpec extends RoutingSpec with CompileOnlySpec { complete(201 -> "bar") }, path("e") { - complete(StatusCodes.Created, List(`Content-Type`(`text/plain(UTF-8)`)), "bar") + complete(StatusCodes.Created, List(`Access-Control-Allow-Origin`.`*`), "bar") }, path("f") { - complete(201, List(`Content-Type`(`text/plain(UTF-8)`)), "bar") + complete(201, List(`Access-Control-Allow-Origin`.`*`), "bar") }, path("g") { complete(Future { StatusCodes.Created -> "bar" }) @@ -82,13 +82,13 @@ class RouteDirectivesExamplesSpec extends RoutingSpec with CompileOnlySpec { Get("/e") ~> route ~> check { status shouldEqual StatusCodes.Created - header[`Content-Type`] shouldEqual Some(`Content-Type`(`text/plain(UTF-8)`)) + header[`Access-Control-Allow-Origin`] shouldEqual Some(`Access-Control-Allow-Origin`.`*`) responseAs[String] shouldEqual "bar" } Get("/f") ~> route ~> check { status shouldEqual StatusCodes.Created - header[`Content-Type`] shouldEqual Some(`Content-Type`(`text/plain(UTF-8)`)) + header[`Access-Control-Allow-Origin`] shouldEqual Some(`Access-Control-Allow-Origin`.`*`) responseAs[String] shouldEqual "bar" } diff --git a/project/Common.scala b/project/Common.scala index 93cfee37937..342c7eacbb7 100644 --- a/project/Common.scala +++ b/project/Common.scala @@ -16,19 +16,15 @@ object Common extends AutoPlugin { scalacOptions ++= Seq( "-deprecation", "-encoding", "UTF-8", // yes, this is 2 args - "-target:jvm-1.8", + "-release", "8", "-unchecked", - "-Xlint", "-Ywarn-dead-code", // Silence deprecation notices for changes introduced in Scala 2.12 // Can be removed when we drop support for Scala 2.12: "-Wconf:msg=object JavaConverters in package collection is deprecated:s", "-Wconf:msg=is deprecated \\(since 2\\.13\\.:s", ), - // '-release' parameter is restricted to 'Compile, compile' scope because - // otherwise `sbt akka-http-xml/compile:doc` fails with it on Scala 2.12.9 - Compile / compile / scalacOptions ++= - onlyAfterScala212(onlyAfterJdk8("-release", "8")).value, + scalacOptions ++= onlyOnScala2(Seq("-Xlint")).value, javacOptions ++= Seq("-encoding", "UTF-8") ++ onlyOnJdk8("-source", "1.8") ++ onlyAfterJdk8("--release", "8"), // restrict to 'compile' scope because otherwise it is also passed to @@ -54,6 +50,9 @@ object Common extends AutoPlugin { def onlyAfterScala212[T](values: Seq[T]): Def.Initialize[Seq[T]] = Def.setting { if (scalaMinorVersion.value >= 12) values else Seq.empty[T] } + def onlyOnScala2[T](values: Seq[T]): Def.Initialize[Seq[T]] = Def.setting { + if (scalaVersion.value.startsWith("3")) Seq.empty[T] else values + } def scalaMinorVersion: Def.Initialize[Long] = Def.setting { CrossVersion.partialVersion(scalaVersion.value).get._2 }