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

7

11

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?

Algae answered 20/12, 2011 at 20:35 Comment(3)
Have you checked if .apk contains classes that are not found?Oxfordshire
I have almost the same exact problem as you: An Android project that depends on Java-only projects. Up until today (when I updated to Android SDK Tools r17 from r16), I was able to make this work with Project Properties->Java Build Path->Projects. But now I get the same exception you report. I filed a bug report: code.google.com/p/android/issues/detail?id=27882Superhuman
Wow i was going nuts with this problem. Luckily jfritz42's link had the answer i needed. Thx man.Breeching
S
12

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).

Superhuman answered 28/3, 2012 at 18:5 Comment(0)
C
2

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>
Cheyenne answered 11/3, 2012 at 7:38 Comment(0)
U
2

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.

Unkennel answered 11/3, 2012 at 22:18 Comment(0)
S
2

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

Testing Android project with jar dependecies

Six answered 14/9, 2012 at 20:24 Comment(0)
P
1

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.

Photomicrograph answered 16/3, 2012 at 9:56 Comment(0)
J
0

I doubt about you and your project. From my viewpoint, I see you have a good design. But why are you working with Build Path / Order and Export? Honestly I've never gone to that tab from the first day I worked with Eclipse.

To import jar files as libraries, use tab Libraries -> add external Jars.

And I'm sorry I don't know about game programming, this is just a suggestion: make sure your engine fits what Android supports. For example Android doesn't support javax.imageio. If not, the app can be compiled with external jars, but can be crashed in runtime.

Jehiel answered 17/3, 2012 at 22:48 Comment(0)
I
0

I know this is an old question, but I found a new way of coming across this error which may help others with recent updates.

I got this error from using a switch/case statement on the R.id. "constants". The latest updates no longer consider the R.java declarations to be constant in the code even though they are declared as final. What happens is the .apk will compile and install but yield those Lcom errors.

To solve this (in Eclipse) is put the cursor at the switch declaration and use Ctrl+1 to convert the switch to a list of if then else's. Note if you have nested breaks within a case statement you'll need to rewrite that block of code (probably with extra else's).

Inurbane answered 7/7, 2013 at 16:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.