Class resolved by unexpected DEX error

4,156 views
Skip to first unread message

Phil HUXLEY

unread,
Nov 27, 2008, 12:07:33 PM11/27/08
to android-...@googlegroups.com

I have a (I beleive) a modified Android image that includes a Java library
built into the image. In the process of building the image, a related
'classes.jar' file gets built which I can include as an external jar file
from a project under Eclipse. The presence of this classes.jar file enables
the system to import and use the classes in the java library.

However, if I point the run configuration at the new build and launch the
application I get the error above.

If I rummage around in the Android code, the place where this message is
generated impllies that if the referrer was pre-verified, then the resolved
class must come from the same DEX.

When the library is built and the image put together, I see three related
files generated in "out/target/common/obj/JAVA_LIBRARIES/mylibrary/ - these
being classes.dex, classes.jar and javalib.jar.

I also get a jar file generated in
out/target/product/generic/system/framework/mylibrary.jar

The classes.jar file is the one I reference when developing using the
library as it contains the classes. The other files look like the contain
DEX code.

In therory, the classes.jar file i'm referring to should work with the java
stuff that gets built into the image..so what is it that I am not doing?

Dianne Hackborn

unread,
Nov 28, 2008, 9:38:20 PM11/28/08
to android-...@googlegroups.com
If you are making a separate shared library, then you need to have it put in the system image under its own name, put an entry in etc/permissions.xml mapping from your library's package name to the path to the .jar file, and then any applications using the library must have a <uses-library> tag in their manifest to have the library loaded into their class path.
--
Dianne Hackborn
Android framework engineer
hac...@android.com

Note: please don't send private questions to me, as I don't have time to provide private support.  All such questions should be posted on public forums, where I and others can see and answer them.

Phil HUXLEY

unread,
Dec 1, 2008, 9:46:11 AM12/1/08
to android-...@googlegroups.com

Thanks Dianne,

Nearly there!

Yes - all those bits are in place - and if I disable a check that happens
in the Android code (around about line 113 in dalvik/vm/oo/Resolve.c - the
line that starts:
if (!fromUnverifiedConstant..) then it all springs into life. With the
check in, the application fails.

The comment in the code implies that if the referrer were pre-verified,
then the resolved class must come from the same DEX code or bootstrap
class. This is causing me some confusion as I beleive that I'm using the
correct components. I'm referencing the generated 'classes.jar' file from
the Android project that is related to the jar file that gets incorporated
into the image (or so I beleive). It may be that I'm still missing a peice
of magic somewhere and perhaps it is down to some pre-processing when the
image is built.

I repeat, if my library is called mylib, and I build it (with its own
makefile) The following entities get created:
- Under out/target/common/obj/JAVA_LIBRARIES/mylib_intermediates
classes.dex
classes.jar
javalib.jar
- Under out/target/product/generic/system/framework/mylib.jar

Of the above files, the classes.jar file contains the '.class' components,
the javalib.jar contains the classes.dex components as does the javalib.jar
file. By pointing the eclipse project at the classes.jar file, the project
happily resolves the references. If I examine what's in the image (using
adb) I can confirm that mylib.jar is indeed under system/framework. All the
files appear to have the same

Thus I'm confused as to why the aforementioned run-time check has failed -
perhaps I'm missing a step that happens when the sdk is built and
android.jar produced?


"Dianne Hackborn"
<hackbod@android.
com> To
Sent by: android-...@googlegroups.com
android-platform@ cc
googlegroups.com
Subject
Re: Class resolved by unexpected
29/11/2008 02:38 DEX error


Please respond to
android-platform@
googlegroups.com

ForwardSourceID:NT00003E3E

Dianne Hackborn

unread,
Dec 1, 2008, 12:59:04 PM12/1/08
to android-...@googlegroups.com
Sorry this is outside of what I know; I work on the framework, not Dalvik, so at that point I basically know that if I set up a shared library the way we have done others in the tree, it seems to work. :}

