4

First, I want to mention that I read many stackoverflow posts about NoClassDefFoundError, and I also read about it in many other blogs and websites, but the solutions that people offered didn't fix it.

I am running Eclipse 64-bit with the ADT plugin version v21.0.1-543035 on Ubuntu 12.10 64-bit. Everything is 64-bit, Ubuntu, Eclipse and the JRE and JDK that I use (jdk1.6.0_38).

I wrote a very small Android App that needs a class from the JDK to run.

I isolated the problem a little, and recreated it by creating a new "Android Application Project" with ONLY ONE LINE OF MY CODE (in the main class in the onCreate method). This line:

BufferedImage buff = new BufferedImage(100,100,BufferedImage.TYPE_INT_RGB);

Eclipse automatically adds the necessary import:

import java.awt.image.BufferedImage;

but asks that I add the jars/JRE for this class.

I added the jdk1.6.0_38 to Eclipse in "Installed JREs" (like they instruct on the Eclipse help pages).

In the project's "Java Build Path" I added it through "Add library" -> "JRE system library" -> "Workspace default JRE". It automatically added the JDK to the project's build path.

During compile time, I get no errors. Only when running the application in the android emulator (any AVD) I get the following error:

E/dalvikvm(828): Could not find class 'java.awt.image.BufferedImage', referenced from method com.example.usejdk.MainActivity.onCreate
W/dalvikvm(828): VFY: unable to resolve new-instance 467 (Ljava/awt/image/BufferedImage;) in Lcom/example/usejdk/MainActivity;
D/dalvikvm(828): VFY: replacing opcode 0x22 at 0x0009
D/dalvikvm(828): DexOpt: unable to opt direct call 0x0cdc at 0x0c in Lcom/example/usejdk/MainActivity;.onCreate
D/AndroidRuntime(828): Shutting down VM
W/dalvikvm(828): threadid=1: thread exiting with uncaught exception (group=0x40a70930)
E/AndroidRuntime(828): FATAL EXCEPTION: main
E/AndroidRuntime(828):   java.lang.NoClassDefFoundError: java.awt.image.BufferedImage
E/AndroidRuntime(828):   at com.example.usejdk.MainActivity.onCreate(MainActivity.java:16)
E/AndroidRuntime(828):   at android.app.Activity.performCreate(Activity.java:5104)
E/AndroidRuntime(828):   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
E/AndroidRuntime(828):   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
E/AndroidRuntime(828):   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
E/AndroidRuntime(828):   at android.app.ActivityThread.access$600(ActivityThread.java:141)
E/AndroidRuntime(828):   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
E/AndroidRuntime(828):   at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(828):   at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(828):   at android.app.ActivityThread.main(ActivityThread.java:5039)
E/AndroidRuntime(828):   at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(828):   at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(828):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
E/AndroidRuntime(828):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
E/AndroidRuntime(828):   at dalvik.system.NativeStart.main(Native Method)

Here are the things I tried that didn't work:

  1. adding to "eclipse.ini" the location of the jdk ("-vm /usr/lib/jvm/jdk1.6.0_38/bin" in 2 separate lines).
  2. I added the "Default VM Arguments" of the path "-Djava.library.path=/usr/lib/jvm/jdk1.6.0_38/jre/lib".
  3. Using 32-bit JREs and JDKs and JRE/JDK7 - didn't work (of course).
  4. I tried adding the jdk jar files manually to the "libs" folder and mark "add to buildpath" - didn't work.
  5. I uninstalled and installed Eclipse again with the ADT and Android SDK...

Nothing fixes this annoying error...

Please, also notice these:

  1. I made sure my .classpath file contains the default JRE entry (like they say here)
  2. I tried adding other jar files to the "libs" folder + "add to path", and using them - it worked fine.
  3. I tried running the same code (the one line) using the "import java.awt.image.BufferedImage;" in a regular java project (not an android project) and made the project "use Default JRE" - and it worked fine! Why does it work on a REGULAR Java project and not in an Android project?

I guess it means that my Eclipse installation does have the ability to use the jdk classes, but not in android applications.

So what do I have to do to make this single line of code run in an android application?

Any help would be VERY-VERY appreciated. Thanx in advance.

fasti
  • 2,379
  • 3
  • 16
  • 9

1 Answers1

8

So what do I have to do to make this single line of code run in an android application?

The short answer is: nothing, because you can't do anything about it. The whole java.awt.* framework isn't part of the Android SDK, including BufferedImage, and hence not supported by the emulator or physical devices. Android has its own implementation for loading and rendering graphics.

Without knowing what you need BufferedImage for, it's hard to say what alternative you should be considering. Most likely you're trying to do some sort of image manipulation that involves getting access to the individual pixels of an image? If that's the case, have a look at the Bitmap and BitmapFactory classes.

It all boils down to Java SDK != Android SDK. Anyways, also consider doing a search here on SO; you're not the first one to make this mistake.

MH.
  • 45,303
  • 10
  • 103
  • 116
  • Thank you for this depressing but helpful answer. :) So Eclipse couldn't tell us, when using ADT to create an Android application, that importing the JRE or JDK as a resource will not work? Moreover, Eclipse has in its menu the option to "use Default JRE" in an Android application, but according to your answer this option will never work? – fasti Jan 04 '13 at 00:56
  • 1
    I suppose there is no such thing as using a specific "JRE in an Android application". Google created its own runtime environment (Dalvik) which is different from a standard JVM, although in some ways 'compatible'. Hence, Android is mainly based around Java as a programming language (syntax), but doesn't adopt the whole platform and all its features. There are some more differences outline [here](http://stackoverflow.com/a/390488/1029225) and [here](http://stackoverflow.com/a/11374587/1029225), if you're interested. – MH. Jan 04 '13 at 01:13
  • I see. Interesting. Thanx for the links. I would also recommend to anyone interested in the subject, reading about Dalvik in Wikipedia. So, would it be correct if I was to address the Eclipse developers and ask to remove the option of "use Default JRE" when coding **in an Android project**? (It could save many newbies a lot of time figuring this out. It took me 3 weeks... the shame...) – fasti Jan 04 '13 at 16:07
  • Well, the Java code you write will still need to be compiled to bytecode before being optimized into the dex format. From this compilation point of view, it probably makes sense to be able to choose whether you want to use e.g. version 1.5, 1.6 or 1.7 of `javac`. The *runtime environment* (what JRE really stands for) version, however, is rather meaningless in the context of Android, since it has its own runtime environment. The Eclipse devs probably can't be bothered with this, but you could try to get in touch with the ADT devs to suggest possible improvements. – MH. Jan 05 '13 at 21:32