Is it possible to use play-grpc with Scala 2.13?

When I follow the documentation, I get an error in my built.sbt, because play.grpc doesn’t exist, so I can’t import play.grpc.gen.scaladsl.PlayScalaClientCodeGenerator.

Hi @danellis,

could you share some more details? Maybe you can share your build.sbt and your project/plugins.sbt.

Also, consider looking at the play gRPC sample for instpiration if you get blocked.

Cheers,

build.sbt

import sbt.Keys._
import sbtrelease.ReleasePlugin.autoImport.releaseProcess
import sbtbuildinfo.BuildInfoPlugin
import Dependencies._

releaseProcess := Settings.releaseProcess
Global / excludeLintKeys += releaseProcess

lazy val cloud = (project in file("."))
    .enablePlugins(ReleasePlugin)

lazy val model = project
    .settings(
        name := "model",
        Settings.commonSettings,
        libraryDependencies += playJson
    )

lazy val db = project
    .settings(
        name := "db",
        Settings.commonSettings,
        libraryDependencies ++= Seq(
            slick, slickPg, hikari, postgres
        )
    )
    .dependsOn(model)
    .enablePlugins(BuildInfoPlugin)

lazy val api = project
    .settings(
        name := "api",
        Settings.commonSettings,
        Settings.serviceSettings,
        libraryDependencies ++= Seq(
            guice,
            playSlick,
            ws,
            scalaCsv,
            akkaActor, akkaActorTyped, akkaStream, akkaDiscovery,
            akkaProtobuf, akkaSerializationJackson,
            alpakkaKafka,
            "org.scalatestplus.play" %% "scalatestplus-play" % "5.0.0" % Test
        ),
        // TwirlKeys.templateImports += "work.wolfbone.controllers._",
        play.sbt.routes.RoutesKeys.routesImport ++= Seq(
            // "work.wolfbone.binders._",
            "java.util.UUID"
        )
    )
    .dependsOn(model, db, rpc)
    .enablePlugins(
        PlayScala,
        BuildInfoPlugin,
        JavaServerAppPackaging,
        sbtdocker.DockerPlugin
    )

lazy val rpc = project
    .settings(
        name := "rpc",
        Settings.commonSettings
    )
    .enablePlugins(AkkaGrpcPlugin)

lazy val `inventory-service` = project
    .settings(
        name := "inventoryservice",
        Settings.commonSettings,
        Settings.serviceSettings,
        libraryDependencies ++= Seq(
            akkaActor, akkaStream, akkaDiscovery, akkaProtobuf
        )
    )
    .dependsOn(model, db, rpc)
    .enablePlugins(
        BuildInfoPlugin,
        JavaServerAppPackaging,
        sbtdocker.DockerPlugin
    )

project/Dependencies.sbt

import sbt._

object Dependencies {
    val AkkaVersion = "2.6.9"
    val akkaActor = "com.typesafe.akka" %% "akka-actor" % AkkaVersion
    val akkaActorTyped = "com.typesafe.akka" %% "akka-actor-typed" % AkkaVersion
    val akkaSerializationJackson = "com.typesafe.akka" %% "akka-serialization-jackson" % AkkaVersion
    val akkaSlf4j = "com.typesafe.akka" %% "akka-slf4j" % AkkaVersion
    val akkaStream = "com.typesafe.akka" %% "akka-stream" % AkkaVersion
    val akkaDiscovery = "com.typesafe.akka" %% "akka-discovery" % AkkaVersion
    val akkaProtobuf = "com.typesafe.akka" %% "akka-protobuf" % AkkaVersion
    val akkaHttp = "com.typesafe.akka" %% "akka-http" % "10.2.1"
    val akkaHttpCors = "ch.megard" %% "akka-http-cors" % "1.1.0"
    val akkaHttpPlayJson = "de.heikoseeberger" %% "akka-http-play-json" % "1.33.0"
    val alpakkaCsv = "com.lightbend.akka" %% "akka-stream-alpakka-csv" % "2.0.2"
    val alpakkaKafka = "com.typesafe.akka" %% "akka-stream-kafka" % "2.0.5"

    val SlickVersion = "3.3.3"
    val slick = "com.typesafe.slick" %% "slick" % SlickVersion
    val slickPg = "com.github.tminglei" %% "slick-pg" % "0.19.3"
    val playSlick = "com.typesafe.play" %% "play-slick" % "5.0.0"
    val hikari = "com.typesafe.slick" %% "slick-hikaricp" % SlickVersion
    val postgres = "org.postgresql" % "postgresql" % "42.2.16"

