objectbox / objectbox-java

Android Database - first and fast, lightweight on-device vector database
https://objectbox.io
Apache License 2.0
4.41k stars 302 forks source link

FlatBuffers version conflicts with other library #894

Closed nicodubi closed 3 years ago

nicodubi commented 4 years ago

Edit: this is due to FlatBuffers versions conflicting. See the comment below for details and potential workarounds. https://github.com/objectbox/objectbox-java/issues/894#issuecomment-674734559


@greenrobot-team I have the same issue of duplicated dependencies (between ObjectBox and GoogleArCore Sceneform):

Duplicate class com.google.flatbuffers.Constants found in modules jetified-flatbuffers-java-1.12.0.jar (com.google.flatbuffers:flatbuffers-java:1.12.0) and jetified-sceneform-base-1.15.0-runtime.jar (com.google.ar.sceneform:sceneform-base:1.15.0)
Duplicate class com.google.flatbuffers.FlatBufferBuilder found in modules jetified-flatbuffers-java-1.12.0.jar (com.google.flatbuffers:flatbuffers-java:1.12.0) and jetified-sceneform-base-1.15.0-runtime.jar (com.google.ar.sceneform:sceneform-base:1.15.0)
Duplicate class com.google.flatbuffers.FlatBufferBuilder$ByteBufferFactory found in modules jetified-flatbuffers-java-1.12.0.jar (com.google.flatbuffers:flatbuffers-java:1.12.0) and jetified-sceneform-base-1.15.0-runtime.jar (com.google.ar.sceneform:sceneform-base:1.15.0)
Duplicate class com.google.flatbuffers.FlatBufferBuilder$HeapByteBufferFactory found in modules jetified-flatbuffers-java-1.12.0.jar (com.google.flatbuffers:flatbuffers-java:1.12.0) and jetified-sceneform-base-1.15.0-runtime.jar (com.google.ar.sceneform:sceneform-base:1.15.0)
Duplicate class com.google.flatbuffers.Struct found in modules jetified-flatbuffers-java-1.12.0.jar (com.google.flatbuffers:flatbuffers-java:1.12.0) and jetified-sceneform-base-1.15.0-runtime.jar (com.google.ar.sceneform:sceneform-base:1.15.0)
Duplicate class com.google.flatbuffers.Table found in modules jetified-flatbuffers-java-1.12.0.jar (com.google.flatbuffers:flatbuffers-java:1.12.0) and jetified-sceneform-base-1.15.0-runtime.jar (com.google.ar.sceneform:sceneform-base:1.15.0)
Duplicate class com.google.flatbuffers.Utf8 found in modules jetified-flatbuffers-java-1.12.0.jar (com.google.flatbuffers:flatbuffers-java:1.12.0) and jetified-sceneform-base-1.15.0-runtime.jar (com.google.ar.sceneform:sceneform-base:1.15.0)
Duplicate class com.google.flatbuffers.Utf8Safe found in modules jetified-flatbuffers-java-1.12.0.jar (com.google.flatbuffers:flatbuffers-java:1.12.0) and jetified-sceneform-base-1.15.0-runtime.jar (com.google.ar.sceneform:sceneform-base:1.15.0)

If I follow the solution of @dpproduction everything works right. I mean adding:

 implementation ("io.objectbox:objectbox-android:$objectboxVersion"){
        exclude group: 'com.google.flatbuffers', module: 'flatbuffers-java'
    }
    annotationProcessor "io.objectbox:objectbox-processor:$objectboxVersion"

and removing the "apply plugin: 'io.objectbox'".

However I'm afraid of what you said of avoid removing the apply plugin.

I tried to add apply plugin: 'io.objectbox' in every ways (after dependencies block, at the beggining of the build.gradle app file, after the apply plugin: 'com.android.application') but nothing worked. Just removing the apply plugin.

Is there any solutions? What does it happen if I haven't the apply plugin? The ObjectBox library will work with errors?

Thanks!!

Originally posted by @nicodubi in https://github.com/objectbox/objectbox-java/issues/479#issuecomment-669634048

nicodubi commented 4 years ago

Please, any update of this issue? @greenrobot-team @greenrobot I need to know if I could use and trust in ObjectBox for my mobile app or not .

greenrobot commented 4 years ago

You did not state which version of ObjectBox you are using. Are you on the latest 2.7.0?

nicodubi commented 4 years ago

Oh sorry, yes, I'm trying with 2.7.0 version. Please, let me know anything I could show you in order to step forward.

here is my build.gradle (project level):

