Gradle で ScalaPB を使う
ScalaPB であればビルドツールに sbt を使う方が簡単かもしれませんが、引き続き Gradle を使います。
- Gradle 3.0
- ScalaPB 0.5.40
今回作成したソースは http://github.com/fits/try_samples/tree/master/blog/20160905/
proto ファイル
前回と同じファイルですが、ファイル名に -
を含むと都合が悪いようなので ※ ファイル名だけ変えています。
※ ScalaPB 0.5.40 では、デフォルトで proto ファイル名が そのままパッケージ名の一部となりました (パッケージ名は <java_package オプションの値>.<protoファイル名> )
ちなみに、java_outer_classname
のオプション設定は無視されるようです。
proto/addressbook.proto (.proto ファイル)
syntax = "proto3"; package sample; option java_package = "sample.model"; option java_outer_classname = "AddressBookProtos"; message Person { string name = 1; int32 id = 2; string email = 3; enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; } message PhoneNumber { string number = 1; PhoneType type = 2; } repeated PhoneNumber phone = 4; } message AddressBook { repeated Person person = 1; }
Gradle ビルド定義
基本的な構成は前回と同じですが、ScalaPBC
を実行してソースを生成する等、Scala 用に変えています。
build.gradle
apply plugin: 'scala' apply plugin: 'application' // protoc によるソースの自動生成先 def protoDestDir = 'src/main/protoc-generated' // proto ファイル名 def protoFile = 'proto/addressbook.proto' mainClassName = 'SampleApp' repositories { jcenter() } configurations { scalapbc } dependencies { scalapbc 'com.trueaccord.scalapb:scalapbc_2.11:0.5.40' compile 'org.scala-lang:scala-library:2.11.8' compile 'com.trueaccord.scalapb:scalapb-runtime_2.11:0.5.40' } task scalapbc << { mkdir(protoDestDir) javaexec { main = 'com.trueaccord.scalapb.ScalaPBC' classpath = configurations.scalapbc args = [ protoFile, "--scala_out=${protoDestDir}" ] } } compileScala { dependsOn scalapbc source protoDestDir } clean { delete protoDestDir }
サンプルアプリケーション
こちらも前回と同じ処理内容ですが、ScalaPB 用の実装となっています。
src/main/scala/SampleApp.scala
import java.io.ByteArrayOutputStream import sample.model.addressbook.Person import Person.PhoneNumber import Person.PhoneType._ object SampleApp extends App { val phone = PhoneNumber("000-1234-5678", HOME) val person = Person(name = "sample1", phone = Seq(phone)) println(person) val output = new ByteArrayOutputStream() try { person.writeTo(output) println("----------") val restoredPerson = Person.parseFrom(output.toByteArray) println(restoredPerson) } finally { output.close } }
ビルドと実行
ビルドと実行の結果は以下の通りです。
前回と違って今回のビルド(scalapbc の実施)には python コマンドが必要でした。※
※ python コマンドを呼び出せるように環境変数 PATH 等を設定しておきます 今回は Python 2.7 を使用しました
実行結果
> gradle run ・・・ :scalapbc protoc-jar: protoc version: 300, detected platform: windows 10/amd64 protoc-jar: executing: [・・・\Temp\protoc8428481850206377506.exe, --plugin=protoc-gen-scala=・・・\Temp\protocbridge9000836851429371052.bat, proto/addressbook.proto, --scala_out=src/main/protoc-generated] :compileScala ・・・ :run name: "sample1" phone { number: "000-1234-5678" type: HOME } ---------- name: "sample1" phone { number: "000-1234-5678" type: HOME } BUILD SUCCESSFUL
scalapbc タスクの実行によって以下のようなソースが生成されました。
- src/main/protoc-generated/sample/model/addressbook/AddressBook.scala
- src/main/protoc-generated/sample/model/addressbook/AddressbookProto.scala
- src/main/protoc-generated/sample/model/addressbook/Person.scala
java_package
オプションの設定値は反映されていますが、java_outer_classname
オプション設定の方は無視されているようです。