Skip to content

Commit de8214b

Browse files
committed
Wrap ScalaPbCodeGenerator, expose Scala 2.11 error
Wraps `scalapb.ScalaPbCodeGenerator` to catch and return all errors. Without this, any errors escaping from `scalapb.ScalaPbCodeGenerator` will cause the `scala_proto` aspect workers to hang. Also deletes some `@io_bazel_rules_scala` references, replacing them with `Label` instances as appropriate. The `test_scala_version 2.11.12` case from `test_version.sh` would previously hang given the combination of ScalaPB 0.9.8 (the newest available for Scala 2.11) and Protobuf v28.3. Running the following in a `test_version/test_scala_version_*` repo generated by `test_version.sh` reproduced the hang: ```txt $ bazel build --repo_env=SCALA_VERSION=2.11.12 //proto:test_proto [ ...wait 10 seconds, then CTRL-C... ] INFO: Analyzed target //proto:test_proto (2 packages loaded, 22 targets configured). INFO: Found 1 target... [1,038 / 1,047] 4 actions running ProtoScalaPBRule proto/test_service_scala_scalapb.srcjar; 10s worker ProtoScalaPBRule proto/test2_scala_scalapb.srcjar; 10s worker Target //proto:test_proto failed to build ``` With this change, the command now exposes the exact incompatibility between these versions: ```txt $ bazel build --repo_env=SCALA_VERSION=2.11.12 //proto:test_proto ERROR: .../test_version/test_scala_version_1731169107/proto/BUILD:14:14: ProtoScalaPBRule proto/test3_scala_scalapb.srcjar failed: (Exit 1): scalapb_worker failed: error executing command (from target //proto:test3) bazel-out/.../bin/external/io_bazel_rules_scala/src/scala/scripts/scalapb_worker ... (remaining 2 arguments skipped) --scala_out: java.lang.NoSuchMethodError: 'void com.google.protobuf.Descriptors$FileDescriptor.internalBuildGeneratedFileFrom(java.lang.String[], com.google.protobuf.Descriptors$FileDescriptor[], com.google.protobuf.Descriptors$FileDescriptor$InternalDescriptorAssigner)' at scalapb.options.compiler.Scalapb.<clinit>(Scalapb.java:10592) at scalapb.ScalaPbCodeGenerator$.run(ScalaPbCodeGenerator.scala:14) at scalapb.ScalaPbCodeGenerator$.run(ScalaPbCodeGenerator.scala:10) at scripts.ScalaPbCodeGenerator$.run(ScalaPbCodeGeneratorWrapper_2_11.scala:8) at protocbridge.frontend.PluginFrontend$$anonfun$runWithBytes$2.apply(PluginFrontend.scala:52) at protocbridge.frontend.PluginFrontend$$anonfun$runWithBytes$2.apply(PluginFrontend.scala:52) at scala.util.Try$.apply(Try.scala:192) at protocbridge.frontend.PluginFrontend$.runWithBytes(PluginFrontend.scala:51) at protocbridge.frontend.PluginFrontend$.runWithInputStream(PluginFrontend.scala:103) at protocbridge.frontend.PosixPluginFrontend$$anonfun$prepare$1.apply$mcV$sp(PosixPluginFrontend.scala:33) at protocbridge.frontend.PosixPluginFrontend$$anonfun$prepare$1.apply(PosixPluginFrontend.scala:31) at protocbridge.frontend.PosixPluginFrontend$$anonfun$prepare$1.apply(PosixPluginFrontend.scala:31) at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24) at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24) at scala.concurrent.impl.ExecutionContextImpl$AdaptedForkJoinTask.exec(ExecutionContextImpl.scala:121) at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) java.lang.RuntimeException: Exit with code 1 at scala.sys.package$.error(package.scala:27) at scripts.ScalaPBWorker$.work(ScalaPBWorker.scala:44) at io.bazel.rulesscala.worker.Worker.persistentWorkerMain(Worker.java:96) at io.bazel.rulesscala.worker.Worker.workerMain(Worker.java:49) at scripts.ScalaPBWorker$.main(ScalaPBWorker.scala:39) at scripts.ScalaPBWorker.main(ScalaPBWorker.scala) Target //proto:test_proto failed to build ```
1 parent 5be9951 commit de8214b

File tree

7 files changed

+105
-39
lines changed

7 files changed

+105
-39
lines changed

scala_proto/BUILD

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
load(
2-
"//scala_proto:scala_proto_toolchain.bzl",
3-
"scala_proto_deps_toolchain",
4-
"scala_proto_toolchain",
5-
)
1+
load("//scala:providers.bzl", "declare_deps_provider")
62
load(
73
"//scala_proto/default:default_deps.bzl",
84
"DEFAULT_SCALAPB_COMPILE_DEPS",
95
"DEFAULT_SCALAPB_GRPC_DEPS",
6+
"DEFAULT_SCALAPB_WORKER_DEPS",
107
)
11-
load("//scala:providers.bzl", "declare_deps_provider")
128
load("//scala_proto/private:toolchain_deps.bzl", "export_scalapb_toolchain_deps")
9+
load(
10+
"//scala_proto:scala_proto_toolchain.bzl",
11+
"scala_proto_deps_toolchain",
12+
"scala_proto_toolchain",
13+
)
1314

