I am integrating Back4App into my app and am following the android tutorials step by step and am now in the live-query portion of the tutorial and encountered an issue with duplicate okhttp3 libraries. I am able to build the project successfully, however when attempting to run, I receive compilation error stating
Program type already present: okhttp3.internal.ws.WebSocketReader$FrameCallback
My App level build.gradle is
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
defaultConfig {
applicationId 'my.app.id'
//multiDexEnabled true
minSdkVersion 19
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
productFlavors {
}
configurations.all {
// OkHttp 3.5.0+ includes the websockets API, so we need this to prevent a conflict
//exclude module: 'okhttp-ws'
}
packagingOptions {
exclude 'META-INF/rxjava.properties'
}
}
dependencies {
// Google GCM Firebase stuff
implementation 'com.parse.bolts:bolts-android:1.4.0'
implementation 'com.google.firebase:firebase-core:16.0.3'
implementation 'com.google.firebase:firebase-messaging:17.3.0'
// Back4App library
implementation 'com.parse:parse-android:1.16.3'
// Back4App Live Query Client
// *************************************************** //
implementation 'com.github.tgio:parse-livequery:1.0.3'
// *************************************************** //
// in-app billing
implementation 'com.android.billingclient:billing:1.1'
// Arch COmponents ViewModelProviders Library
implementation "android.arch.lifecycle:extensions:$rootProject.lifecycle_version"
annotationProcessor "android.arch.persistence.room:compiler:$rootProject.room_version"
// For Room Dependencies
implementation "android.arch.persistence.room:runtime:$rootProject.room_version"
//implementation "android.arch.persistence.room:compiler:$room_version"
// Room -- Optionales
implementation "android.arch.persistence.room:rxjava2:$rootProject.room_version"
// Room Test helpers
testImplementation "android.arch.persistence.room:testing:$rootProject.room_version"
implementation 'de.hdodenhof:circleimageview:2.2.0'
implementation 'com.android.support:design:27.1.1'
implementation 'com.android.support:support-v4:27.1.1'
implementation 'com.android.support:support-v13:27.1.1'
implementation 'com.android.support:cardview-v7:27.1.1'
implementation 'org.jetbrains:annotations-java5:15.0'
implementation 'com.android.support:recyclerview-v7:27.1.1'
implementation 'com.android.support:support-vector-drawable:27.1.1'
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
// AndroidJUnitRunner and JUnit Rules
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test:rules:1.0.2'
// Espresso dependencies
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-contrib:3.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-intents:3.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-accessibility:3.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-web:3.0.2'
androidTestImplementation 'com.android.support.test.espresso.idling:idling-concurrent:3.0.2'
// Espresso dependency either "compile" or "androidTestImplementation", depends on app's implementation
androidTestImplementation 'com.android.support.test.espresso:espresso-idling-resource:3.0.2'
// Required -- JUnit 4 framework
testImplementation 'junit:junit:4.12'
// Optional -- Mockito framework
testImplementation 'org.mockito:mockito-core:2.15.0'
androidTestImplementation 'com.android.support:support-annotations:27.1.1'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test:rules:1.0.2'
}
repositories {
jcenter()
google()
maven {
url "https://maven.google.com"
}
}
apply plugin: 'com.google.gms.google-services'
this is the Activity that I am testing
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.EditText;
import com.parse.Parse;
import com.parse.ParseException;
import com.parse.ParseObject;
import com.parse.SaveCallback;
import org.json.JSONObject;
import tgio.parselivequery.BaseQuery;
import tgio.parselivequery.LiveQueryClient;
import tgio.parselivequery.LiveQueryEvent;
import tgio.parselivequery.interfaces.OnListener;
public class QueryExample extends AppCompatActivity {
// Subscription
final tgio.parselivequery.Subscription sub = new BaseQuery.Builder("message")
.where("destination", "pokelist")
.addField("content")
.build()
.subscribe();
// Back4App's Parse setup
private void initializeParse() {
Parse.initialize(new Parse.Configuration.Builder(this)
.applicationId(getResources().getString(R.string.back4app_server_url))
.clientKey(getResources().getString(R.string.back4app_client_key))
.server("https://parseapi.back4app.com/")
.build());
initLiveQueryClient();
}
// Init Live Query Client
private void initLiveQueryClient() {
// Example: 'wss://livequerytutorial.back4app.io'
LiveQueryClient.init("wss://"+"myprototype.back4app.io",
getResources().getString(R.string.back4app_app_id),
true);
LiveQueryClient.connect();
}
int numPokes = 0;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_live_query_example);
EditText pokeText = findViewById(R.id.pokeText);
initializeParse();
sub.on(LiveQueryEvent.CREATE, new OnListener() {
@Override
public void on(JSONObject object) {
runOnUiThread(new Runnable() {
@Override
public void run() {
EditText pokeText = findViewById(R.id.pokeText);
numPokes++;
if(numPokes == 1) {
pokeText.setText("Poked " + numPokes + " time.");
}
else {
pokeText.setText("Poked " + numPokes + " times.");
}
}
});
}
});
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View view) {
ParseObject poke = new ParseObject("Message");
poke.put("content", "poke");
poke.put("destination", "pokelist");
poke.saveInBackground(new SaveCallback() {
@Override
public void done(ParseException e) {
Snackbar.make(view, "Poke has been sent!", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
});
}
}
I notice when commenting out
implementation 'com.github.tgio:parse-livequery:1.0.3'
from my app level build.gradle, am able to compile and run the app, however the QueryExample Activity above crashes due to it missing the okhttp3-ws import
I have researched numerous Stack Overflow questions regarding this problem and implemented this solution Here. The reasoning is explained in this Github Forum (deprecation) however, similar to cinder92 comment on Mar 21, 2017 , the problem persists. Has anyone gone through this issue and if so found a solution? My Activity briefly ran until it crashed with error log
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.kungfu.tuga, PID: 25976
java.lang.NoClassDefFoundError: Failed resolution of: Lokhttp3/ws/WebSocketListener;
at tgio.parselivequery.LiveQueryClient.getNewRequestId(LiveQueryClient.java:128)
at tgio.parselivequery.BaseQuery$Builder.<init>(BaseQuery.java:100)
at com.kungfu.tuga.utilities.the_wire.QueryExample.<init>(QueryExample.java:27)
at java.lang.Class.newInstance(Native Method)
at android.app.Instrumentation.newActivity(Instrumentation.java:1174)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2669)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Caused by: java.lang.ClassNotFoundException: Didn't find class "okhttp3.ws.WebSocketListener" on path: DexPathList[[zip file "/data/app/com.kungfu.tuga-9jJWU4yht8e1tuYOuZmIQQ==/base.apk"],nativeLibraryDirectories=[/data/app/com.kungfu.tuga-9jJWU4yht8e1tuYOuZmIQQ==/lib/x86, /system/lib, /vendor/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:125)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at tgio.parselivequery.LiveQueryClient.getNewRequestId(LiveQueryClient.java:128)
at tgio.parselivequery.BaseQuery$Builder.<init>(BaseQuery.java:100)
at com.kungfu.tuga.utilities.the_wire.QueryExample.<init>(QueryExample.java:27)
at java.lang.Class.newInstance(Native Method)
at android.app.Instrumentation.newActivity(Instrumentation.java:1174)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2669)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Yes, I faced this issue too, however, if you set your gradle like this:
implementation ('com.parse:parse-android:1.16.3'){
exclude group: "com.squareup.okhttp3"
}
It will work without any trouble. (: