Monday, December 19, 2011

How I got eclipse to play nice with Android ADT16

Ever since Google released version 14 of the Android Developer Tools for eclipse, the Android development community has been in an uproar. Many developers are facing broken build environments that have forced them to repackage and restructure their source just so they can move forward. ADT 15 & 16 have fixed these bugs, however, many of us have legacy objects in our build environment which are producing the dreaded error;



UNEXPECTED TOP-LEVEL EXCEPTION:
java.lang.IllegalArgumentException: already added: Lpath/to/some/Class;
....
Conversion to Dalvik format failed with error 1



This problem forced me to work through Ant scripts for a long period despite various posts describing different fixes for the problem.  I have now resolved the different problems and this post explains how.

First, take a look at the following image.  It shows how my various eclipse projects and android libraries flow into projects that depend on them.


At the bottom are two custom java frameworks I have created for use in my apps.  In the next block up are three android libraries my apps rely on.  Notice that I have libraries dependent on libraries.  At the top level are two product families with still more libraries depending on libraries.  In fact, my original app for Android 2.1 depends on the App for Android 2.2.  (To accomplish this, I turn the main app into a library long enough to build the OS 2.1 App).   To the top right is a new family of Apps built on a refactoring of the original app (Android Lib 6).  

It is not necessary to understand why my projects are so encapsulated or complicated.  What matters for this article is that, despite all the dependencies, the entire thing builds and runs without error.

Step 1 - Remove all the '_src' folders.  

I won't go into detail on this.  This problem is well documented around the internet.  Just get rid of all folders named '_src'.  This is the old way Android SDT used to include libraries.

Step 2 - Check your build path in eclipse

In each projects properties, under the 'Order & Export' tab, make sure that the src folder is ahead of the gen folder.  If the gen folder precedes the src folder, eclipse has problems finding the source code during debugging.

Step 3 - Remove your libs directories from your projects

This is where I had real problems.  The presence of a libs directory in one of my projects was creating a problem even though the contents of that directory were not specified in my build path.


Step 4 - get control of your jar files.

In order to maintain libraries for this kind of structure I use an external lib directory.  Mine happens to sit at the same level as the projects themselves but it could be anywhere.  All my jar dependencies go into that folder.  (e.g. commons-lang.jar ).  My custom frameworks at the bottom level of the chart above also build directly into the lib directory.  So my package explorer looks like this;

> Product 1
> Product 2
>Android Lib 4
>Android Lib 3
    ...
>lib
        commons-lang.jar
        Java_Framework.jar
        J_ Framework.jar
        ...
>Java Framework
>J Framework


So, instead of using the libs directory in each project, instead I defined an eclipse environment variable called COMMONS_LIB and pointed it to the central lib directory.  In each project, I added the necessary jar files as extensions to that variable.

Now, each project shows three Libraries - One for the Android SDK, one called Library Projects which contains jar files for the Android libraries and one called Referenced Libraries which contains the jar files I explicitly defined using the COMMONS_LIB variable.

NOTE: Do not add COMMONS_LIB to the build path without an extension.  That will cause ALL the jar files in that directory get added and some of those could be duplicates of jar files in your Referenced Libraries Library.

If the project is set up correctly, you should be able to expand both Referenced Libraries and Library Projects and see each of your required jar files once and only once.

If you follow these steps you should be able to build and run your apps from eclipse.