Skip to content

Interoperability between protobuf-javalite and protobuf-java #290

@viktor-kostadinovski

Description

@viktor-kostadinovski

The problem

Clients using protobuf-java instead of protobuf-javalite have to migrate their codebase to protobuf-javalite in order to integrate with PlaidSDK
The PlaidSDK is using protobuf-javalite, which expects GeneratedMessageLite classes, while our project is using protobuf-java, which works with GeneratedMessage classes (such as Struct). This mismatch unfortunately causes the verifier to reject the class during runtime, as it’s expecting GeneratedMessageLite but encountering a class from protobuf-java instead , which is the Struct.
This leads to the following error :

java.lang.NoSuchMethodError: No virtual method build()Lcom/google/protobuf/GeneratedMessageLite; in class Lcom/google/protobuf/Timestamp$Builder; or its super classes (declaration of 'com.google.protobuf.Timestamp$Builder' appears in /data/app/~~kr4cSZrPd_dXG0MQKGpZDQ==/com.kaching.merchant.dev0-yhGyMQvWrSi28Sq9If92wg==/base.apk!classes39.dex)
                                                                                                    	at com.plaid.internal.xk.a(SourceFile:106)
                                                                                                    	at com.plaid.internal.z8.a(SourceFile:3436)
                                                                                                    	at com.plaid.internal.z8$j.invokeSuspend(SourceFile:1)

We have encountered similar cases and there is multiple solutions to support clients that use protobuf-java as well as protobuf-javalite

Possible solutions :

  • PlaidSDK keeps using protobuf-javalite but generate the protobuf files for protobuf-java , i.e. generate the classes from the .proto files to be compatible with protobuf-java ( i.e. Use Struct instead of GeneratedMessageLite for example)
  • additionally include the dependency : com.google.firebase:protolite-well-known-types , which includes (the Struct for example). That way a client using protobuf-javalite can simply integrate
    and a client using protobuf-java , can simply exclude the dependencies , similar to firebase-performance
    like :
 implementation(FirebasePerformance) {
        exclude(group = "com.google.protobuf", module = "protobuf-javalite")
        exclude(group = "com.google.firebase", module = "protolite-well-known-types")
    }

Since protobuf-java already includes these well-known-types, that’s the most minimally invasive option to accommodate SDK integrators in both cases.

  • We have also seen SDK providers that offer 2 versions , one with protobuf-java and one with protobuf-javalite, however that requires maintaining both versions , so its not the most direct approach.

Useful links :

protocolbuffers/protobuf#8104
firebase/firebase-android-sdk#5997 (comment)
https://github.com/firebase/firebase-android-sdk/tree/main/protolite-well-known-types#problem

Environment

Android OS Version e.g. 13.0.0 (21)
Android Devices/Emulators e.g. Pixel 6a emulator

Expected Result

Should not be required to change our dependencies for protobuf.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions