Brijesh-Thakkar opened a new pull request, #40904:
URL: https://github.com/apache/beam/pull/40904

   Addresses #19713.
   
   `ProtoCoder` stores only the message class and finds its `Parser` lazily 
through `getDefaultInstance()`. For a generic `T extends Message` the type is 
erased to the `com.google.protobuf.Message` interface, which has no 
`getDefaultInstance()`. A coder for it can never decode, and the failure on the 
worker was a bare `NoSuchMethodException: 
com.google.protobuf.Message.getDefaultInstance()`, as reported in the issue.
   
   The concrete type is not recoverable at decode time (the wire format carries 
no type information), so this PR does not try to make that coder work and does 
not change what succeeds or fails. It only makes the failure understandable: 
`ProtoCoder.getParser()` now throws an `IllegalArgumentException` (the same 
exception type as before, with the original `NoSuchMethodException` as the 
cause) saying why the parser cannot be found and to use a concrete generated 
message class, `DynamicProtoCoder`, or `setCoder()`. The existing 
`DynamicMessage` path is untouched.
   
   Earlier attempts (#34194, #37005) added an instantiation fallback. That 
cannot work for an interface, and their tests did not fail before the change. 
The decode test here fails on master (old message, no guidance) and passes with 
the change.
   
   **Behaviour change:** none beyond the error message. Encoding with a 
raw-`Message` coder still works and is covered by a test.
   
   Testing:
   - `./gradlew :sdks:java:extensions:protobuf:spotlessCheck 
:sdks:java:extensions:protobuf:test` : 196 tests, all pass.
   - `testDecodeWithRawMessageClass` fails on master (old 
`NoSuchMethodException` message), passes with the change. 
`testEncodeWithRawMessageClass` passes before and after.
   - GCP IO (users of `ProtoCoder`): `PubsubIOTest`, `PubsubUnboundedSinkTest`, 
`PubsubMessageWith*CoderTest`, `BigQueryIOStorageReadTest` : 133 tests, all 
pass.
   - CHANGES.md updated under Bugfixes.
   
   ## Possible follow-up (for the maintainer to decide)
   
   Coder inference (`CoderRegistry`) still returns a `ProtoCoder<Message>` 
silently for the raw `Message` type, so the failure only appears at decode time 
on the worker. A small follow-up would make `ProtoCoderProvider.coderFor` throw 
`CannotProvideCoderException` for it, so the failure moves to pipeline 
construction (test: `testRegistryRejectsRawMessageType`). I held it back 
because it is a behaviour change: a pipeline that relied on inference for an 
erased `T extends Message` and only ever encoded (never decoded, shuffled or 
checkpointed) works today and would then need an explicit `setCoder()`. No Beam 
code constructs a raw-`Message` coder (grep of main and test code), and the 
protobuf and GCP IO tests pass with it. It is ready as a separate local commit 
if wanted.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to