fadden

unread,
Dec 1, 2008, 6:51:13 PM12/1/08
to android-platform
On Dec 1, 6:46 am, Phil HUXLEY <phil.hux...@3dlabs.com> wrote:
> The comment in the code implies that if the referrer were pre-verified,
> then the resolved class must come from the same DEX code or bootstrap
> class. This is causing me some confusion as I beleive that I'm using the
> correct components. I'm referencing the generated 'classes.jar' file from
> the Android project that is related to the jar file that gets incorporated
> into the image (or so I beleive).  It may be that I'm still missing a peice
> of magic somewhere and perhaps it is down to some pre-processing when the
> image is built.

As noted in the sources, the long-winded explanation is in dalvik/vm/
oo/Class.c, with some additional background provided in dalvik/docs/
dexopt.html.

> - Under out/target/product/generic/system/framework/mylib.jar

What classes are in that library?

How is the library being loaded?

What's the full content of the log message?

What are you coding against? Tip-of-tree sources from "git"?

Xavier Ducrohet

unread,
Dec 1, 2008, 7:17:22 PM12/1/08
to android-...@googlegroups.com
I'm not sure about the dalvik part, but I'd like to mention an issue
with Eclipse here.

Adding your .jar file as an external library means that the Android
plugin for Eclipse will treat this as a 3rd party library, which is to
be included with your application code.

Therefore you will get your library code inside your app, as well as
on the system. I'm not sure what will happen.

There is no support for optional system libraries in the plugin (yet),
and you should use Ant instead.
Just modify the "compile" target to add your library to the classpath.

Xav

Phil HUXLEY

unread,
Dec 2, 2008, 7:02:21 AM12/2/08
to android-...@googlegroups.com
Xav,

Thanks for your input - I'm pretty sure that something like this is
happening. dalvik is 'unexpectedly resolving the class' - the error message
is 'Class resolved by unexpected DEX' (which is what happens) and this
results in an IllegalAccessError exception being thrown.

When a vanilla flavoured android is built (make), then an associated sdk
(make.sdk), the resultant android.jar file can be used in the SDK for
development purposes. Does this mean that both the jar file and the image
contain the android classes? Does the plugin reference android.jar in a
different way to an external library. My question is - why does it work for
android.jar, but not my library - what bit of post-processing am I not
doing?

I'd like to think that a developer could use Eclipse & the plug in to
develop something that used this extended library! t'would seem a shame if
he couldn't.

I don't know much about ant - seems a step backwards from using Eclipse
etc.


Xavier Ducrohet
<x...@google.com>
Sent by: To
android-platform@ android-...@googlegroups.com
googlegroups.com cc

Subject
02/12/2008 00:17 Re: Class resolved by unexpected

Xav

ForwardSourceID:NT00004092

Xavier Ducrohet

unread,
Dec 2, 2008, 2:06:36 PM12/2/08
to android-...@googlegroups.com
Hi Phil,

The custom builders provided by the Eclipse plugin treat android.jar
differently. It's used to compile the Java classes, but not used in
the packaging because it's considered a system library.

However, external libraries must be packaged with the apk or the
application would not work, since their code is not already present in
the system image.

We are working on supporting optional system libraries at the plugin
level, but this is not ready yet (we'll add automated support for this
in Ant too.)

In the mean time, because Ant is a script that you can manually change
(as opposed to not being able to change the Eclipse builders), you can
use Ant to build your application the way you need it.

Xav

Phil HUXLEY

unread,
Dec 3, 2008, 6:34:50 AM12/3/08
to android-...@googlegroups.com
Xav,

Thanks again for clarifying that. For now I'll skip the check dalvik makes
so I can use Eclipse (more convenient in the short-term).

Presumably your changes to accomodate this will be a change to the Eclipse
plugin and sounds weeks away rather than months?

Best Regards,
Phil.



Xavier Ducrohet
<x...@google.com>
Sent by: To
android-platform@ android-...@googlegroups.com
googlegroups.com cc

