Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Activity under Eclipse/ADT with Project Dependencies (Failed resolving XY)

I tried to keep a game project quite platform independent so I split it up into three projects from low-level to top android specific level like that: engine, game, android game.

The involved classes/interfaces in the error are those:

  1. (low level) engine project defines this interface:

    com.myteam.engine.IGame
    
  2. (mid level) platform independent game project defines those classes:

    com.myteam.myproject.Game
    com.myteam.myproject.MyProject (derived from com.myteam.myproject.Game)
    
  3. (top level) android project implements activity, etc.:

    com.myteam.myproject.android.MyAndroidActivity (using com.myteam.myproject.MyProject)
    

All compiles well and runs perfectly under Windows (with another Windows project on level 3 using the first two).

But when running with ADT it fails at run-time when the Activity starts. The Android app basically just displays a call stack with a "NoClassDefFoundError com.myteam.myproject.MyProject" exception.

The exception seems to be caused by its super class (or the super class' interface) while loading/resolving as the LogCat output reveals:

12-20 19:51:51.897: D/ddm-heap(218): Got feature list request
12-20 19:51:52.207: I/dalvikvm(218): Failed resolving Lcom/myteam/myproject/Game; interface 18 'Lcom/myteam/engine/IGame;'
12-20 19:51:52.217: W/dalvikvm(218): Link of class 'Lcom/myteam/myproject/Game;' failed
12-20 19:51:52.227: W/dalvikvm(218): Unable to resolve superclass of Lcom/myteam/myproject/MyProject; (52)
12-20 19:51:52.227: W/dalvikvm(218): Link of class 'Lcom/myteam/myproject/MyProject;' failed
12-20 19:51:52.227: E/dalvikvm(218): Could not find class 'com.myteam.myproject.MyProject', referenced from method com.myteam.myproject.android.MyAndroidActivity.onCreate
12-20 19:51:52.227: W/dalvikvm(218): VFY: unable to resolve new-instance 54 (Lcom/myteam/myproject/MyProject;) in Lcom/myteam/myproject/android/Youcode_AndroidActivity;
12-20 19:51:52.227: D/dalvikvm(218): VFY: replacing opcode 0x22 at 0x0008
12-20 19:51:52.227: D/dalvikvm(218): Making a copy of Lcom/myteam/myproject/android/Youcode_AndroidActivity;.onCreate code (88 bytes)

I tried adding the two first projects under the "Build Path / Order and Export" Eclipse project settings of the android game project as described in other posts and forums but it doesn't change a thing.

My hunch is that the Manifest or Project settings need another mentioning of the package/class dependencies for apk packaging or run-time. Any ideas?

like image 380
PiLLe Avatar asked Dec 20 '11 20:12

PiLLe


5 Answers

I have a three-tiered Android/Java app, almost just like you:

  1. Java-only project for low level network communication
  2. Java-only project to abstract the low level project's features
  3. Android app

Each thing above is a separate Eclipse project contained in a single workspace.

Here's what you need to do:

  1. Under the App's project properties->Java Build Path->Projects, add the Java-only projects
  2. Under the App's project properties->Java Build Path->Order and Export, check the Java-only projects (which marks them for export)

Now your app should build and run without NoClassDefFoundError exceptions or VFY errors like the following:

03-27 21:10:17.120: W/dalvikvm(420): VFY: unable to find class referenced in signature (Labstractionlayer/BaseStationManager;)
03-27 21:10:17.120: W/dalvikvm(420): VFY: unable to find class referenced in signature (Labstractionlayer/BaseStationManager;)
03-27 21:10:17.160: I/dalvikvm(420): Failed resolving Lcom/demo/log/AndroidLogWrapper; interface 253 'Lcommon/Logger/LogWrapper;'
03-27 21:10:17.160: W/dalvikvm(420): Link of class 'Lcom/demo/log/AndroidLogWrapper;' failed
03-27 21:10:17.160: E/dalvikvm(420): Could not find class 'com.demo.log.AndroidLogWrapper', referenced from method com.demo.Application.onCreate
03-27 21:10:17.160: W/dalvikvm(420): VFY: unable to resolve new-instance 218 (Lcom/demo/log/AndroidLogWrapper;) in Lcom/demo/Application;
03-27 21:10:17.170: D/dalvikvm(420): VFY: replacing opcode 0x22 at 0x0003
03-27 21:10:17.170: D/dalvikvm(420): VFY: dead code 0x0005-003c in Lcom/demo/Application;.onCreate ()V
03-27 21:10:17.170: D/AndroidRuntime(420): Shutting down VM
03-27 21:10:17.170: W/dalvikvm(420): threadid=1: thread exiting with uncaught exception (group=0x40015560)
03-27 21:10:17.180: E/AndroidRuntime(420): FATAL EXCEPTION: main
03-27 21:10:17.180: E/AndroidRuntime(420): java.lang.NoClassDefFoundError: com.demo.log.AndroidLogWrapper

BTW, prior to ADT r17, you only needed to do step 1 above (add the Java-only projects). But beginning with r17, you need to also do step 2 (mark the Java-only projects for export).

like image 195
jfritz42 Avatar answered Nov 09 '22 03:11

jfritz42


Add name of your dependent projects to .claspath file of your android project. like that:

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
    <classpathentry kind="src" path="src"/>
    <classpathentry kind="src" path="gen"/>
    <classpathentry combineaccessrules="false" kind="src" path="/DependentProject1"/>
    <classpathentry combineaccessrules="false" kind="src" path="/DependentProject2"/>
    <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
    <classpathentry kind="output" path="bin"/>
</classpath>
like image 24
Behlül Avatar answered Nov 09 '22 04:11

Behlül


I have been trying to find an simple solution for this long time ago, as far as I can tell, the only way to make ADT export the final apk with the dependent library classes is explicitly add all your external lib.jar (generated from your other projects) into your Android project's build path.

Current version of Eclipse ADT plugin has a very inflexible predefined build life cycle (specifically in dexing step), apparently it doesn't support project grouping other than those three types of Android Project together (classic, library and test). In another words, ADT doesn't know how to build your Android project with a regular java dependent project under the build path and automatically add the lib.jar generated by dependent project into your main project's build path (even though you add them to Order and Export list), unless you explicitly add the external lib.jar into it. Suppose you add C:\workspace\game\target\game.jar and C:\workspace\engine\target\engine.jar into your android-game project's build path, command to generate your dex file should be something like this:

java [-Xmx1024M, -jar, C:\android-sdk-r16\platform-tools\lib\dx.jar, --dex, --output=C:\workspace\android-game\target\classes.dex, C:\workspace\android-game\target\classes, C:\workspace\game\target\game.jar, C:\workspace\engine\target\engine.jar]

If you plan to adopt some external build tools to manage your project build life cycle, I know Maven provide more flexible configuration on Android build life cycle. It support multi-module project (project grouping) and can handle regular java project dependency properly.

My knowledge is based on Eclipse, Looking forward to hear some noises from Android source or other sophisticated IDE user.

Update from ADT 17.0.0:

Latest release SDK r17 with ADT 17.0.0 claims to handle this use cases properly now:

Eclipse specific changes

The dynamic classpath container called “Library Projects” has been renamed to “Android Dependencies” as it now contains more than just Library Projects.

The container will now also be populated with Java-only projects that are referenced by Library Projects. If those Java projects also reference other Java projects and/or jar files they will be added automatically (jar files referenced through user libraries are supported as well).

Important: this only happens if the references are set to be exported in the referencing project. Note that this is not the default when adding a project or jar file to a project build path. Library Projects (and the content of their libs/*.jar files) is always exported. This change only impacts Java-only projects and their own jar files.

Again, duplicates (both projects and jar files) are detected and removed.

Check out the changelog.

like image 2
yorkw Avatar answered Nov 09 '22 03:11

yorkw


I found this thread and it actually worked for me just make sure to check the dependentproject

Testing Android project with jar dependecies

like image 2
magorich Avatar answered Nov 09 '22 02:11

magorich


The Java Build path of the mid-level project includes the low-level project, I guess. Have you checked the low-level project for there (tab "Order and Export")? Otherwise, the low-level project dependency is not forwarded to the high-level project, excluding IGame from the APK, which actually triggers the failure.

However, this solution AFAIK will not work if your projects contain Android-specific things like resources and the like.

like image 1
johsin18 Avatar answered Nov 09 '22 04:11

johsin18