buildscript {

    repositories {
        google()
        jcenter()
    }
    ext.objectboxVersion = '2.7.0'

    dependencies {
        classpath 'com.android.tools.build:gradle:4.0.1'
        classpath 'com.google.gms:google-services:4.3.3'
        classpath "io.objectbox:objectbox-gradle-plugin:$objectboxVersion"
        classpath 'com.google.firebase:firebase-crashlytics-gradle:2.2.0'
        classpath 'com.google.ar.sceneform:plugin:1.13.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        maven {
            url "https://maven.google.com"
        }
        maven { url "https://jitpack.io" }
    }
}
task clean(type: Delete) {
    delete rootProject.buildDir
}

build.gradle (app)

apply plugin: 'com.android.application'
apply plugin: 'com.google.firebase.crashlytics'

android {

    compileSdkVersion 28
    flavorDimensions "default"
....
buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }

        debug {
            debuggable true
            minifyEnabled false
            shrinkResources false
        }

        applicationVariants.all { variant ->
            variant.outputs.each { output ->
                def name = "Cartear_${variant.versionName}(${variant.versionCode})_${variant.name}.apk"
                output.outputFileName = name
            }
        }
    }
    packagingOptions {
        exclude 'META-INF/rxjava.properties'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/io.netty.versions.properties'
        exclude 'META-INF/INDEX.LIST'
        exclude 'META-INF/DEPENDENCIES'

    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    // Ensure the no-op dependency is always used in JVM tests.
    configurations.all { config ->
        if (config.name.contains('UnitTest')) {
            config.resolutionStrategy.eachDependency { details ->
                if (details.requested.group == 'com.squareup.leakcanary' && details.requested.name == 'leakcanary-android') {
                    details.useTarget(group: details.requested.group, name: 'leakcanary-android-no-op', version: details.requested.version)
                }
            }
        }
        resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9'
    }
}
dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'com.google.android.gms:play-services-maps:17.0.0'
    implementation 'androidx.appcompat:appcompat:1.1.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.2.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.1'
    releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    }

    //dagger annotation processor
    annotationProcessor "com.google.dagger:dagger-android-processor:2.27"
    annotationProcessor "com.google.dagger:dagger-compiler:2.27"

    //FACEBOOK LOGIN
    implementation 'com.facebook.android:facebook-login:4.32.0'
    implementation project(':common')

    implementation ("io.objectbox:objectbox-android:$objectboxVersion"){
        exclude group: 'com.google.flatbuffers', module: 'flatbuffers-java'
    }
    annotationProcessor "io.objectbox:objectbox-processor:$objectboxVersion"

}
apply plugin: 'com.google.gms.google-services'
//apply plugin: 'io.objectbox'

and build.gradle (common module)

apply plugin: 'com.android.library'
apply plugin: 'com.google.ar.sceneform.plugin'

android {
    compileSdkVersion 28

    defaultConfig {
...
     }
}
greenrobot-team commented 4 years ago

First, make sure to apply the plugin. Then change:

implementation ("io.objectbox:objectbox-android:$objectboxVersion"){
    exclude group: 'com.google.flatbuffers', module: 'flatbuffers-java'
}

to

implementation "io.objectbox:objectbox-android:$objectboxVersion"
implementation ("io.objectbox:objectbox-java:$objectboxVersion"){
    exclude group: 'com.google.flatbuffers', module: 'flatbuffers-java'
}

Does that work?

Note: you can use gradlew :app:dependencies to inspect the dependency tree and see where FlatBuffers might still be included.

nicodubi commented 4 years ago

Sorry but that doesn't work. I don't know what more can I do. I really need to solve this, I can't compile the project! I attach the result of gradlew :app:dependencies so you can review that all flatbuffer duplicated dependencies are from greenrobot....

flatbuffer duplicated app dependencies.txt

As you could see every flatbuffers dependencies are from greenrobot...

I tried with the apply plugin: 'io.objectbox' at the beginning, at the end, but the error still happens. I tried with

implementation ("io.objectbox:objectbox-android:$objectboxVersion"){ exclude group: 'com.google.flatbuffers', module: 'flatbuffers-java' } I tried with implementation "io.objectbox:objectbox-android:$objectboxVersion" implementation ("io.objectbox:objectbox-java:$objectboxVersion"){ exclude group: 'com.google.flatbuffers', module: 'flatbuffers-java' } I tried with buildscript { dependencies { classpath "io.objectbox:objectbox-gradle-plugin:2.7.0" } } in the project build.gradle , then in the module app build.gradle. But alaways the same result: when apply plugin: 'io.objectbox' line is present, the error occurs!!!!

Duplicate class com.google.flatbuffers.Constants found in modules jetified-flatbuffers-java-1.12.0.jar (com.google.flatbuffers:flatbuffers-java:1.12.0) and jetified-sceneform-base-1.15.0-runtime.jar (com.google.ar.sceneform:sceneform-base:1.15.0) Duplicate class com.google.flatbuffers.FlatBufferBuilder found in modules jetified-flatbuffers-java-1.12.0.jar (com.google.flatbuffers:flatbuffers-java:1.12.0) and jetified-sceneform-base-1.15.0-runtime.jar (com.google.ar.sceneform:sceneform-base:1.15.0) Duplicate class com.google.flatbuffers.FlatBufferBuilder$ByteBufferFactory found in modules jetified-flatbuffers-java-1.12.0.jar (com.google.flatbuffers:flatbuffers-java:1.12.0) and jetified-sceneform-base-1.15.0-runtime.jar (com.google.ar.sceneform:sceneform-base:1.15.0) Duplicate class com.google.flatbuffers.FlatBufferBuilder$HeapByteBufferFactory found in modules jetified-flatbuffers-java-1.12.0.jar (com.google.flatbuffers:flatbuffers-java:1.12.0) and jetified-sceneform-base-1.15.0-runtime.jar (com.google.ar.sceneform:sceneform-base:1.15.0) Duplicate class com.google.flatbuffers.Struct found in modules jetified-flatbuffers-java-1.12.0.jar (com.google.flatbuffers:flatbuffers-java:1.12.0) and jetified-sceneform-base-1.15.0-runtime.jar (com.google.ar.sceneform:sceneform-base:1.15.0) Duplicate class com.google.flatbuffers.Table found in modules jetified-flatbuffers-java-1.12.0.jar (com.google.flatbuffers:flatbuffers-java:1.12.0) and jetified-sceneform-base-1.15.0-runtime.jar (com.google.ar.sceneform:sceneform-base:1.15.0) Duplicate class com.google.flatbuffers.Utf8 found in modules jetified-flatbuffers-java-1.12.0.jar (com.google.flatbuffers:flatbuffers-java:1.12.0) and jetified-sceneform-base-1.15.0-runtime.jar (com.google.ar.sceneform:sceneform-base:1.15.0) Duplicate class com.google.flatbuffers.Utf8Safe found in modules jetified-flatbuffers-java-1.12.0.jar (com.google.flatbuffers:flatbuffers-java:1.12.0) and jetified-sceneform-base-1.15.0-runtime.jar (com.google.ar.sceneform:sceneform-base:1.15.0)

Please I need to know what to do to solve this and start using object box (I don't want to keep using Room or Realm)

nicodubi commented 4 years ago

Here I attach both build.gradle files (app and project). Maybe you could see what's happening:

app build gradle.txt project build gradle.txt

Thanks.

Looking forward to your reply @greenrobot @greenrobot-team

nicodubi commented 4 years ago

I realized that the "apply plugin: 'io.objectbox'" is not the whole problem, because as you can see:

app build gradle not working.txt

the line is commented but the error still occurs with implementation "io.objectbox:objectbox-android:2.7.0" If I comment that line the app runs right.

Also the other way to works right is with the exclude implementation ("io.objectbox:objectbox-android:2.7.0"){ exclude group: 'com.google.flatbuffers', module: 'flatbuffers-java' }

app build gradle works right.txt

Please help me!

nicodubi commented 4 years ago

Greenrobot! I have an idea! @greenrobot @greenrobot-team Could you create a new Android project and add to the app build.gradle dependencies: implementation 'com.google.ar.sceneform.ux:sceneform-ux:1.15.0'

And try to make that google sceneform dependency and ObjectBox coexist together in the same project. Could you? You really would help a lot of people that can't use ObjectBox and Sceneform in the same app.

Please, tell me if I could help you with whatever you need.

greenrobot-team commented 4 years ago

Please share the output of the Gradle task :cartear:dependencies! The one you shared is from :cartear:androidDependencies which does not show the dependency tree hierarchy.

greenrobot-team commented 4 years ago

OK, researched some more. Adding the following to the app build.gradle works in an example project:

configurations.all {
    exclude group: 'com.google.flatbuffers', module: 'flatbuffers-java'
}

However, this solution might stop working in the future. ObjectBox code might use FlatBuffers API functionality in the future that is not present in the version packaged by AR core.

The sceneform-android-sdk is no longer developed, but it is open source! It should be possible to manually package https://github.com/google-ar/sceneform-android-sdk without the FlatBuffers source files (and instead add a true dependency). Or maybe there are actively maintained forks that did this already?

More info: com.google.ar.sceneform:sceneform-base is the actual package that has the FlatBuffers classes packaged.

nicodubi commented 4 years ago

Today I tried with

configurations.all {
    exclude group: 'com.google.flatbuffers', module: 'flatbuffers-java'
}

And the compile process worked great. However I had three doubts and one big issue: Doubts: 1) What will happen with Sceneform and ObjectBox when both need to do some work with Flatbuffers? Because the exclude flatbuffer inside configuration.all will make to disappear FlatBuffers from my whole project, right? or it still will be packaged in ArCoreSceneform dependency? 2) I understand what you say about future functionalities in ObjectBox that might require FlatBuffers API that is not present in the version of ArCore... , but if I don't need to upgrade Sceneform (1.15.0) nor ObjectBox (2.7.0) that would not be a problem, right? 3) When I ran the project and starts the compiling process, this warning appears in the console: Note: [ObjectBox] Starting ObjectBox processor (debug: false, incremental: true) I have to do something with that?