Subject

02/12/2008 19:06 Re: Class resolved by unexpected

Hi Phil,

Xav

ForwardSourceID:NT0000425E

Richard Meng

unread,
Aug 20, 2009, 3:47:51 AM8/20/09
to Dianne Hackborn, android-...@googlegroups.com
Sorry, I didn't find the option to *reply* this thread, but only
*reply author*. (though i am new here, i can't find the *reply* in the
expanded thread.) Anyway, adding the group mail address in the *To*
field.

And can you help with this :

>> Do you how to buildup the etc/permissions.xml? Anywhere should i input
>> under the platform?

Thanks!

On Thu, Aug 20, 2009 at 1:22 PM, Dianne Hackborn<hac...@android.com> wrote:
> Could you please post publicly?  Thanks.
>
> On Wed, Aug 19, 2009 at 10:02 PM, Richard Meng <meng...@gmail.com> wrote:
>>
>> Hi Dianne,
>>
>> Do you how to buildup the etc/permissions.xml? Anywhere should i input
>> under the platform?
>>
>> Thanks
>> -Richard
>>
>> On Nov 29 2008, 10:38 am, "Dianne Hackborn" <hack...@android.com>


>> wrote:
>> > If you are making a separate shared library, then you need to have it
>> > put in
>> > the system image under its own name, put an entry in etc/permissions.xml
>> > mapping from your library's package name to the path to the .jar file,
>> > and
>> > then any applications using the library must have a <uses-library> tag
>> > in
>> > their manifest to have the library loaded into their class path.
>> >
>> >
>> >

>> > On Thu, Nov 27, 2008 at 9:07 AM, Phil HUXLEY <phil.hux...@3dlabs.com>

>> > hack...@android.com


>> >
>> > Note: please don't send private questions to me, as I don't have time to
>> > provide private support.  All such questions should be posted on public
>> > forums, where I and others can see and answer them.
>
>
>
> --
> Dianne Hackborn
> Android framework engineer
> hac...@android.com
>
> Note: please don't send private questions to me, as I don't have time to

> provide private support, and so won't reply to such e-mails.  All such

jimshowalter

unread,
Sep 27, 2009, 12:43:25 PM9/27/09
to android-platform
I am also getting class resolved by unexpected DEX, cross-loader
access from pre-verified class.

I first encountered this problem on a real product I'm working on,
couldn't resolve it there, and boiled it down to the following simple
setup that reproduces the problem:

I have three projects: LoaderProblem, LoaderProblemTest, and
LoaderProblemCommon.

LoaderProblem is an Android project, and was created with the 1.6 ADT
project wizard.

LoaderProblemTest is an Android test project, and was created with the
same project wizard after creating the main Android project.

LoaderProblemCommon is an ordinary Eclipse Java project.

LoaderProblemTest has an Eclipse project dependency on LoaderProblem.

LoaderProblem and LoaderProblemTest have Eclipse project dependencies
on LoaderProblemCommon.

LoaderProblemCommon contains one source file, LoaderLogger.java:

package com.loaderproblem;

public class LoaderLogger {
public static void log(String message) {
System.out.println(message);
}
}

What the class does is irrelevant--I just needed something that the
other two projects could share.

LoaderProblem contains one source file, Hello.java, which contains the
default code put there by the wizard, plus a hello method (so I have
something to call from the test):

package com.loaderproblem;

import android.app.Activity;
import android.os.Bundle;

public class Hello extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
logHello();
}

public static void logHello() {
LoaderLogger.log("Hello");
}
}

LoaderProblemTest contains one source file, LogHelloTest.java:

package com.loaderproblem.test;

import com.loaderproblem.Hello;
import android.test.AndroidTestCase;

public class LogHelloTest extends AndroidTestCase {
public void testLogHello() {
Hello.logHello();
}
}

When I run LoggerProblem as an Android application, the emulator
launches and the hello screen displays. There are no errors.

