Describe the bug
The pulsar-client-admin-2.5.0.jar available on Maven Central incorrectly contains an unshaded protobuf dependency.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
The protobuf classes should be shaded, under org.apache.pulsar.shade.come.google.protobuf.*
Screenshots

Additional context
This causes a collsiion with the (newer, v3.7.0) version we already depend on in our project, resulting in NoSuchMethodError failures at runtime.
@yjshen Would you please help check this issue?
The unshaded part was introduced deliberately by https://github.com/apache/pulsar/pull/3184/files#diff-9de37f4080556c0ee70ef82b066396f7R120-R122.
@jerrypeng since you added these, any ideas on why not shading the protobuf classes?
I think the reason was because to support ProtobufSchema correctly in PulsarClient. If a user gives the client a generated Protobuf object, the client needs to have Protobuf classes at the same classpath as the user given Protobuf Object. If a user provides a protobuf object to the client but the included protobuf dependencies are all shaded, then there will be "NoClassDefError"s thrown as none of the internal protobuf class with be at the expected classpath.
If a user is providing a protobuf object to the client, then chances are they already have their preferred version of Protobuf on their classpath though? Would it be better to exclude the protobuf classes from the Pulsar jar and require the user to include an appropriate version on their classpath themselves or would that then cause problems on the Pulsar side of things?
Hello, faced this issue. Is there any workaround to exclude these protobuf classes?
We are having the issue too.
I think we can try to make the protobuf schema dependencies as provided.
@jiazhai @gaoran10 let's pick this up the coming week.
Get it.
Shading protobuf might not solve all issues. The generated protobuf classes seem to have dependencies to specific protobuf version like already mentioned in https://github.com/apache/pulsar/issues/6484#issuecomment-600413743. Here's an example of a stack trace when using Pulsar client 2.5.1 and a Protobuf class compiled with Protobuf protoc version 3.11.4 :
java.lang.NoSuchMethodError: 'com.google.protobuf.Descriptors$FileDescriptor com.google.protobuf.Descriptors$FileDescriptor.internalBuildGeneratedFileFrom(java.lang.String[], com.google.protobuf.Descriptors$FileDescriptor[])'
at my.code.proto.SomeOuterClass.<clinit>(SomeOuterClass.java:44)
at my.code.proto.SomeApi.<clinit>(SomeApi.java:75)
at my.code.proto.Something.getDescriptor(Something.java:112)
... 139 more
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at org.apache.pulsar.shade.org.apache.avro.protobuf.ProtobufData.getSchema(ProtobufData.java:189)
at org.apache.pulsar.client.impl.schema.ProtobufSchema.createProtobufAvroSchema(ProtobufSchema.java:64)
at org.apache.pulsar.client.impl.schema.ProtobufSchema.of(ProtobufSchema.java:120)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.apache.pulsar.client.internal.DefaultImplementation.lambda$newProtobufSchema$25(DefaultImplementation.java:235)
at org.apache.pulsar.client.internal.ReflectionUtils.catchExceptions(ReflectionUtils.java:35)
at org.apache.pulsar.client.internal.DefaultImplementation.newProtobufSchema(DefaultImplementation.java:232)
at org.apache.pulsar.client.api.Schema.PROTOBUF(Schema.java:220)
...
Caused by:
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.apache.pulsar.shade.org.apache.avro.protobuf.ProtobufData.getSchema(ProtobufData.java:183)
... 134 more
Caused by:
java.lang.NoSuchMethodError: 'com.google.protobuf.Descriptors$FileDescriptor com.google.protobuf.Descriptors$FileDescriptor.internalBuildGeneratedFileFrom(java.lang.String[], com.google.protobuf.Descriptors$FileDescriptor[])'
at my.code.proto.SomeOuterClass.(SomeOuterClass.java:44)
at my.code.proto.SomeApi.(SomeApi.java:75)
at my.code.proto.Something.getDescriptor(Something.java:112)
... 139 more
It seems that Apache Avro depends on a specific Protobuf version and it's not possible to upgrade it since it's shaded. Is there a plain "unshaded" Pulsar client available?
It seems that Avro 1.9.1 depends on Protobuf 3.6.1 . That was released 31-Jul-2018 . The newest Protobuf version is currently 3.11.4 .
Is there a way to use a newer Protobuf version with Pulsar?
UPDATE: it seems that my issue would also be resolved if pulsar-client-admin-2.5.x.jar would contain a shaded Protobuf version. In my case, the unshaded classes got loaded from pulsar-client-admin-2.5.1.jar and that caused the issue and exception.
However my question is that why is protobuf shaded in the first place? Could it be an optional dependency instead so that the user would have to include protobuf if the user is using protobuf features of Pulsar. Anyhow the user's code is dependent on the protobuf version that the user protobuf classes have been compiled with. I investigated the issue and Protobuf versions <3.8.0 aren't compatible with Protobuf generated classes that have been compiled with Protobuf protoc >=3.8.0 (I tracked the breaking change in Protobuf Java to be dependent on this change https://github.com/protocolbuffers/protobuf/commit/d0f91c863ae0fbb75b41460c8bbb786ade197a0f#diff-8168b8744060c287ceee789b0eb8cbb4R403-R405)
Just ran into this issue too. Is there a work around?
Just ran into this issue too. Is there a work around?
@mwmitchell One workaround is to use the unshaded version of pulsar-client-admin . The dependency is pulsar-client-admin-original . A similar unshaded dependency for pulsar-client is called pulsar-client-original.
Most helpful comment
If a user is providing a protobuf object to the client, then chances are they already have their preferred version of Protobuf on their classpath though? Would it be better to exclude the protobuf classes from the Pulsar jar and require the user to include an appropriate version on their classpath themselves or would that then cause problems on the Pulsar side of things?