Louis B Louis B - 5 months ago 41
Java Question

RxJava noClassDefFoundError: rx.plugins.RxJavaPlugins on API 16

I am developing an Android application using RxJava and Retofit. When I test my code on API 23 I get no errors however when I test in API 15, my RxJava doesnt appear to work properly and my app crashes with error:

FATAL EXCEPTION: main
java.lang.ExceptionInInitializerError
at $Proxy1.createToken(Native Method)
at com.loginsignup.presenter.LoginPresenterImpl.tryToLogin(LoginPresenterImpl.java:39)
at com.loginsignup.view.LoginActivity.tryToLogin(LoginActivity.java:197)
at com.loginsignup.view.LoginActivity.onClick(LoginActivity.java:180)
at android.view.View.performClick(View.java:4084)
at android.view.View$PerformClick.run(View.java:16966)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NoClassDefFoundError: rx.plugins.RxJavaPlugins
at rx.Observable.<clinit>(Observable.java:63)
at $Proxy1.createToken(Native Method)
at com.gooroo.gooroo.loginsignup.presenter.LoginPresenterImpl.tryToLogin(LoginPresenterImpl.java:39)
at com.gooroo.gooroo.loginsignup.view.LoginActivity.tryToLogin(LoginActivity.java:197)
at com.gooroo.gooroo.loginsignup.view.LoginActivity.onClick(LoginActivity.java:180)
at android.view.View.performClick(View.java:4084)
at android.view.View$PerformClick.run(View.java:16966)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)


Here is my gradle build:

apply plugin: 'com.android.application'

android {
compileSdkVersion 23
buildToolsVersion "23.0.2"

defaultConfig {
applicationId "com.example.ex"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "0.1 alpha"
multiDexEnabled true
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}

dexOptions {
javaMaxHeapSize "4g"
}
}

dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.4-beta2'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta2'
testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta2'
compile files('libs/sinch-android-rtc-3.9.5.jar')
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:design:23.4.0'
compile 'com.android.support:support-v4:23.4.0'
compile 'com.android.support:cardview-v7:23.4.0'
compile 'com.google.android.gms:play-services-maps:8.4.0'
compile 'com.google.android.gms:play-services-location:8.4.0'
compile 'com.google.code.gson:gson:2.6.2'
compile 'com.google.android.gms:play-services-analytics:8.4.0'
compile 'com.squareup.picasso:picasso:2.5.2'
compile 'com.squareup.okhttp3:okhttp-urlconnection:3.2.0'
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
compile 'com.squareup.retrofit2:retrofit:2.0.0'
compile 'com.squareup.retrofit2:converter-gson:2.0.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0'
compile 'com.github.orhanobut:logger:1.12'
compile 'com.viewpagerindicator:library:2.4.1@aar'
compile 'io.reactivex:rxandroid:1.2.0'
compile 'io.reactivex:rxjava:1.1.5'
compile 'com.facebook.android:facebook-android-sdk:4.+'
compile 'com.stripe:stripe-android:+'
compile 'com.google.android.gms:play-services-gcm:8.4.0'
compile 'com.timehop.stickyheadersrecyclerview:library:0.4.3@aar'
compile 'com.amazonaws:aws-android-sdk-core:2.+'
compile 'com.amazonaws:aws-android-sdk-s3:2.+'
compile 'com.google.android.gms:play-services-wallet:8.4.0'
compile 'com.android.support:multidex:1.0.0'
}

apply plugin: 'com.google.gms.google-services'


Any idea why there is no issue on API 23, but when I run it on API 16 it crashes when I try to login which uses RxJava?

Answer

The problem here is may be you have not initialized MultiDex Option

Multidex support for Android 5.0 and higher

Android 5.0 and higher uses a runtime called ART which natively supports loading multiple dex files from application APK files. ART performs pre-compilation at application install time which scans for classes(..N).dex files and compiles them into a single .oat file for execution by the Android device. For more information on the Android 5.0 runtime, see Introducing ART. This is the reason why your app is working fine on API level 21.

Multidex support prior to Android 5.0

Versions of the platform prior to Android 5.0 use the Dalvik runtime for executing app code. By default, Dalvik limits apps to a single classes.dex bytecode file per APK. In order to get around this limitation, you can use the multidex support library, which becomes part of the primary DEX file of your app and then manages access to the additional DEX files and the code they contain.

So, Firstly making sure you have imported correct dependency, which It seems you did it.

dependencies {
  compile 'com.android.support:multidex:1.0.0'
}

In your manifest add the MultiDexApplication class from the multidex support library to the application element.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.multidex.myapplication">
    <application
        ...
        // This will solved the problem
        android:name="YourAppName">
        ...
    </application>
</manifest>

This is how i solved my problem, even there is closed Git issue regarding the same.

EDIT

public class YouAppName extends MultiDexApplication {
    ..  ..
}

I hope it will help you out.

Comments