Issue: 1) After of the successful compile I started to follow the "First steps" to use ObjectBox. I just copied pasted the ObjectBox class:

public class ObjectBox {
    private ObjectBox() {

    }

    private static BoxStore boxStore;

    public static void init(Context context) {
        boxStore = MyObjectBox.builder()
                .androidContext(context.getApplicationContext())
                .build();
    }

    public static BoxStore get() {
        return boxStore;
    }
}

and call the init(this) from my Application class. I wrote a simple class:

@Entity
public class UserProfile {
    private String photoURL;
    private String firstname;
    private String lastname;
    @NonNull @Index @Unique
    private String uuid;
    private String loginProvider;
    @Id public long boxID;

    //TODO ADDRESS

    public String getLoginProvider() {
        return loginProvider;
    }

    public void setLoginProvider(String loginProvider) {
        this.loginProvider = loginProvider;
    }

    public String getUuid() {
        return uuid;
    }

    public void setUuid(String uuid) {
        this.uuid = uuid;
    }

    public String getPhotoURL() {
        return photoURL;
    }

    public void setPhotoURL(String photoURL) {
        this.photoURL = photoURL;
    }

    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    @NonNull
    @Override
    public String toString() {
        return "UserId: " + FirebaseHelper.getUID() + " UserEmail: " + FirebaseHelper.getEmail()
                + "Name: " + Utils.getString(firstname) + " " + Utils.getString(lastname);
    }
}

And when I ran the app, the app inmediately crash with this error:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.cartear.cartear, PID: 6235
    java.lang.NoSuchMethodError: No virtual method startTable(I)V in class Lcom/google/flatbuffers/FlatBufferBuilder; or its super classes (declaration of 'com.google.flatbuffers.FlatBufferBuilder' appears in /data/app/com.cartear.cartear-Fu0-ugATw-pl7Ciqa7-yiQ==/base.apk!classes3.dex)
        at io.objectbox.model.ModelProperty.startModelProperty(ModelProperty.java:69)
        at io.objectbox.ModelBuilder$PropertyBuilder.finish(ModelBuilder.java:116)
        at io.objectbox.ModelBuilder$EntityBuilder.checkFinishProperty(ModelBuilder.java:206)
        at io.objectbox.ModelBuilder$EntityBuilder.property(ModelBuilder.java:199)
        at io.objectbox.ModelBuilder$EntityBuilder.property(ModelBuilder.java:193)
        at io.objectbox.ModelBuilder$EntityBuilder.property(ModelBuilder.java:189)
        at com.cartear.cartear.model.MyObjectBox.buildEntityUserProfile(MyObjectBox.java:43)
        at com.cartear.cartear.model.MyObjectBox.getModel(MyObjectBox.java:32)
        at com.cartear.cartear.model.MyObjectBox.builder(MyObjectBox.java:21)
        at com.cartear.cartear.db.ObjectBox.init(ObjectBox.java:24)
        at com.cartear.cartear.application.CartearApplication.onCreate(CartearApplication.java:36)
        at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1190)
        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6540)
        at android.app.ActivityThread.access$1400(ActivityThread.java:220)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1883)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:224)
        at android.app.ActivityThread.main(ActivityThread.java:7520)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
E/MQSEventManagerDelegate: failed to get MQSService.

Hope you could help me with the runtime issue and with both doubts. Thanks a lot! @greenrobot @greenrobot-team

nicodubi commented 4 years ago

@greenrobot @greenrobot-team Any update about the issue and doubts of the above comment? Please I really need and appreciate your help in order to go forward.