But when I run LoggerProblemTest as an Android JUnit test, logcat
displays the errors below.

What am I doing wrong? It appears that the loader doesn't let me share
projects or code.

Note that the shared code isn't being compiled to a JAR, just
to .class files.

The same problem happens with 1.5 ADT.

I can probably trick the loader by using symbolic links to make it
look like all of the code is in the main Android project, but that's a
hack.

09-27 16:21:53.587: INFO/jdwp(1132): received file descriptor 29 from
ADB
09-27 16:21:53.697: INFO/TestRunner(1132): started: testLogHello
(com.loaderproblem.test.LogHelloTest)
09-27 16:21:53.817: WARN/dalvikvm(1132): Class resolved by unexpected
DEX: Lcom/loaderproblem/Hello;(0x43761310):0x1aa540 ref [Lcom/
loaderproblem/LoaderLogger;] Lcom/loaderproblem/LoaderLogger;
(0x43761310):0x1a99a8
09-27 16:21:53.837: INFO/TestRunner(1132): failed: testLogHello
(com.loaderproblem.test.LogHelloTest)
09-27 16:21:53.847: INFO/TestRunner(1132): ----- begin exception -----
09-27 16:21:53.967: INFO/TestRunner(1132):
java.lang.IllegalAccessError: cross-loader access from pre-verified
class
09-27 16:21:53.967: INFO/TestRunner(1132): at
com.loaderproblem.Hello.logHello(Hello.java:17)
09-27 16:21:53.967: INFO/TestRunner(1132): at
com.loaderproblem.test.LogHelloTest.testLogHello(LogHelloTest.java:11)
09-27 16:21:53.967: INFO/TestRunner(1132): at
java.lang.reflect.Method.invokeNative(Native Method)
09-27 16:21:53.967: INFO/TestRunner(1132): at
java.lang.reflect.Method.invoke(Method.java:521)
09-27 16:21:53.967: INFO/TestRunner(1132): at
junit.framework.TestCase.runTest(TestCase.java:154)
09-27 16:21:53.967: INFO/TestRunner(1132): at
junit.framework.TestCase.runBare(TestCase.java:127)
09-27 16:21:53.967: INFO/TestRunner(1132): at
junit.framework.TestResult$1.protect(TestResult.java:106)
09-27 16:21:53.967: INFO/TestRunner(1132): at
junit.framework.TestResult.runProtected(TestResult.java:124)
09-27 16:21:53.967: INFO/TestRunner(1132): at
junit.framework.TestResult.run(TestResult.java:109)
09-27 16:21:53.967: INFO/TestRunner(1132): at
junit.framework.TestCase.run(TestCase.java:118)
09-27 16:21:53.967: INFO/TestRunner(1132): at
android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:164)
09-27 16:21:53.967: INFO/TestRunner(1132): at
android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:151)
09-27 16:21:53.967: INFO/TestRunner(1132): at
android.test.InstrumentationTestRunner.onStart
(InstrumentationTestRunner.java:425)
09-27 16:21:53.967: INFO/TestRunner(1132): at
android.app.Instrumentation$InstrumentationThread.run
(Instrumentation.java:1520)
09-27 16:21:53.988: INFO/TestRunner(1132): ----- end exception -----
09-27 16:21:54.037: INFO/TestRunner(1132): finished: testLogHello
(com.loaderproblem.test.LogHelloTest)
09-27 16:21:54.057: INFO/TestRunner(1132): started:
testAndroidTestCaseSetupProperly(com.loaderproblem.test.LogHelloTest)
09-27 16:21:54.086: INFO/TestRunner(1132): finished:
testAndroidTestCaseSetupProperly(com.loaderproblem.test.LogHelloTest)
09-27 16:21:54.086: INFO/TestRunner(1132): passed:
testAndroidTestCaseSetupProperly(com.loaderproblem.test.LogHelloTest)
09-27 16:21:54.137: DEBUG/ActivityManager(567): Uninstalling process
com.loaderproblem
09-27 16:21:54.137: DEBUG/ActivityManager(567): Force removing process
ProcessRecord{438bfdb0 1132:com.loaderproblem/10027}
(com.loaderproblem/10027)