    val uuidGenerator = "com.fasterxml.uuid" % "java-uuid-generator" % "4.0.1"
    val playJson = "com.typesafe.play" %% "play-json" % "2.9.1"
    val jsr305 = "com.google.code.findbugs" % "jsr305" % "3.0.2" % "compile"
    val hasher = "com.roundeights" % "hasher_2.12" % "1.2.0"
    val commonsCodec = "commons-codec" % "commons-codec" % "1.15"
    val scalaCsv = "com.github.tototoshi" %% "scala-csv" % "1.3.6"
    val playGrpcRuntime = "com.lightbend.play" %% "play-grpc-runtime" % "0.9.1"

    val logbackClassic = "ch.qos.logback" % "logback-classic" % "1.2.3"
    val log4s = "org.log4s" %% "log4s" % "1.8.2"

    val specs2 = "org.specs2" %% "specs2-core" % "4.10.0" % "test"
    val ammonite = "com.lihaoyi" %% "ammonite" % "2.2.0" % "test" cross CrossVersion.full
}

project/Settings.sbt

import sbt._
import sbt.Keys.{artifactName, _}
import sbtbuildinfo.BuildInfoPlugin
import sbtbuildinfo.BuildInfoPlugin.autoImport._
import sbtdocker.DockerPlugin.autoImport._
import sbtrelease.ReleasePlugin.autoImport._
import sbtrelease.ReleaseStateTransformations._
import Dependencies._
import com.typesafe.sbt.SbtNativePackager.autoImport.executableScriptName
import com.typesafe.sbt.packager.universal.UniversalPlugin.autoImport.stage

object Settings {
    val releaseProcess = Seq[ReleaseStep](
        checkSnapshotDependencies,
        inquireVersions,
        runClean,
        runTest,
        setReleaseVersion,
        commitReleaseVersion,
        tagRelease,
        ReleaseStep(releaseStepTask(DockerKeys.docker)),
        ReleaseStep(releaseStepTask(DockerKeys.dockerPush)),
        setNextVersion,
        commitNextVersion,
        pushChanges
    )

    lazy val commonSettings = Seq(
        organization := "work.wolfbone",

        scalaVersion := "2.13.3",
        scalacOptions := Seq("-unchecked", "-deprecation", "-encoding", "utf8", "-feature", "-language:implicitConversions"),
        scalacOptions in Test ++= Seq("-Yrangepos"),

        testOptions in Test := Nil,

        libraryDependencies += ammonite,

        sourceGenerators in Test += Def.task {
            val file = (sourceManaged in Test).value / "amm.scala"
            IO.write(file, """object amm extends App { ammonite.Main.main(args) }""")
            Seq(file)
        }.taskValue
    )

    lazy val serviceSettings = BuildInfoPlugin.buildInfoDefaultSettings ++ Seq(
        buildInfoKeys := Seq[BuildInfoKey](version),
        buildInfoUsePackageAsPath := true,
        buildInfoPackage := s"${organization.value}.${name.value}",

        publishArtifact in (Compile, packageDoc) := false,

        imageNames in docker := Seq("v" + version.value) map { tag =>
            ImageName(
                registry = Some("registry.gitlab.com"),
                namespace = Some("wolfbone/cloud"),
                repository = name.value,
                tag = Some(tag)
            )
        },

        dockerfile in docker := {
            val appDir: File = stage.value
            val targetDir = "/app"

            new Dockerfile {
                from("anapsix/alpine-java:8")
                maintainer("Dan Ellis <dan@reactivedynamics.io>")
                entryPoint(s"$targetDir/bin/${executableScriptName.value}")
                env(
                    "JAVA_OPTS" -> "-Dlogback.configurationFile=logback.xml",
                    "SENTRY_RELEASE" -> version.value
                )
                expose(9000)
                copy(appDir, targetDir)
            }
        },

        artifactName := { (_, module: ModuleID, artifact: Artifact) =>
            s"wolfbone-${artifact.name}-${module.revision}.${artifact.extension}"
        }
    )
}

project/plugins.sbt

logLevel := Level.Warn

addSbtPlugin("com.github.gseitz" % "sbt-release" % "1.0.13")
addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.9.0")
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.7.4")
addSbtPlugin("se.marcuslonnberg" % "sbt-docker" % "1.7.0")
addSbtPlugin("io.spray" % "sbt-revolver" % "0.9.1")
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.8.2")
addSbtPlugin("org.foundweekends.giter8" % "sbt-giter8-scaffold" % "0.11.0")
addSbtPlugin("com.lightbend.akka.grpc" % "sbt-akka-grpc" % "1.0.2")

hi @danellis,

it looks like you are missing a dependency. In order to use the play-grpc generators from the akka-grpc plugin you need to add the play-grpc generators dependency on the project build definition.

See also https://developer.lightbend.com/docs/play-grpc/current/play/serving-grpc.html

Cheers,