如何在 Beam Pulsar connector 中访问 PulsarMessage 的主题和 payload?
结论
从给出的类定义看,PulsarMessage 没有向包外代码公开 topic、value 等字段的 getter。因此,在包外的 DoFn<PulsarMessage> 中调用 message.getValue() 会因访问权限不足而报错。仅凭这些代码,无法判断这是有意设计还是接口遗漏;可以确定的是,当前展示的 API 无法通过这些方法读取 payload。
为什么会报错
在 Java 中,没有写访问修饰符的方法具有包级访问权限。问题中的 PulsarMessage 声明了这样的方法:
abstract byte[] getValue();
它没有 public 修饰符。生成类 AutoValue_PulsarMessage 中的 getValue() 也没有声明为 public。所以,org.apache.beam.sdk.io.pulsar 包之外的代码无法调用这些方法。getTopic()、getKey()、getProperties() 也有相同限制。
可行的处理方式
-
在消息转换为
PulsarMessage之前读取 payload。问题中的create(Message<byte[]> message)展示了转换过程:payload 来自message.getValue(),topic 来自message.getTopicName()。如果读取流程能在这一步处理原始Message<byte[]>,就可以在那里提取所需字段。当前材料没有说明 Beam connector 的读取配置或可用的转换钩子,因此无法判断你的 pipeline 是否能采用这种方式。 -
让 connector 提供公开的访问接口。如果 pipeline 必须接收
PulsarMessage,就需要使用提供公开 getter 的 connector 版本,或调整 connector API。例如,可以将基类中的声明改为public abstract byte[] getValue();,并为需要公开的其他字段提供相应的publicgetter。还应检查项目对 API 兼容性和代码生成的要求,并按要求处理。 -
确认是否支持其他输出类型或转换入口。对照实际使用的 Beam Pulsar IO 配置和版本文档,确认能否直接输出原始 Pulsar 消息,或在读取阶段完成转换。现有材料无法确认该 connector 是否提供这些选项。
toString() 不能替代 getter。给出的代码没有定义它的输出格式,因此不能依靠它可靠地提取 topic 或 payload。反射也不适合作为常规解决方案,因为它绕过类型和访问控制,并依赖实现细节。
注意事项
这个错误发生在 Java 编译期。用 try/catch 捕获运行时异常,无法让不可访问的方法变得可调用。你可以继续打印 message.toString() 来调试,但它不保证包含消息内容,格式也不保证稳定。
备注:内容仅供参考。