Jim Showalter

unread,
Sep 27, 2009, 1:07:38 PM9/27/09
to android-platform
Resolved, finally. In Eclipse, in the build path for the test project, instead of adding project dependencies on the shared code, I needed to add dependencies on the class libraries.

It will be interesting to see how to get this working from maven.

By the way, there is an error in the example below--the test should have called the log method directly:


public class LogHelloTest extends AndroidTestCase {
    public void testLogHello() {
        LoaderLogger.log("Hello");
        Hello.logHello();
    }
}

That doesn't change the behavior, but it's more representative of the problem in the real product.

jimshowalter

unread,
Sep 27, 2009, 3:51:05 PM9/27/09
to android-platform
Although depending on the class folders instead of the project source
folders fixed the problem, it's not clear *why* it fixed the problem.

Does anyone know why it worked?

On Sep 27, 10:07 am, Jim Showalter <jamesleeshowal...@gmail.com>
wrote:
> Resolved, finally. In Eclipse, in the build path for the test project,
> instead of adding project dependencies on the shared code, I needed to add
> dependencies on the class libraries.
>
> It will be interesting to see how to get this working from maven.
>
> By the way, there is an error in the example below--the test should have
> called the log method directly:
>
> public class LogHelloTest extends AndroidTestCase {
>     public void testLogHello() {
>         LoaderLogger.log("Hello");
>         Hello.logHello();
>     }
>
> }
>
> That doesn't change the behavior, but it's more representative of the
> problem in the real product.
>
> On Sun, Sep 27, 2009 at 9:43 AM, jimshowalter
> <jamesleeshowal...@gmail.com>wrote:

Fred Grott

unread,
Sep 27, 2009, 4:23:22 PM9/27/09
to android-...@googlegroups.com
if I rememebr the ant scripts in android_rules.xml and etc dex takes references from bin/classes parent project correct?

Jim Showalter

unread,
Sep 27, 2009, 6:15:06 PM9/27/09
to android-...@googlegroups.com
Can you explain what that means in a bit more detail?

jimshowalter

unread,
Oct 4, 2009, 6:33:48 PM10/4/09
to android-platform
For an example of how to reproduce this problem as well as fix it, see
http://jimshowalter.blogspot.com/2009/10/developing-android-with-multiple.html.

On Sep 27, 3:15 pm, Jim Showalter <jamesleeshowal...@gmail.com> wrote:
> Can you explain what that means in a bit more detail?
>
> On Sun, Sep 27, 2009 at 1:23 PM, Fred Grott <fred.gr...@gmail.com> wrote:
> > if I rememebr the ant scripts in android_rules.xml and etc dex takes
> > references from bin/classes parent project correct?
>
> > On Sun, Sep 27, 2009 at 2:51 PM, jimshowalter <jamesleeshowal...@gmail.com

Bjarke Freund-Hansen

unread,
Jul 13, 2011, 5:37:12 AM7/13/11
to android-...@googlegroups.com
Just for info when others encounter the problem. What Jim Showalter describes on his blog solved the issue for me. Specifically the last few lines contains the "right" solution:

The proper way to fix this problem was reported by another reader:
  1. In the build path for LoaderProblem, click on "Order and Export".
  1. Check the box for LoaderCommon, to let LoaderProblem export the LoaderCommon classes as well as its own.
  1. In the build path for LoaderProblemTests, remove the dependency on the LoaderCommon project. The dependency is already now covered by the LoaderProblem dependency.
  1. Clean, build, rerun LoaderProblem, then rerun LoaderProblemTests.


Read the rest of the blog entry for a very nice explanation of why the problem occurs in the first place.


/Bjarke
Reply all
Reply to author
Forward
0 new messages