Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: ClassNotFoundException when using library project that has gradle dependencies

I have a custom view library that compiles and runs correctly on it's own (through another activity created just for testing purposes inside the library project). However when I build the library, and then import the aar into another project (open module settings->new module->existing aar..) I'm getting a runtime ClassNotFoundException - the exception is on the only gradle dependency that the library is using. Why is this happening?

Library gradle file:

    apply plugin: 'com.android.library'

    android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
dependencies {
    compile 'com.googlecode.libphonenumber:libphonenumber:7.2.1'
}

The error that I'm getting:

Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.i18n.phonenumbers.PhoneNumberUtil" on path: DexPathList[[zip file..
like image 893
Jon Avatar asked Jan 26 '16 10:01

Jon


1 Answers

An aar dependency is not like a maven/ivy dependency in that there is no transitive dependency bundled with it in a pom or xml file. When you add a aar dependency, gradle has no way to know what transitive dependencies to fetch.

A common practice in the android world seems to be, to add transitive dependencies explicitly to your app, that uses the aar. This can get cumbersome and sort of defeats the point of a dependency management system.

There are a couple of workarounds:

1. android-maven plugin

There is a 3rd party gradle plugin that allows you to publish the aar file to a local maven repo, along with a valid pom file.

2. maven-publish plugin

You an use the standard maven-publish plugin to publish the aar to a maven repo, but you have to assemble pom dependencies yourself. For example:

publications {
    maven(MavenPublication) {
        groupId 'com.example' //You can either define these here or get them from project conf elsewhere
        artifactId 'example'
        version '0.0.1-SNAPSHOT'
        artifact "$buildDir/outputs/aar/app-release.aar" //aar artifact you want to publish

        //generate pom nodes for dependencies
        pom.withXml {
            def dependenciesNode = asNode().appendNode('dependencies')
            configurations.compile.allDependencies.each { dependency ->
                def dependencyNode = dependenciesNode.appendNode('dependency')
                dependencyNode.appendNode('groupId', dependency.group)
                dependencyNode.appendNode('artifactId', dependency.name)
                dependencyNode.appendNode('version', dependency.version)
            }
        }
    }
}

In both of these cases, once aar+pom are available in a maven repo, you can use it in your app like this:

compile ('com.example:example:0.0.1-SNAPSHOT@aar'){transitive=true}

(I'm not entirely sure how transitives work if you add a dependency as compile project(:mylib). I will update this answer for this case shortly)

like image 143
RaGe Avatar answered Oct 21 '22 05:10

RaGe