Thanks!

greenrobot-team commented 4 years ago

The Sceneform SDK packages the FlatBuffers sources (instead of declaring a dependency), so excluding flatbuffers-java won't remove it from there.

The error you get is exactly what I was afraid of, ObjectBox expects a newer FlatBuffers API (FlatBufferBuilder.startTable(...)) that is not present in the FlatBuffers version packaged into the Sceneform SDK.

Your best option is to fork the Sceneform SDK. Then either

Task for us:

qathom commented 4 years ago

Hello! I'm also looking for a solution :/

pelusodan commented 3 years ago

Any updates on re-packaging FlatBuffers for ObjectBox? Still running into this issue 😖

greenrobot commented 3 years ago

I'm curious, is the other FlatBuffers lib older and what's the dependency?

greenrobot-team commented 3 years ago

The next update will ship without the FlatBuffers dependency. Instead the FlatBuffers Java code version this library uses is copied to a different package name.

This will make it possible for user (your) code to use any other version of FlatBuffers Java library and flatc generated code. And prevent conflicts with other libraries not properly repackaging FlatBuffers like above.

Dark7SiD commented 3 years ago

not working for me also

greenrobot commented 3 years ago

Did you try 2.9.2-RC3?

sandsaber commented 3 years ago

Did you try 2.9.2-RC3?

For me, seem like problem fixed. (Problem was in junit test run)

greenrobot-team commented 3 years ago

This is now available with the 3.0.1 release.

tbikash62 commented 3 years ago

@greenrobot-team

Hello I'm still getting the error.

Exact Error - Duplicate class com.google.flatbuffers.Constants found in modules jetified-flatbuffers-java-1.12.0.jar (com.google.flatbuffers:flatbuffers-java:1.12.0) and jetified-sceneform-base-1.6.0-runtime.jar (com.google.ar.sceneform:sceneform-base:1.6.0) Duplicate class com.google.flatbuffers.FlatBufferBuilder found in modules jetified-flatbuffers-java-1.12.0.jar (com.google.flatbuffers:flatbuffers-java:1.12.0) and jetified-sceneform-base-1.6.0-runtime.jar (com.google.ar.sceneform:sceneform-base:1.6.0) Duplicate class com.google.flatbuffers.FlatBufferBuilder$ByteBufferFactory found in modules jetified-flatbuffers-java-1.12.0.jar (com.google.flatbuffers:flatbuffers-java:1.12.0) and jetified-sceneform-base-1.6.0-runtime.jar (com.google.ar.sceneform:sceneform-base:1.6.0) Duplicate class com.google.flatbuffers.FlatBufferBuilder$HeapByteBufferFactory found in modules jetified-flatbuffers-java-1.12.0.jar (com.google.flatbuffers:flatbuffers-java:1.12.0) and jetified-sceneform-base-1.6.0-runtime.jar (com.google.ar.sceneform:sceneform-base:1.6.0) Duplicate class com.google.flatbuffers.Struct found in modules jetified-flatbuffers-java-1.12.0.jar (com.google.flatbuffers:flatbuffers-java:1.12.0) and jetified-sceneform-base-1.6.0-runtime.jar (com.google.ar.sceneform:sceneform-base:1.6.0) Duplicate class com.google.flatbuffers.Table found in modules jetified-flatbuffers-java-1.12.0.jar (com.google.flatbuffers:flatbuffers-java:1.12.0) and jetified-sceneform-base-1.6.0-runtime.jar (com.google.ar.sceneform:sceneform-base:1.6.0)

Go to the documentation to learn how to Fix dependency resolution errors.

greenrobot commented 3 years ago

@tbikash62 Please double check. See https://github.com/objectbox/objectbox-java/blob/main/objectbox-java/src/main/java/io/objectbox/flatbuffers/Constants.java as an example that we changed the package.

tbikash62 commented 3 years ago

Hello @greenrobot

Thank you for responding. I agree, some work has been done.

but for me I tried a lot to change around so that it can coexist(Sceneform + Flatbuffers)

What I'm trying to do is as below - In the below build.gradle file https://github.com/tensorflow/examples/blob/master/lite/examples/object_detection/android/app/build.gradle

And then introduce there in the same build.gradle file- (implementation "com.google.ar.sceneform.ux:sceneform-ux:1.6.0")

I can see that error. So what's needed to be changed any hint?

I thank you in advance.

greenrobot-team commented 3 years ago

@tbikash62 The project you link to does not include ObjectBox. That the Sceneform SDK from Google includes a not repackaged FlatBuffers version is known and not something we, the ObjectBox team, can fix.