My favorites | Sign in
Project Home Issues
New issue   Search
for
  Advanced search   Search tips   Subscriptions
Issue 21720: Tools r15 has broken a whole bunch of things... :/
37 people starred this issue and may be notified of changes. Back to list
Status:  Released
Owner:  x...@android.com
Closed:  Apr 2012


Sign in to add a comment
 
Reported by jason.po...@gmail.com, Nov 10, 2011
I have recently updated my ADT environment and have spent the last 3 full days trying to recover from this.  The new features introduced into the ANT build system, and the way library projects are dealt with in Eclipse seems to be a great improvement, but also seems to break everything.. at least for me.

I will try to explain my situation:

I have a library project, a sample project which references the library, and a test project which tests the sample app.  This arrangement was necessary because there was (is?) no way to run JUnit tests against a library project.

The new way that library projects are dealt with in Eclipse is a great improvement over the previous implementation (i.e. not having foreign source code in projects referencing the library) however it now seems that it seems impossible to use the ANT build system to run tests.

My test project in eclipse depends on the sample project (it has to in order to find the Activities etc to be tested).
The test project ALSO depends on the library project.
My sample project depends on the library project.

If I try to build the test project, the build consistently fails with:

       [dx] UNEXPECTED TOP-LEVEL EXCEPTION:
       [dx] java.lang.IllegalArgumentException: already added: Lcom/...

The duplicate class is always a class from my library project.  

This makes some sense because both the test project and the sample project depend on the library project, so maybe it's being added twice?  In an attempt to resolve this, I tried "exporting" the Library project in the sample project build path, but eclipse cannot compile the test project if it does not have a reference to the library project AND the sample project.

I then realized that if I ran "ant clean" on ALL 3 projects, the problem goes away, which tells me that somehow the previous jar file created in the initial compile is being appended to?  Of course as soon as I go back into eclipse everything is now broken and requires a full re-build, which then causes this problem...

If you run a full "clean" in eclipse, it will consistently result in DEX failures complaining about duplicate classes.  The classes.jar that is produced for the library project after an Eclipse "clean" contains a bunch of duplicates.  I have to manually delete this to overcome this error in the ANT build.  Also after this, eclipse often loses it's project state.  After a full clean/rebuild, "some" projects are no longer accessible from the Package Explorer.  The project appears, but has no contents.  Not sure if this is an ADT issue or an Eclipse one but the problem did not manifest in previous ADT versions.  

Restarting eclipse, or closing/opening the project seems to be the only work-around.

Also...

We use EMMA for coverage, and in the previous versions we needed to re-write most of the ANT build script to get EMMA to work (refer to http://blog.appmakr.com/android-code-coverage/).  
The new version does not seem to have overcome this, and it appears we will need to re-write the new ANT scripts as well.  
Also this statement in the build script is false "WARNING: Code Coverage is currently only supported on the emulator and rooted devices."  
I'm not sure what this is saying, but we have been running EMMA code coverage successfully on a non-rooted device for 6 months.

Finally...

It would be awesome if you provided a simple way for developers to extend the ANT build system without needing to copy/paste the contents of the build script provided in ADT.  
For example we make extensive use of a mocking framework which requires a compiler argument to generate mocks on compilation (-ARegenerateFrameworkMocks=true).  
Because the call to javac in the build script is buried in the -compile target, with no provision for extension, we have to copy this entire target from the default script into our own.   
In fact because of the problems with the EMMA implementation we have needed to copy and change almost the entire build script.


Going to try rolling back ADT...

P.S.

update since drafing this...

I managed to get consistent building working, but tests are unable to run:

     [exec] android.test.suitebuilder.TestSuiteBuilder$FailedToCreateTests:
     [exec] Error in testSuiteConstructionFailed:
     [exec] java.lang.RuntimeException: Exception during suite construction
     [exec] 	at android.test.suitebuilder.TestSuiteBuilder$FailedToCreateTests.testSuiteConstructionFailed(TestSuiteBuilder.java:239)
     [exec] 	at java.lang.reflect.Method.invokeNative(Native Method)
     [exec] 	at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
     [exec] 	at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)
     [exec] 	at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:529)
     [exec] 	at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1584)
     [exec] Caused by: java.lang.TypeNotPresentException: Type com.blah.SomeClass not present


The "com.blah.SomeClass" is replaced in this trace (just for this post) but it's a class that exists in the sample project, which was successfully built and installed onto the device. 
Nov 10, 2011
#1 rickg....@gmail.com
I am also seeing this problem.

