My understanding is that Google didn't like Oracle's licensing policy for using the JRE in Java ME so it just rewrote
it using its own JVM specification that mimics the JRE but behaves a little bit differently, especially when it comes
to making things more efficient and more secure.
So, if my understanding is correct, it means that when javac
is ran on some Java source code and compiled into "binary"
byetcode, a compliant JVM will interpret that bytecode different than Dalvik will (in some cases). This is the inherent
difference between Dalvik and other (compliant) JVMs.
If anything I have said so far is incorrect, please begin by correcting me!
Now, if Android came with its own compiler (which it might), and compiled Java source in a different (Dalvik-compliant)
manner than javac
, then I could understand how some code (not compiled with the Android SDK) would not run on an
Android device:
MySource.java --> javac --> MySource.class (JRE-compliant) --> JVM --> running Java app
MySource.java --> android-compiler --> MySource.class (Dalvik-compliant) --> Dalvik JVM --> running Android app
However, it looks like you use javac
to compile Android apps!?!? So it looks like we have this:
MySource.java --> javac --> MySource.class (JRE-compliant) --> JVM --> running Java app
MySource.java --> javac --> MySource.class (JRE-compliant) --> Dalvik JVM --> running Android app (???)
If javac
is used to compile all sources into bytecode, then why is it that Dalvik can't run some types
of Java code?
I asked a very similar question yesterday and although it was technically answered (after re-reading my question
I see I was simply not specific enough) no one was able to explain what it is that's inherent to Dalvik that
makes it impossible to run Java code from projects like Google Guice or Apache Camel. I was told that in order to get Camel to run on Dalvik, that I would have to get Camel's source and then it would have to be "built with the Android SDK", but I couldn't get clarity on what that meant or implied.
With Camel, for instance, you have this (simplified):
RouteBuilder.java --> javac --> RouteBuilder.class --> jartool --> camel-context-2.9.jar --> JVM --> running Camel ESB
RouteBuilder.java --> javac --> RouteBuilder.class --> jartool --> camel-context-2.9.jar --> Dalvik JVM --> doesn't work !!! (???)
Clearly, something is happening inside the Dalvik JVM that prevents it from running certain types of Java code.
I'm trying to understand what types of Java code will not run when "fed" into the Dalvik JVM.
Edit: In before "but Camel 3.0 will run on Android!" I know - not my question!
I'm trying to understand what types of Java code will not run when "fed" into the Dalvik JVM.
Dalvik JVM differs from other JVMs in following aspects:
It uses special DEX format for storing applications binaries vs. JAR
and Pack200 formats used by standard Java virtual machines. Google
claims that DEX results in smaller binaries than JAR. I think they
could use Pack200 with the same success, but they decided to go their
own way in this aspect
Dalvik JVM was optimized for running multiple JVM processes
simultaneously
Dalvik JVM uses register-based architecture vs. stack based
architecture of other JVMs with intent to speed up execution and
to reduce binary sizes
It uses its own instructions set (not a standard JVM bytecode)
One can run (if needed) several independent Android applications
within a single JVM process
Application execution can span across several Dalvik JVM processes
“naturally”. To support this it
adds:
Special object serialization mechanism based on Parcel and Parcelable
classes. Functionally it serves the same purpose as standard Java
Serializable, but results in smaller data footprint and is potentially more lenient towards differences in versions of classes
Special Android way to execute inter process calls (IPC) based on
Android Interface Definition Language (AIDL)
Until Android 2.2 Dalvik JVM did not support JIT compilation which
adversely impacted Android application performance. Adding it in 2.2
improves markedly execution speed for often used applications
If anything I have said so far is incorrect, please begin by correcting me!
Ummm, well...
The Dalvik VM has technical advantages over the Java VM for mobile environments, most notably aggressive use of copy-on-write memory sharing, so the entire VM and standard class library is shared among all Android SDK app processes, reducing the net per-process memory footprint. See user370305's answer (posted while I was wrapping this up) for more.
The bytecode from javac
is cross-compiled into Dalvik bytecode as part of the Android application build process. The Java VM cannot execute Dalvik bytecode any more than it can execute the output of /dev/random
; similarly, the Dalvik VM cannot execute Java bytecode.
Here is a blog post of mine from around two years ago that goes into additional points.
If javac is used to compile all sources into bytecode, then why is it that Dalvik can't run some types of Java code?
Because the javac
bytecode output is cross-compiled. The cross-compiler (dx
) handles a very specific flavor of javac
output, meaning that while it works with the classic javac
(what you would have gotten from java.sun.com) and OpenJDK for Java 1.5 and 1.6, it will not work with alternative compilers (e.g., GCJ) and, at minimum, will not work with any new bytecodes from Java 7.
no one was able to explain what it is that's inherent to Dalvik that makes it impossible to run Java code from projects like Google Guice or Apache Camel
Personally, I have never used Google Guice, though Roboguice works on Android. I had never heard of Apache Camel prior to your question and am rather confused to find that it is not a Java port of Perl. :-)
Any tools that do runtime JVM bytecode generation will not work on Android, simply because the cross-compiler is only available at compile-time, not run-time. Also, I am unfamiliar with the techniques used by runtime JVM bytecode-generating tools and how they get the JVM to execute that bytecode, and therefore I do not know if equivalent hooks exist in Android to have Dalvik run arbitrary chunks of Dalvik bytecode.
However, since you declined to specify exactly what "Java code from projects like Google Guice or Apache Camel" you are having problems with, and since I am not intimately familiar with those projects, it is difficult to comment further.
This picture from Android official document illustrate the build process of Android APK, it will help to understand the difference between java bytecode and dalvik executable.
![](https://www.manongdao.com/static/images/pcload.jpg)
Here I give an example to demonstrate some of the differences.
Hello.java
import java.io.*;
public class Hello {
public static void main(String[] args) {
System.out.println("hello world!!!!");
}
}
use javac
to compile Hello.java
to java bytecode Hello.class
$ javac Hello.java
Then use dx
tool from android sdk convert java bytecode Hello.class
to Hello.dex
$ $ANDROID_SDK_ROOT/build-tools/21.1.2/dx --dex --output=Hello.dex Hello.class
After that, use adb
to put Hello.class
and Hello.dex
to Android device or emulator.
$ adb push Hello.class /data/local/tmp/
$ adb push Hello.dex /data/local/tmp/
use adb shell
to enter the shell environment of Android device. Then use the command /system/bin/dalvikvm
to execute the simple java program we just created Hello.class
and Hello.dex
$ dalvikvm -Djava.class.path=./Hello.class Hello
java.lang.NoClassDefFoundError: Hello
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassNotFoundException: Didn't find class "Hello" on path: ./Hello.class
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:65)
at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
... 1 mor
$ dalvikvm -Djava.class.path=./Hello.dex Hello
hello world!!!!
In the example above, when we use the java bytecode Hello.class
, dalvikvm
complaint error, if we changed the class to dalvik executable Hello.dex
, it would run properly.
@alijandro, you explained very well on how dalvikvm can pnly execute .dex
byte code and not .class
byte code.
For the build process of Android APK picture you have attached what are the conventions used for the color coding and the figures? Can you please attach a reference ?