8

I am using Android Studio. I am writing an Android Library called detector. It runs perfectly in the project from which it was created.

compile project(':detector')

I want to import the AAR file it generates into another project. I do so:

File > New > New Module > Import .JAR/.AAR Package

I then add the same line in the new projects app build.gradle:

compile project(':detector')

After cleaning and building, I run the app and get this error:

11-18 06:32:14.151 21283-21283/testing.com.test D/ResourcesManager: For user 0 new overlays fetched Null
11-18 06:32:14.161 21283-21283/testing.com.test W/System: ClassLoader referenced unknown path: /data/app/testing.com.test-1/lib/arm
11-18 06:32:15.131 21283-21283/testing.com.test W/System: ClassLoader referenced unknown path: /data/app/testing.com.test-1/lib/arm
11-18 06:32:15.131 21283-21283/testing.com.test D/ContextRelationManager: ContextRelationManager() : FEATURE_ENABLED=true
11-18 06:32:15.131 21283-21283/testing.com.test D/RelationGraph: garbageCollect()
11-18 06:32:15.301 21283-21283/testing.com.test D/RelationGraph: garbageCollect()
11-18 06:32:15.501 21283-21283/testing.com.test W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
11-18 06:32:15.621 21283-21283/testing.com.test I/art: Rejecting re-init on previously-failed class java.lang.Class<detector.Manager>
11-18 06:32:15.621 21283-21283/testing.com.test I/art: Rejecting re-init on previously-failed class java.lang.Class<detector.Manager>
11-18 06:32:15.621 21283-21283/testing.com.test I/art: Rejecting re-init on previously-failed class java.lang.Class<detector.Manager>
11-18 06:32:15.621 21283-21283/testing.com.test I/art: Rejecting re-init on previously-failed class java.lang.Class<detector.Manager>
11-18 06:32:15.621 21283-21283/testing.com.test I/art: Rejecting re-init on previously-failed class java.lang.Class<detector.Manager>
11-18 06:32:15.621 21283-21283/testing.com.test I/art: Rejecting re-init on previously-failed class java.lang.Class<detector.Manager>
11-18 06:32:15.621 21283-21283/testing.com.test I/art: Rejecting re-init on previously-failed class java.lang.Class<detector.Manager>
11-18 06:32:15.621 21283-21283/testing.com.test I/art: Rejecting re-init on previously-failed class java.lang.Class<detector.Manager>
11-18 06:32:15.631 21283-21283/testing.com.test I/art: Rejecting re-init on previously-failed class java.lang.Class<detector.Manager>
11-18 06:32:15.631 21283-21283/testing.com.test I/art: Rejecting re-init on previously-failed class java.lang.Class<detector.Manager>
11-18 06:32:15.631 21283-21283/testing.com.test I/art: Rejecting re-init on previously-failed class java.lang.Class<detector.Manager>
11-18 06:32:15.631 21283-21283/testing.com.test I/art: Rejecting re-init on previously-failed class java.lang.Class<detector.Manager>
11-18 06:32:15.631 21283-21283/testing.com.test I/art: Rejecting re-init on previously-failed class java.lang.Class<detector.Manager>
11-18 06:32:15.631 21283-21283/testing.com.test I/art: Rejecting re-init on previously-failed class java.lang.Class<detector.Manager>
11-18 06:32:15.631 21283-21283/testing.com.test I/art: Rejecting re-init on previously-failed class java.lang.Class<detector.Manager>
11-18 06:32:15.631 21283-21283/testing.com.test I/art: Rejecting re-init on previously-failed class java.lang.Class<detector.Manager>
11-18 06:32:15.631 21283-21283/testing.com.test I/art: Rejecting re-init on previously-failed class java.lang.Class<detector.Manager>
11-18 06:32:15.631 21283-21283/testing.com.test I/art: Rejecting re-init on previously-failed class java.lang.Class<detector.Manager>
11-18 06:32:15.631 21283-21283/testing.com.test D/AndroidRuntime: Shutting down VM
11-18 06:32:15.631 21283-21283/testing.com.test E/AndroidRuntime: FATAL EXCEPTION: main
                                                                         Process: testing.com.test, PID: 21283
                                                                         java.lang.NoClassDefFoundError: detector.Manager
                                                                             at detector.Detector.<clinit>(Detector.java:39)
                                                                             at testing.com.test.MainActivity.onCreate(MainActivity.java:17)
                                                                             at android.app.Activity.performCreate(Activity.java:6904)
                                                                             at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1136)
                                                                             at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3266)
                                                                             at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3415)
                                                                             at android.app.ActivityThread.access$1100(ActivityThread.java:229)
                                                                             at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1821)
                                                                             at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                             at android.os.Looper.loop(Looper.java:148)
                                                                             at android.app.ActivityThread.main(ActivityThread.java:7325)
                                                                             at java.lang.reflect.Method.invoke(Native Method)
                                                                             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
                                                                             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