Attached is a very simple example.
Nov 10, 2011
#2 rickg....@gmail.com
(No comment was entered for this change.)
sdk_build_test1.zip
149 KB   Download
Nov 10, 2011
#3 jason.po...@gmail.com
Update.. I'm very close to getting it all working with various changes to the default ANT build.  Once it's stable I'll blog it.
Nov 10, 2011
#4 jason.po...@gmail.com
I'm now stuck on the EMMA part.  Same problem reported here:
https://code.google.com/p/android/issues/detail?id=21640
Nov 10, 2011
#5 jason.po...@gmail.com
OK.. it gets worse unfortunately..

The EMMA issue I mentioned in the last comment was because I wasn't using an instrumented build.. ok, fair enough.  BUT... the new way that library projects are managed means that the source code for the library project is not in the src path of the referencing project (in my case the sample), which also means the class files do not get produced in the bin/classes folder.  Although the library classes ARE in the DEX file produced in the build, EMMA looks to the bin/classes folder for instrumented classes.

Hence it does not find the instrumented library classes, so you effectively cannot do code coverage of library projects.  :/
Nov 11, 2011
Project Member #6 x...@android.com
(No comment was entered for this change.)
Owner: x...@android.com
Labels: Target-r16
Nov 16, 2011
Project Member #7 r...@android.com
(No comment was entered for this change.)
Status: Assigned
Nov 17, 2011
#8 rickg....@gmail.com
Is there an expected date or timeframe for tools r-16 ?
Dec 1, 2011
#9 goo...@umito.nl
This is not fixed nor in 16 preview 1 nor 16 preview 2
Dec 1, 2011
#10 goo...@umito.nl
Converting all java projects to android projects using a android wrapper library worked for me finally. Just create for every jar or eclipse java project a new android project that references that project or jar. Then you include that wrapper project instead of the java project directly.
Dec 1, 2011
#11 jason.po...@gmail.com
All my projects are already Android projects.  The library projects are just marked as such in project.properties (android.library=true).

My work-around was to create a sym-link (actually Linked Source in eclipse) from the project referencing the library to the library source.  Basically re-creating the older way ADT handled library projects.
Dec 16, 2011
#12 a...@sibblingz.com
not fixed with sdk16 for me still broken.
Jan 3, 2012
#13 ze0...@gmail.com
Running into same problem as described in comment 5.

Everything works fine except the fact that introduced library projects do not get instrumented at all.

Is there any workaround for this? 
Re-creating 'linked src's' way of handling projects is an overkill... 
Jan 10, 2012
#15 joe.bowb...@gmail.com
The issue for library projects not getting instrumented is:

https://code.google.com/p/android/issues/detail?id=21276

and I think the reason for this is that the library jar is created before the library's classes are instrumented: a bug in the -compile target's implementation.

Jan 24, 2012
#16 chris@orr.me.uk
It's a shame those of us who use good software development practices like automated testing and code reuse get punished by having our builds broken by the new build system.. ;)  But hopefully this bug will be fixed soon..?

Anyway, I have a workaround that restores the desired functionality.  It's fairly pragmatic, pure Ant solution, but still somewhat ugly.
It requires compiling the test project against all its library dependencies, but then removing the library class files before they get dex'd and packaged into the test APK:


Copy the "<app-project>/project.properties" file to "<test-project>/project.properties" -- or at least copy over the "android.library.reference" lines to the test project.


Add the following target to "<test-project>/build.xml" before the <import> statement:

<target name="-post-compile">
    <delete verbose="true">
        <fileset dir="${out.classes.absolute.dir}" includes="${library.paths}" />
    </delete>
    <path id="out.dex.jar.input.ref">
        <fileset dir="${jar.libs.absolute.dir}" includes="*.jar" />
    </path>
</target>


