Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android NoClassDefFoundError for library's class inside a dependency

Tags:

android

gradle

I created an Android library named "core" that use the Logger library (https://github.com/orhanobut/logger).

Here its build.gradle:

apply plugin: 'com.android.library'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.1"

    defaultConfig {
        minSdkVersion 16
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

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

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])

    compile 'com.orhanobut:logger:1.15'

    compile 'com.android.support:appcompat-v7:25.0.1'

    testCompile 'junit:junit:4.12'
}

Then I build a .aar of core library.

I add this library as a dependency into my application, by putting the .aarcore files in the libs folder.

That's the build.gradle of my application :

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.1"
    defaultConfig {
        applicationId "com.package.test"
        minSdkVersion 16
        targetSdkVersion 25
        multiDexEnabled true
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner     "android.support.test.runner.AndroidJUnitRunner"

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

    repositories {
    mavenCentral()
    jcenter()
    flatDir {
        dirs 'libs'
    }
}

dependencies {

    compile 'com.mypackage:core:1.0@aar'

    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })

    testCompile 'junit:junit:4.12'

    compile 'com.android.support:appcompat-v7:25.0.1'
    compile 'com.android.support:multidex:1.0.1'

}

As you can see I have multidex activated.

It compile just fine but at runtime, at the first call to Logger I get an exception:

stack=java.lang.NoClassDefFoundError: Failed resolution of: Lcom/orhanobut/logger/Logger;

Even if I set transitive = true

compile (com.mypackage:core:1.0@aar) {
        transitive=true
}

it doesn't work.

Thank you !

like image 837
Sophian Laroy Avatar asked Nov 09 '22 03:11

Sophian Laroy


1 Answers

I had to do a couple of things in concert to get it to work.

1) In your library project

Add the following to your project-level gradle file:

buildscript {
    dependencies {
        classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
    }
}

Be sure to use the right version of the plugin for your gradle version, check here.

Add the following to your module-level gradle file:

apply plugin: 'com.github.dcendents.android-maven'
group='com.github.YourPackage'// Doesn't have to be github, just an example

Also in this file, make sure your dependencies (the ones you want to be transitive) use api instead of implementation if you are using Gradle 3.4+. If you are using a version of Gradle <3.4, compile is the way to go. Example:

dependencies {
    api 'com.google.android.gms:play-services-location:15.0.1'
}

2) In your app project (which uses the library)

Add the following to your module-level gradle file:

dependencies {
    implementation('com.github.YourPackage:yourRepo:version@aar') {
        transitive=true
    }
}

Add the following to you project-level gradle file (but this will depend on where your library is served from, for me it's jitpack):

allprojects {
    repositories {
        ...
        maven {
            url 'https://jitpack.io'
            credentials { username 'yourAuthKey' }// Only for private repositories
        }
    }
}

Note: You shouldn't add the auth key as a string in build.gradle, put it in a property in your gradle.properties file.

Note 2: JitPack allows you to use for example development-SNAPSHOT as a version number for a gradle dependency. Android Studio caches these dependencies and will not re-download it when you push to your development branch. To overcome this, use commit hashes as version numbers during development or clear (delete) the cache files, located on Windows at ~/.gradle/caches/modules-2/metadata-x.xx/descriptors/com.github.YourPackage/yourRepo. (Needles to say, I learned this the hard way).

like image 126
Kenneth Saey Avatar answered Nov 15 '22 06:11

Kenneth Saey