It seems that also the latest android SDK tools still don't properly support testing of applications that contain linked library projects.
I have a project with the following setup:
TestLib (android library project) <- TestMain (android project) <- TestMainTest (android unit test project)
I created all those projects in eclipse and then used android update (test-/lib-)project ...
to generate the build.xml
et. al.
The problem starts as soon as you have a class in TestMain (InheritAddition.java
in my example) that inherits from a class in TestLib (Addition.java
) and you want to reference this class in the unit test (InheritAdditionTest.java
).
TestLib
public class Addition {
public int add2(int o1, int o2) {
return o1 + o2;
}
}
TestMain
public class InheritAddition extends Addition {
public int sub(int p1, int p2) {
return p1 - p2;
}
}
TestMainTest
public class InheritAdditionTest extends AndroidTestCase {
public void testSub() {
Assert.assertEquals(2, new InheritAddition().sub(3, 1));
}
}
When building on the command line the result is the following:
W/ClassPathPackageInfoSource(14871): Caused by: java.lang.NoClassDefFoundError: org/test/main/InheritAddition W/ClassPathPackageInfoSource(14871): ... 26 more W/ClassPathPackageInfoSource(14871): Caused by: java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation W/ClassPathPackageInfoSource(14871): at dalvik.system.DexFile.defineClass(Native Method) W/ClassPathPackageInfoSource(14871): at dalvik.system.DexFile.loadClassBinaryName(DexFile.java:195) W/ClassPathPackageInfoSource(14871): at dalvik.system.DexPathList.findClass(DexPathList.java:315) W/ClassPathPackageInfoSource(14871): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:58) W/ClassPathPackageInfoSource(14871): at java.lang.ClassLoader.loadClass(ClassLoader.java:501) W/ClassPathPackageInfoSource(14871): at java.lang.ClassLoader.loadClass(ClassLoader.java:461) W/ClassPathPackageInfoSource(14871): ... 26 more W/dalvikvm(14871): Class resolved by unexpected DEX: Lorg/test/main/InheritAddition;(0x41356250):0x13772e0 ref [Lorg/test/lib/Addition;] Lorg/test/lib/Addition;(0x41356250):0x13ba910
I found some workaround that works for eclipse:
That does the trick, but I am looking for a solution that works with ANT (more precisely I am looking for a solution that works on both at the same time).
The documented approach (by changing build.xml to include jars from the main project into the class path) is not applicable here as the sample project doesn't use any library jars (also I believe that this particular problem is now fixed with SDK tools r16).
I guess the brute force way of solving that is to try and somehow remove the dependencies of TestMainTest
to TestLib
(by modifying project.properties
) and instead manage to hack the build script to put those built jars into the class path (so replace the -compile
target with something that modifies the class path for javac
). Since I have a long history of trying to keep up with android SDK toolchain changes, this is not really my favorite option as it is a) rather complicated and b) requires constant modification of the build.xml
whenever the toolchain changes (which is quite frequently).
So I am looking for ideas of how to get such a setup working without using the sledge hammer. Maybe I am missing something totally obvious but for me this use case is fairly standard and I have a hard time understanding why this isn't supported out of the box.