I unzip the AAR and decompile the Classes.jar file to find the Manager file does exist:

Manager.class
Manager$3.class
Manager$2.class
Manager$1.class

Here is the libraries build.gradle

apply plugin: 'com.android.library'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        minSdkVersion 10
        targetSdkVersion 23
        versionCode 1
        versionName '1'
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile ('org.altbeacon:android-beacon-library:2.8.1')
    compile ('com.google.android.gms:play-services-ads:9.6.1')
    compile 'com.android.support:appcompat-v7:23.4.0'
}

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

Additionally, I am able to deploy the library to jCenter and am able to successfully run the library in other projects when linking to the jCenter installation. It is just the direct AAR import that is causing this issue.

Please advise on building an Android Library AAR and importing it into another Android Project.

======UPDATE======

I have found due to help from @bwt that the issue is solved if I include the libraries dependencies inside the apps build.gradle that is bootstrapping the AAR. How can I ensure that the dependencies ( which are google-play and altbeacon ) are included inside the AAR? Setting them as transitive dependencies before building the AAR has not helped.

John Foley
  • 4,373
  • 3
  • 21
  • 23
  • Is your code directly referencing `detector.Manager`? IOW, is this something that perhaps ProGuard is stripping out in a `release` build? – CommonsWare Nov 08 '16 at 17:44
  • My code is directly referencing it, yes. I will check if it is being stripped. – John Foley Nov 08 '16 at 17:46
  • These classes exist in the extracted classes.jar: Manager.class Manager$3.class Manager$2.class Manager$1.class – John Foley Nov 08 '16 at 17:50
  • maybe this will help you [this question](http://stackoverflow.com/q/37360126/6747577) – Malik Abu Qaoud Nov 17 '16 at 21:59
  • @JohnFoley can you please share your aar build.gradle script? – Avi Levin Nov 17 '16 at 22:07
  • @AviLevinshtein I don't have a specific build.gradle script. The libraries build.gradle is in the question. I am using the detector-release.aar/detector-debug.aar found in the "library_root > build > outputs > aar" directory that gets produced after the library is built – John Foley Nov 17 '16 at 22:13
  • @AviLevinshtein do I need a specific aar-build section in my build.gradle file? – John Foley Nov 17 '16 at 22:34
  • @John Foley - yes for every aar that you import a new gradle file has to generated. will write on the answer, hope it will solve your case. – Avi Levin Nov 18 '16 at 07:38
  • Forgive me if I have missed anything. So, you are able to compile your project after importing the .aar and getting stack trace while running in the device/emulator ? If yes, what's the platform and version? You might be exceeding total methods limit if you are working on $(api < 21). – Burak Day Nov 19 '16 at 10:22
  • Above issue occurs especially when you have protocol buffers in your .aar – Burak Day Nov 19 '16 at 10:29
  • Did you solved this? Can you post an answer of the solution? – eri0o Jan 19 '21 at 13:58

5 Answers5

3

I am not sure the problem is that the class are not imported (otherwise you could not compile) but just in case what happen if you import the local aar without an additional module ?

  1. Put the aar in a directory inside the module where you want to use it (e.g. aarlibs in the app module)

  2. Declare this directory as a repository (in the app's build.gradle) :

    repositories{
        flatDir{
            dirs 'aarlibs'
        }
    }
    
    android {
    ...
    
  3. Reference it as a dependency (also in the app's build.gradle) :

    dependencies {
        compile(name:'aar_file_name', ext:'aar')
    ...
    
bwt
  • 17,292
  • 1
  • 42
  • 60
  • Thanks for your response. I have tried this and am still getting the same error. I have pasted the verbose output of the error condition in the question to add more context. – John Foley Nov 18 '16 at 11:39
  • It seems that the `Detector` class is found, but not the `Manager` class. Is it present in the apk ? ( from Android Studio : Build > Analyse APK, look in `classes.dex` ) – bwt Nov 18 '16 at 12:17
  • I am having trouble analyzing the APK. That option does not exist in my build menu and I have tried double clicking on the generated APK in the build > outputs > apk directory but it does not open the APK Analyzer. I am using a mac – John Foley Nov 18 '16 at 14:29
  • I think the apk analyzer (described [here](https://developer.android.com/studio/build/apk-analyzer.html)) has been added in Android Studio 2.2. You can also use [ClassyShark](http://classyshark.com/) – bwt Nov 18 '16 at 15:01
  • Updating to 2.2 provided the analyzer, thanks. Also, I was able to find the all the relevant classes including the Manager in the classes.dex file – John Foley Nov 18 '16 at 15:11
  • So the class is actually there but ART can not find it. Can you test with an older device ? maybe Dalvik shows a different error – bwt Nov 18 '16 at 16:01
  • Just thought of something else : Does it change something if you add the compile dependencies (`org.altbeacon`, `com.google.android.gms`, ...) from the library to the the app itself ? – bwt Nov 18 '16 at 17:01
  • Yes! If I add the library dependencies to the apps build.gradle it solves the issue! Do I need to make the dependencies transitive or do something else to ensure they exist in the built AAR? – John Foley Nov 18 '16 at 17:09
  • I had the same problem (not the same symptom but the same cause). Making the dependencies transitive didn't help, I ended up adding the depencies in the application – bwt Nov 18 '16 at 17:30
2

The aar file does not have the transitive dependencies and doesn't have a pom file that describes the dependencies used by the library.

means, if you are importing a aar file then you have to specify the dependencies also in your project.

You should use a maven repository (you have to publish the library in a private or public maven repo).

2

The way of importing .AAR/JAR in Android Studio v-4.2 above has changed, so use this https://developer.android.com/studio/projects/android-library#psd-add-aar-jar-dependency

Denny
  • 991
  • 12
  • 20
1
  1. First, grab all the required .AAR files from the libraries folder of the sdk.
  2. Create new modules for each of these libraries. Using Android Studio's GUI, this can be done via File -> New -> New Module. Select Import .JAR/.AAR Package. Locate one of the .AARs and import it.
  3. Then add this new module as a dependency to your main app via File > Project Structure > Modules (on the left side's section list) > YOUR APP's MODULE NAME > Dependencies (on the right side's tab list) -> '+' -> Module Dependency.

Using the steps above will cause Android Studio to generate new modules and edit your .gradle files automatically. Alternatively, you can directly include the .AARs in your application's module by editing that specific module's build.gradle file.

Refrence: https://developers.google.com/vr/android/get-started

Misagh
  • 3,403
  • 1
  • 20
  • 17
0

Let say you got 2 projects:

  1. AAR project - this is the one where you build and create the aar file.
  2. Work project - this is where you run a code that needs the generated aar file from (1).

In your work project (2) you will have to add a new module for your aar file (1). The process for that is as follows, press the right mouse key on one of your existing modules and select select "open module settings" then press the "+" sign to add a new module choose import jar/aar and select the relevant file that was generated in section 1.

You will notice that a new gradle file for you new module was generated with the following code:

configurations.maybeCreate("default")
artifacts.add("default", file('name_of_you_aar_file.aar'))

After the module was created you'll have to link the new module to your app module using what you already wrote in the build.gradle that relates to your module: compile project(':name_of_your_module')

Let me know if it's working for you.

Avi Levin
  • 1,868
  • 23
  • 32
  • I have done this and am still getting the error. Here is the gradle: configurations.maybeCreate("default") artifacts.add("default", file('detector-debug.aar')) – John Foley Nov 18 '16 at 11:23