Generate both Java and Scala classes using Protocol Buffers in ScalaPB

2.7k views Asked by At

I have been using sbt-protobuf to generate Java classes from proto definition files. I now want to generate Scala classes as well. To do that, I try to use the ScalaPB plugin. The goal is to have one src/main/protobuf/ directory in the project and generate both Java and Scala classes from those definitions.

The problem is that when I add the ScalaPB dependency in my project it stops generating the Java classes (it only generate Scala case classes).

In fact, trying to modify any traditional sbt-protobuf settings, always results in this (or similar) error message:

build.sbt:YYY: error: reference to protocOptions is ambiguous;
it is imported twice in the same scope by
import _root_.sbtprotobuf.ProtobufPlugin._
and import _root_.com.trueaccord.scalapb.ScalaPbPlugin._
    protocOptions in SPB.protobufConfig ++= Seq(..)

I am not sure if these two issues are related. The idea was to change the protocOptions to enforce the generation of the Java classes.

2

There are 2 answers

0
marios On BEST ANSWER

Two things to do here:

  1. Have the PB.javaConversions in PB.protobufConfig := true set to true
  2. Make sure you do a clean on your project. ScalaPB will not regenerate class files if they are already there. If you want your new configuration to take place, make sure you clean the previous protocol buffers.

Here is an example (build.sbt) project that will generate both Java and Scala classes (using SBT 0.13.5):

import com.trueaccord.scalapb.{ScalaPbPlugin => PB}

name  :=  "proto-buf-test"

scalaVersion := "2.10.5"

autoCompilerPlugins in Global := true

lazy val root = project.in(file(".")).settings(PB.protobufSettings:_*).settings(
     PB.javaConversions in PB.protobufConfig := true
)

Here is how my build structure looks like before I call "sbt compile":

├── build.sbt
├── project
│   ├── build.properties
│   └── plugin.sbt
└── src
    └── main
        ├── protobuf
        │   └── types.proto
        └── scala
            └── com
                └── yyyyy
                    └── test
                        └── Test.scala
0
zen On

Per the scalapb readme, you should add PB.gens.java as a target in build.sbt like so:

PB.targets in Compile := Seq(
  PB.gens.java -> (sourceManaged in Compile).value,
  scalapb.gen(javaConversions = true) -> (sourceManaged in Compile).value
)