unit testing - Android java.lang.NoClassDefFoundError: R$string -


whenever run unit test, error when tries retrieve string value custom config.xml file.

background:

the project library apk project uses , references library apk project.

the error occurs when project tries initiate new object subclass of super class contained on referenced library apk project.

the issue explained more below

the specific line of code fails error static variable defined below:

  protected static final string android_config_id =  libraryapplication.getapplication().getstring(r.string.api_checkout_config_id_override); 

it fails following error:

java.lang.noclassdeffounderror: com/jon/commonlib/r$string 

commonlib referenced library apk if wondering.

here unit test

@runwith(robolectrictestrunner.class) @config(constants = buildconfig.class, manifest=config.none) public class testsearchshows {      @test     public void testsearchjsonfile(){         eventstesthelper testhelper = new eventstesthelper(runtimeenvironment.application);          try {             showslist showlist = testhelper.getshowlist(new searchevent());              if(showlist.getshows().size() < 0){                 assert.fail("show list empty");             }          } catch (ioexception e) {             e.printstacktrace();             assert.fail(e.tostring());         }     }   } 

the eventstesthelper sub class super class called networkhelper looks this:

public abstract class networkhelper<t, p, s> implements networkconstants {  protected static final string android_config_id = libraryapplication.getapplication().getstring(r.string.api_checkout_config_id_override);  //other stuff ....  } 

i use robolectric version 3.0 latest runing ,my unit tests.

if run code live , call , initiate sub class, works fine, no crashes

edit: here snippets of build gradle file below

apply plugin: 'android-sdk-manager' apply plugin: 'com.android.library' apply plugin: 'crashlytics'   buildscript {     repositories {         jcenter()         mavencentral()         maven { url 'http://download.crashlytics.com/maven' }         maven { url 'http://www.testfairy.com/maven' }      }     dependencies {         classpath 'com.android.tools.build:gradle:1.1.0'         classpath 'com.jakewharton.sdkmanager:gradle-plugin:0.12.+'         classpath 'com.crashlytics.tools.gradle:crashlytics-gradle:1.+'         classpath 'com.testfairy.plugins.gradle:testfairy:1.+'      } }  repositories {     mavencentral()     maven { url 'http://download.crashlytics.com/maven' }     maven { url "https://oss.sonatype.org/content/repositories/snapshots" }     flatdir {         dirs 'libs'     } }  android {     compilesdkversion 19     buildtoolsversion "22.0.1"     def package_namespace = "com.jonney.moduleapp"     defaultconfig {         minsdkversion 14         testapplicationid "com.jonney.moduleapp"         targetsdkversion 19         versioncode 1         versionname "1.0"     }  productflavors {         //testing {         //}         local {         }         mock {         }         qa {         }         //qa4 {         //}         production {         }     }      sourcesets {            local {             res.srcdir 'build-config/local/res'         }         testing {             res.srcdir 'build-config/testing/res'         }         mock {             res.srcdir 'build-config/mock/res'         }         qa {             res.srcdir 'build-config/qa/res'         }         qa4 {             res.srcdir 'build-config/qa4/res'         }         staging {             res.srcdir 'build-config/staging/res'             test.java.srcdirs += 'src/main/java'         }         production {             res.srcdir 'build-config/production/res'             test.java.srcdirs += 'src/main/java'             test.java.srcdirs += "build/generated/source/r/production"             test.java.srcdirs += "build/generated/source/buildconfig/production"         }      } }  dependencies {     compile filetree(dir: 'libs', include: ['*.jar'])     compile 'com.android.support:appcompat-v7:19.1.+'     compile 'com.google.code.gson:gson:2.3'     testcompile('org.robolectric:robolectric:3.0') {         exclude group: 'commons-logging', module: 'commons-logging'         exclude group: 'org.apache.httpcomponents', module: 'httpclient'     }     compile 'com.fasterxml.jackson:jackson-parent:2.5'     compile 'com.squareup:otto:1.3.6'     compile 'com.jakewharton:butterknife:6.1.0'     compile 'com.sothree.slidinguppanel:library:3.0.0'     compile 'com.crashlytics.android:crashlytics:1.+'     compile 'com.mcxiaoke.volley:library-aar:1.0.0'     compile "joda-time:joda-time:2.4"     testcompile('junit:junit:4.12') {         exclude module: 'hamcrest'         exclude module: 'hamcrest-core'     }     testcompile 'org.hamcrest:hamcrest-all:1.3'     compile 'com.sothree.slidinguppanel:library:3.0.0'     compile 'com.squareup:otto:1.3.6'     compile 'com.squareup.okhttp:okhttp:2.3.0'     testcompile 'org.apache.maven:maven-ant-tasks:2.1.3'      compile 'com.google.android.gms:play-services:7.0.0'      compile 'com.android.support:multidex:1.0.0'      compile(name: 'commonlib 1.0 1', ext: 'aar')     testcompile(name: 'commonlib-1.0 1', ext: 'aar') } 

edit: have tried manually create task copies r class each dependency.

    afterevaluate { project ->         android.libraryvariants.each { variant ->             // workaround missing r class aar dependencies             def copytaskname = "copy${variant.name.capitalize()}appcompat"             def copytasknametwo = "copy${variant.name.capitalize()}commonlib"             task(copytaskname, type:copy) {                 dependson "process${variant.name.capitalize()}resources"                 { "build/generated/source/r/${variant.dirname}/$package_namespace_path" }                 { "build/generated/source/r/${variant.dirname}/com/jon/commonlib" } //                { "src/test/java/android/support/v7/appcompat" }                 include 'r.java'                 filter { line -> line.contains("package ${package_namespace};") ? 'package android.support.v7.appcompat;' : line }                 outputs.uptodatewhen { false }             }             task(copytasknametwo, type:copy) {                 dependson "process${variant.name.capitalize()}resources"                 { "build/generated/source/r/${variant.dirname}/$package_namespace_path" }                 { "build/generated/source/r/${variant.dirname}/android/support/v7/appcompat" } //                { "src/test/java/android/support/v7/appcompat" }                 include 'r.java'                 filter { line -> line.contains("package ${package_namespace};") ? 'package com.jon.commonlib;' : line }                 outputs.uptodatewhen { false }             }             system.out.println("adding ${copytaskname} build/generated/source/r/${variant.dirname}/$package_namespace_path ")             println("basename =  ${variant.basename}")             println("directory name =  ${variant.dirname}")             tasks.getbyname("compile${variant.name.capitalize()}unittestjava") dependson copytaskname         }     } 

kind regards

jonnney

the project library apk project uses , references library apk project.

for type of projects exist known issue https://github.com/robolectric/robolectric/issues/1796 can workaround it.

the base issue android/gradle behaviour library projects different compared application projects. ignores generate r classes aar dependencies.

to workaround can provide own r class contains dependencies r values. here example appcompat dependency

afterevaluate { project ->   android.libraryvariants.each { variant ->     // 1 line each aar dependency     tasks.getbyname("assemble${variant.name.capitalize()}").dependson copyappcompat   } }  // copy each aar dependency , adjust needs task copyappcompat(type: copy) {    // replace base package yours (all after /r/debug/) contains r.class   'build/generated/source/r/debug/com/example/core'.replace("/", file.separator)    // replace library packages yours (all after /test/java/) aar dependency base package   'src/test/java/android/support/v7/appcompat'.replace("/", file.separator)    // replace package declaration or compile errors   filter { line -> line.contains('package com.example.core;') ? 'package android.support.v7.appcompat;' : line }   include 'r.java' } 

an example project setup can found @ https://github.com/nenick/androidstudioandrobolectric/tree/library-with-aar


Comments

Popular posts from this blog

html - Firefox flex bug applied to buttons? -

html - Missing border-right in select on Firefox -

c# - two queries in same method -