Define the "library.paths" property in your "<test-project>/ant.properties" file as follows:
library.paths=com/example/my-library-1/** com/example/my-library-2/** com/example/my-library-3/**

i.e. Those are ant fileset matchers pointing to the library class files in <test-project>/bin/classes/


Running this with "ant all clean debug install test" works for me in a small project I used to reproduce the problem, as well as in a real-life project (four libraries, 650 unit tests).
Jan 24, 2012
#17 chris@orr.me.uk
Correction to comment 16:

The "android.library.reference" lines should be added to "<test-project>/ant.properties" rather than its project.properties file.
Otherwise building and testing from Ant works, but no longer from Eclipse!

With this change made to the workaround, the tests will run successfully regardless of how they are launched.
Mar 9, 2012
Project Member #18 x...@android.com
(No comment was entered for this change.)
Labels: Target-r18
Apr 4, 2012
#19 mmert1...@googlemail.com
I had similar issue for my build and succeed to fix it thanks to the solution provided in 16th comment. Unfortunately in order to run automated tests from my build script, after this command:

adb -s mydeviceid shell am instrument -w -e class com.mydomain.android.project.test.AllTests com.mydomain.android.project.test/android.test.InstrumentationTestRunner

i do get the following error:

INSTRUMENTATION_STATUS: id=ActivityManagerService
INSTRUMENTATION_STATUS: Error=Unable to find instrumentation info for: ComponentInfo{com.mydomain.android.project.test/android.test.InstrumentationTestRunner}
INSTRUMENTATION_STATUS_CODE: -1
android.util.AndroidException: INSTRUMENTATION_FAILED: com.mydomain.android.project.test/android.test.InstrumentationTestRunner

although i'm sure, that i call it with the right domains and class names.

someone ideas to fix it?
Apr 4, 2012
#20 joe.bowb...@gmail.com
See https://code.google.com/p/android/issues/detail?id=21276

The reason instrumentation is missing for library classes is because the -compile target creates the library's .jar before it instruments the library's classes...
Apr 9, 2012
#21 ievgenii...@gmail.com
Here is a workaround without copying libraries. I only have one library used by my application under test, so I just hardcoded the path. 

The idea is to "fix" the path "project.libraries.jars" before "-compile" target, and undo the fix before "-dex" target. 

    <!-- temporary hack for android  bug 21720  -->
    <target name="-pre-compile">
        <property name="project.libraries.jars.orig" value="${toString:project.libraries.jars}" />
        <path id="project.libraries.jars">
            <pathelement path="${project.libraries.jars.orig}" />
            <fileset dir="../actionbar-sherlock-lib/bin/">
                <include name="*.jar" />
            </fileset>
        </path>
    </target>

    <target name="-post-compile">
        <path id="project.libraries.jars">
            <pathelement path="${project.libraries.jars.orig}" />
        </path>
    </target>

Replace <fileset dir="../actionbar-sherlock-lib/bin/"> with you paths (or move it to some property file if you wish).
Apr 11, 2012
#22 mmert1...@googlemail.com
After solution provided in https://code.google.com/p/android/issues/detail?id=21720#c21 i'm having following error in due to classes from library project when executing tests:

test:
     [echo] Running tests ...
     [exec] INSTRUMENTATION_RESULT: shortMsg=java.lang.IllegalAccessError
     [exec] INSTRUMENTATION_RESULT: longMsg=java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation
     [exec] INSTRUMENTATION_CODE: 0

i did even change the build.xml of the library project the same way, which also depends from two another lib-projects, but it also doesn't help...
Apr 11, 2012
#23 chris@orr.me.uk
I haven't tried the workaround in comment 21, but I had the same "Class ref" error during test cases until I applied the workaround in comment 16.
Apr 11, 2012
#24 mmert1...@googlemail.com
i've figured out that i actually can't apply the workaround in 16 because main-project do have the same pakage domain like the lib-project with just one additional package for identifying the brand (the lib-project is actually for the common stuff, that different brands do have), for example like this:

Package of lib-project:
com.mydomain.product

Package of main-project (which is one of the multiple brands):
com.mydomain.product.brand1

So the fix in 16 is going to delete all file under com.myproject.product with the following line in ant.properties:

library.paths=com/mydomain/project/**

which of course is a non-sense in my case...
Apr 11, 2012
#25 mmert1...@googlemail.com
So, with a small change i've solved the problem!

I also included the two library-projects which was my lib-project depending on in ant.properties as refernced libraries and also in library.paths property.
The different thing was, that i set the path to my lib-project like this

com/mydomain/project/*

so that i was able to eliminate the conflict with the main-project's and test-project's path...
Apr 13, 2012
Project Member #26 x...@android.com
(No comment was entered for this change.)
Labels: -Target-r18 Target-r20
Apr 13, 2012
Project Member #27 x...@android.com
all the emma issues should be fixed in 20.
Apr 13, 2012
Project Member #28 x...@android.com
(No comment was entered for this change.)
Status: FutureRelease
Jun 25, 2012
#30 rickg....@gmail.com
I thought these issues were fixed in r19, but apparently not.

I've attached a sample with 4 projects.


AndroidBuildTestLib1
AndroidBuildTestLib2
AndroidBuildTestProject 
- references TestLib1
AndroidBuildTestProjectTest
- Tests AndroidBuildTestProject
- references TestLib2

In eclipse the junits run just fine.

In ant, the compile of AndroidBuildTestProject fails to find classes in AndroidTestLib1.  Adding the reference create the problem with duplicate classes.

Can someone confirm that this fixed in r20 or has a workaround for r19?


build_test.zip
386 KB   Download
Jun 25, 2012
#31 chris@orr.me.uk
There's been a preview of r20 on the tools sites for a while, so you could test with that.
Jul 9, 2012
#32 nono...@gmail.com
Same issue on r20.....
Jul 11, 2012
Project Member #33 x...@android.com
(No comment was entered for this change.)
Status: Released
Sign in to add a comment

Powered by Google Project Hosting