Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Activity Class cannot be found in AAR file java.lang.NoClassDefFoundError

I have created an android library, it contains an Activity Class that uses to open camera intent, the library works perfect excepts for the part that invokes the Activity to appear over the screen and the app crashes throwing following errors

Suppressed: java.lang.ClassNotFoundException: com.me.scanner.ScannerViewActivity
            at java.lang.Class.classForName(Native Method)
            at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
            at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
                    ... 14 more
         Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available

Following is my build.gradle file of other project that will use this library

repositories {
    flatDir {
        dirs 'libs'
    }
}
dependencies {
    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'
    })
    compile 'com.android.support:appcompat-v7:25.3.0'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    compile 'com.me.app:gpio_lib@aar'
    compile ('com.me.app:scanner@aar'){ transitive = true; }
    testCompile 'junit:junit:4.12'
}

Please Note:

  • This library works perfectly as module project,

    compile project(':scannercontrol')
    

    but not when using it as aar in the project

  • I have tried with and without { transitive = true; }, no change

  • I have rename my aar file to scanner.aar
  • I have taken the aar file form /[library-project]/build/outputs/aar/scanner-release.aar

Update1 - 2017-09-14

The activity ScannerViewActivity is part of my library, this is how it is been called from one of the library class

Intent scannerView = new Intent();
scannerView.putExtra(MESSAGE_RECEIVER, new MessageReceiver());
scannerView.setClass(context, ScannerViewActivity.class);
scannerView.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(scannerView);

this context is the instance of android.app.Application and not of any Activity

Update2 - 2017-09-14

Fortunately after roaming 2 days all over google I come across the answer of question Class not found in aar. I have added the dependencies of the library to the project and able to run it with aar but this is not the solution of my issue,

Following is the flow and issue I'm currently facing

  • I'm developing a sandbox version of a library that communicates with a specific barcode scanner hardware, since the developer doesn't necessarily have the hardware they will use the sandbox version of the library that will allow developer to use their device camera as a barcode scanner,

  • We want the developer to extract the AAR files scanner.aar and scanner-sandbox.aar from provided SDK and use either of them

  • We don't want the developer to add extra dependency to their .gradle file if they want to run the sandbox version of the library,

  • Following is the dependency that is being used to simulate device camera as a barcode scanner

    compile 'me.dm7.barcodescanner:zxing:1.9.8'
    

The updated question is

What is the possible way to distribute an aar file without publishing them to any repository like maven repository and all dependencies of the library installed when developer syncs the .gradle file

like image 618
riksof-zeeshan Avatar asked Sep 12 '17 08:09

riksof-zeeshan


4 Answers

zeeshan

I have faced same issue i did lot of research & i fixed hopefully it helps you

Creating .aar file for a project:

  1. For a library module, .aar file is automatically created by Android Studio. For a project with the any resource file or with the libraries, .aar file can be generated as mentioned in next steps.
  2. Check the plugin. It should be in as follows, change to library if it is in application, apply plugin: 'com.android.library'
  3. Open the open right border gradle bar and go to “your project”->Tasks->build and then double click on the assembleRelease. On Building the project, You will find the two .aar files(app-debug.aar and app-release.aar) inside app/build/outputs/aar/ directory. Using .aar file in your project:
  4. Get the “app-release.aar” file and paste it in the libs folder of your project. If libs folder is not present, create a directory named “libs” inside app directory.

  5. Add the following to the app gradle file, repositories { flatDir { dirs 'libs' } } dependencies { compile(name:'app-release', ext:'aar') }

  6. On sync, your project is ready to use the library files. Note : .aar gradle dependencies has to be added manually in your project app gradle Example:below

Assumption of errors:

System.err: java.lang.NoClassDefFoundError:

Solution:





.aar gradle dependencies has to be added manually in your project app gradle

like image 70
madhu527 Avatar answered Nov 20 '22 01:11

madhu527


The answer for your "Update2 - 2017-09-14" - can simply build a fat aar file. which will contain all the dependencies, one thing which you may have to handle is conflict in dependencies sometime may create a issue. also the size of the fat aar may be huge. so give try.

like image 30
roronoa_zoro Avatar answered Nov 19 '22 23:11

roronoa_zoro


There are 3 ways to distribute your library:

  1. Creating a local maven library then distribute the generated aar.
    You can create a local aar by using Gradle Android Maven plugin. How to make it:

    a. Add the plugin classpath to root build.gradle:

    buildscript {
      repositories {
        jcenter()
        mavenCentral()
      }
      dependencies {
        classpath 'com.android.tools.build:gradle:2.2.3'
        classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
    
      }
    }
    
    allprojects {
      repositories {
        jcenter()
      }
    }
    

    b. Set the maven plugin, and add group and version name to library build.gradle:

    apply plugin: 'com.android.library'
    apply plugin: 'com.github.dcendents.android-maven'
    
    group = 'com.your.packagename'
    version = '1.0.0'
    ext.versionCode = 1000
    
    android {
      compileSdkVersion 25
      buildToolsVersion "25.0.3"
    
      defaultConfig {
        minSdkVersion 9
        targetSdkVersion 25
        versionCode versionCode
        versionName version
      }
      buildTypes {
        ...
      }
    
    }
    
    dependencies {
      ...
    }
    

    c. Set the artifactId is set in settings.gradle:

    rootProject.name = 'yourlibraryname'
    

    d. Build and install the library to your local maven.
    You can run ./gradlew install on project folder or use

    Gradle -> YourLibrary -> Other -> Install from Android Studio (on the right side of Android Studio)

    e. Use the installed library directly to your project.
    You can use the library by adding mavenLocal() to your root build.gradle

    allprojects {
      repositories {
        jcenter()
        mavenLocal() // for local maven.
      }
    }
    

    Then add the dependency to the project:

    compile 'com.your.packagename:modulename:1.0.0'
    

    Or you can copy the generated .aar from local maven path. In Linux, you can get it from /your/userpath/.m2/repository/ or ~/.m2/repository/

  2. Use the same technique in number 1, but make the local maven path for each developer computer pointing to the ~/.m2/repository/ central.

  3. Use a private maven repository. You can use JFrog Artifactory oss or Nexus Repository OSS

like image 3
ישו אוהב אותך Avatar answered Nov 19 '22 23:11

ישו אוהב אותך


The cause of the problem is that the class ScannerViewActivity is called inside one of your AAR as a dependency like:

apply plugin: 'com.android.library'
android{...}
dependencies {
    compile 'com.me.scanner:otherscanner@aar' //library which contains ScannerViewActivity
}

but when you use a aar (transitive won't add this aar dependencies !), you have to add the other dependency such as:

dependencies {
...
compile ('com.me.app:scanner@aar')// remove{ transitive = true; }
compile ('com.me.scanner:otherscanner@aar')
...
}
like image 2
xiaomi Avatar answered Nov 20 '22 00:11

xiaomi