1415
toolchain_type(
1516
name = "toolchain_type",
@@ -80,11 +81,7 @@ declare_deps_provider(
8081
name = "scalapb_worker_deps_provider",
8182
deps_id = "scalapb_worker_deps",
8283
visibility = ["//visibility:public"],
83-
deps = [
84-
"@com_google_protobuf//:protobuf_java",
85-
"@scala_proto_rules_scalapb_compilerplugin",
86-
"@scala_proto_rules_scalapb_protoc_bridge",
87-
],
84+
deps = DEFAULT_SCALAPB_WORKER_DEPS,
8885
)
8986

9087
export_scalapb_toolchain_deps(

scala_proto/default/default_deps.bzl

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
# These are the compile/runtime dependencies needed for scalapb compilation
22
# and grpc compile/runtime.
33
#
4-
# In a complex environment you may want to update the toolchain to not refer to these anymore
5-
# If you are using a resolver (like bazel-deps) that can export compile + runtime jar paths
6-
# for you, then you should only need much shorter dependency lists. This needs to be the unrolled
7-
# transitive path to be used without such a facility.
8-
#
4+
# In a complex environment you may want to update the toolchain to not refer to
5+
# these anymore If you are using a resolver (like bazel-deps) that can export
6+
# compile + runtime jar paths for you, then you should only need much shorter
7+
# dependency lists. This needs to be the unrolled transitive path to be used
8+
# without such a facility.
9+
10+
load("//scala:scala_cross_version_select.bzl", "select_for_scala_version")
11+
912
DEFAULT_SCALAPB_COMPILE_DEPS = [
1013
"//scala/private/toolchain_deps:scala_library_classpath",
1114
"@com_google_protobuf//:protobuf_java",
@@ -41,3 +44,12 @@ DEFAULT_SCALAPB_GRPC_DEPS = [
4144
"@scala_proto_rules_perfmark_api",
4245
"@scala_proto_rules_scalapb_runtime_grpc",
4346
]
47+
48+
DEFAULT_SCALAPB_WORKER_DEPS = [
49+
"@com_google_protobuf//:protobuf_java",
50+
"@scala_proto_rules_scalapb_compilerplugin",
51+
"@scala_proto_rules_scalapb_protoc_bridge",
52+
] + select_for_scala_version(
53+
any_2_11 = [],
54+
since_2_12 = ["@scala_proto_rules_scalapb_protoc_gen"],
55+
)

scala_proto/scala_proto_toolchain.bzl

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
load("@io_bazel_rules_scala//scala:providers.bzl", "DepsInfo")
1+
load("//scala:providers.bzl", "DepsInfo")
22

33
def _generators(ctx):
44
return dict(
@@ -7,9 +7,12 @@ def _generators(ctx):
77
)
88

99
def _generators_jars(ctx):
10+
generator_deps = ctx.attr.extra_generator_dependencies + [
11+
ctx.attr._main_generator_dep,
12+
]
1013
return depset(transitive = [
1114
dep[JavaInfo].transitive_runtime_jars
12-
for dep in ctx.attr.extra_generator_dependencies
15+
for dep in generator_deps
1316
])
1417

1518
def _generators_opts(ctx):
@@ -74,18 +77,20 @@ scala_proto_toolchain = rule(
7477
"code_generator": attr.label(
7578
executable = True,
7679
cfg = "exec",
77-
default = Label("@io_bazel_rules_scala//src/scala/scripts:scalapb_worker"),
80+
default = Label("//src/scala/scripts:scalapb_worker"),
7881
allow_files = True,
7982
),
80-
"main_generator": attr.string(default = "scalapb.ScalaPbCodeGenerator"),
83+
"main_generator": attr.string(
84+
default = "scripts.ScalaPbCodeGenerator",
85+
),
8186
"named_generators": attr.string_dict(),
8287
"extra_generator_dependencies": attr.label_list(
8388
providers = [JavaInfo],
8489
),
8590
"scalac": attr.label(
8691
executable = True,
8792
cfg = "exec",
88-
default = Label("@io_bazel_rules_scala//src/java/io/bazel/rulesscala/scalac"),
93+
default = Label("//src/java/io/bazel/rulesscala/scalac"),
8994
allow_files = True,
9095
),
9196
"protoc": attr.label(
@@ -105,6 +110,14 @@ scala_proto_toolchain = rule(
105110
[proto rules documentation](https://docs.bazel.build/versions/master/be/protocol-buffer.html#proto_library)
106111
""",
107112
),
113+
"_main_generator_dep": attr.label(
114+
default = Label(
115+
"//src/scala/scripts:scalapb_codegenerator_wrapper",
116+
),
117+
allow_single_file = True,
118+
executable = False,
119+
cfg = "exec",
120+
),
108121
},
109122
)
110123

@@ -119,9 +132,9 @@ scala_proto_deps_toolchain = rule(
119132
attrs = {
120133
"dep_providers": attr.label_list(
121134
default = [
122-
"@io_bazel_rules_scala//scala_proto:scalapb_compile_deps_provider",
123-
"@io_bazel_rules_scala//scala_proto:scalapb_grpc_deps_provider",
124-
"@io_bazel_rules_scala//scala_proto:scalapb_worker_deps_provider",
135+
Label("//scala_proto:scalapb_compile_deps_provider"),
136+
Label("//scala_proto:scalapb_grpc_deps_provider"),
137+
Label("//scala_proto:scalapb_worker_deps_provider"),
125138
],
126139
cfg = "target",
127140
providers = [DepsInfo],

src/scala/scripts/BUILD

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
load("//scala:scala.bzl", "scala_binary", "scala_library")
2+
load("//scala:scala_cross_version_select.bzl", "select_for_scala_version")
23

34
scala_library(
45
name = "scrooge_worker_lib",
@@ -22,6 +23,18 @@ scala_binary(
2223
],
2324
)
2425

26+
scala_library(
27+
name = "scalapb_codegenerator_wrapper",
28+
srcs = select_for_scala_version(
29+
any_2_11 = ["ScalaPbCodeGeneratorWrapper_2_11.scala"],
30+
since_2_12 = ["ScalaPbCodeGeneratorWrapper.scala"],
31+
),
32+
visibility = ["//visibility:public"],
33+
deps = [
34+
"//scala_proto:scalapb_worker_deps",
35+
],
36+
)
37+
2538
scala_library(
2639
name = "scalapb_worker_lib",
2740
srcs = ["ScalaPBWorker.scala"],
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package scripts
2+
3+
import protocgen.{CodeGenApp,CodeGenRequest,CodeGenResponse}
4+
5+
object ScalaPbCodeGenerator extends CodeGenApp {
6+
def process(request: CodeGenRequest): CodeGenResponse = {
7+
try {
8+
scalapb.ScalaPbCodeGenerator.process(request)
9+
10+
} catch {
11+
case e: Throwable =>
12+
val stackStream = new java.io.ByteArrayOutputStream
13+
e.printStackTrace(new java.io.PrintStream(stackStream))
14+
CodeGenResponse.fail(stackStream.toString())
15+
}
16+
}
17+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package scripts
2+
import com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse
3+
4+
object ScalaPbCodeGenerator extends protocbridge.ProtocCodeGenerator {
5+
override def run(req: Array[Byte]): Array[Byte] = {
6+
try {
7+
scalapb.ScalaPbCodeGenerator.run(req)
8+
9+
} catch {
10+
case e: Throwable =>
11+
val b = CodeGeneratorResponse.newBuilder
12+
val stackStream = new java.io.ByteArrayOutputStream
13+
14+
e.printStackTrace(new java.io.PrintStream(stackStream))
15+
b.setError(stackStream.toString())
16+
b.build.toByteArray
17+
}
18+
}
19+
}

test/proto/custom_generator/BUILD.bazel

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1-
load("//scala_proto:scala_proto.bzl", "scala_proto_library")
2-
load("//scala:scala.bzl", "scala_library", "scala_test")
31
load("//scala:providers.bzl", "declare_deps_provider")
4-
load("//scala_proto:scala_proto_toolchain.bzl", "scala_proto_deps_toolchain", "scala_proto_toolchain")
2+
load("//scala:scala.bzl", "scala_library", "scala_test")
3+
load("//scala_proto/default:default_deps.bzl", "DEFAULT_SCALAPB_WORKER_DEPS")
4+
load("//scala_proto:scala_proto.bzl", "scala_proto_library")
5+
load(
6+
"//scala_proto:scala_proto_toolchain.bzl",
7+
"scala_proto_deps_toolchain",
8+
"scala_proto_toolchain",
9+
)
510

611
# This package contains manual tests for custom generators:
712
#
@@ -38,12 +43,7 @@ scala_library(
3843
declare_deps_provider(
3944
name = "scalapb_worker_deps_provider",
4045
deps_id = "scalapb_worker_deps",
41-
deps = [
42-
":DummyGenerator",
43-
"@com_google_protobuf//:protobuf_java",
44-
"@scala_proto_rules_scalapb_compilerplugin",
45-
"@scala_proto_rules_scalapb_protoc_bridge",
46-
],
46+
deps = [":DummyGenerator"] + DEFAULT_SCALAPB_WORKER_DEPS,
4747
)
4848

4949
scala_proto_deps_toolchain(
@@ -83,12 +83,7 @@ scala_library(
8383
declare_deps_provider(
8484
name = "failing_scalapb_worker_deps_provider",
8585
deps_id = "scalapb_worker_deps",
86-
deps = [
87-
":FailingGenerator",
88-
"@com_google_protobuf//:protobuf_java",
89-
"@scala_proto_rules_scalapb_compilerplugin",
90-
"@scala_proto_rules_scalapb_protoc_bridge",
91-
],
86+
deps = [":FailingGenerator"] + DEFAULT_SCALAPB_WORKER_DEPS,
9287
)
9388

9489
scala_proto_deps_toolchain(

0 commit comments

Comments
 (0)