Run Dalvik on X86

很早以前就想过自己编译一个X86上的Dalvik出来玩玩,尝试之后没有成功,就放下了,最近几个月来又想起来搞搞,按照/PATH/TO/AOSP/dalvik/docs/hello-world.html来编译dalvikvm,创建dex档案,设置各种环境变量之后,运行出现错误

E/dalvikvm(10105): execv '/home/guohai/dev/src/android/git/aosp/out/target/product/generic_x86/system/bin/dexopt' failed: No such file or directory
W/dalvikvm(10102): DexOpt: --- END 'Foo.jar' --- status=0x0100, process failed
E/dalvikvm(10102): Unable to extract+optimize DEX from 'Foo.jar'
Dalvik VM unable to locate class 'Foo'
W/dalvikvm(10102): threadid=1: thread exiting with uncaught exception (group=0xf5a1d9c8)
java.lang.NoClassDefFoundError: Foo
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassNotFoundException: Didn't find class "Foo" on path: DexPathList[[zip file "Foo.jar"],nativeLibraryDirectories=[/home/guohai/dev/src/android/git/aosp/out/target/product/generic_x86/system/lib]]
    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:53)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
    ... 1 more

在网络上搜了很久没有出现过这种错误现象的,实在无赖提了个问题
在StackOverflow上,一个星期过去了,还是无人问津

最终请教了一个做Dalvik相关工作的同事,在他的帮助之下解决了问题

原来是我的ANDROID_ROOT写的有问题,可能是我没有理解好/PATH/TO/AOSP/dalvik/docs/hello-world.html的意思,也或者是它的内容比较陈旧。
后来改了就可以正常运行了,我改过的rund请参见https://gist.github.com/guohai/5048153

现在描述下主要过程
1. Download AOSP source code

2. Compile dalvik vm on Ubuntu 11.10 X64

source build/envsetup.sh
lunch 2 # choose full_x86-eng, because we want to run it on X86 directly
make dalvikvm core dexopt ext framework android.policy services

3. Compile Java code and package it to dex.

4. Run & enjoy it.

guohai@KNIGHT:~/dev/src/android/git/aosp$ ./rund -cp Foo.jar Foo
I/dalvikvm( 3473): DexOpt: mismatch dep name: '/home/guohai/dev/src/android/git/aosp/out/target/product/generic_x86/system/framework/core.odex' vs. '/system/framework/core.odex'
E/dalvikvm( 3473): /home/guohai/dev/src/android/git/aosp/out/target/product/generic_x86/system/framework/ext.jar odex has stale dependencies
I/dalvikvm( 3473): Zip is good, but no classes.dex inside, and no valid .odex file in the same directory
I/dalvikvm( 3473): DexOpt: mismatch dep name: '/home/guohai/dev/src/android/git/aosp/out/target/product/generic_x86/system/framework/core.odex' vs. '/system/framework/core.odex'
E/dalvikvm( 3473): /home/guohai/dev/src/android/git/aosp/out/target/product/generic_x86/system/framework/framework.jar odex has stale dependencies
I/dalvikvm( 3473): Zip is good, but no classes.dex inside, and no valid .odex file in the same directory
I/dalvikvm( 3473): DexOpt: mismatch dep name: '/home/guohai/dev/src/android/git/aosp/out/target/product/generic_x86/system/framework/core.odex' vs. '/system/framework/core.odex'
E/dalvikvm( 3473): /home/guohai/dev/src/android/git/aosp/out/target/product/generic_x86/system/framework/android.policy.jar odex has stale dependencies
I/dalvikvm( 3473): Zip is good, but no classes.dex inside, and no valid .odex file in the same directory
I/dalvikvm( 3473): DexOpt: mismatch dep name: '/home/guohai/dev/src/android/git/aosp/out/target/product/generic_x86/system/framework/core.odex' vs. '/system/framework/core.odex'
E/dalvikvm( 3473): /home/guohai/dev/src/android/git/aosp/out/target/product/generic_x86/system/framework/services.jar odex has stale dependencies
I/dalvikvm( 3473): Zip is good, but no classes.dex inside, and no valid .odex file in the same directory
I/dalvikvm( 3473): DexOpt: source file mod time mismatch (4244043d vs 425baf6a)
Hello, Dalvik!

一些对我有些帮助的资料
http://stackoverflow.com/questions/6146983/helloworld-cannot-run-under-dalvikvm
http://stackoverflow.com/questions/11773506/how-to-launch-jar-with-exec-app-process-on-android-ics
http://blog.csdn.net/johnnynuaa/article/details/6543425

附上自己无法运行的启动脚本

#!/bin/sh

# base directory, at top of source tree; replace with absolute path
base=`pwd`

# configure root dir of interesting stuff
root=$base/out/target/product/generic_x86/system
export ANDROID_ROOT=$root #为什么这里不能指到target的路径?

export LD_LIBRARY_PATH=$root/lib:$LD_LIBRARY_PATH

# configure bootclasspath
bootpath=$root/framework
export BOOTCLASSPATH=$bootpath/core.jar:$bootpath/ext.jar:$bootpath/framework.jar:$bootpath/android.policy.jar:$bootpath/services.jar

# this is where we create the dalvik-cache directory; make sure it exists
export ANDROID_DATA=/tmp/dalvik_$USER
mkdir -p $ANDROID_DATA/dalvik-cache

exec $base/out/host/linux-x86/bin/dalvikvm -Xdexopt:none $@

22 thoughts on “Run Dalvik on X86”

  1. hi, friend,

    I also tried this by using your script. But it does not work. The error info is as follows:

    I/dalvikvm(28100): DexOpt: mismatch dep name: ‘/home/K/Android22/out/target/product/generic_x86/system/framework/core.odex’ vs. ‘/system/framework/core.odex’
    E/dalvikvm(28100): /home/K/Android22/out/target/product/generic_x86/system/framework/ext.jar odex has stale dependencies
    I/dalvikvm(28100): Zip is good, but no classes.dex inside, and no valid .odex file in the same directory
    I/dalvikvm(28100): DexOpt: mismatch dep name: ‘/home/K/Android22/out/target/product/generic_x86/system/framework/core.odex’ vs. ‘/system/framework/core.odex’
    E/dalvikvm(28100): /home/K/Android22/out/target/product/generic_x86/system/framework/framework.jar odex has stale dependencies
    I/dalvikvm(28100): Zip is good, but no classes.dex inside, and no valid .odex file in the same directory
    I/dalvikvm(28100): DexOpt: mismatch dep name: ‘/home/K/Android22/out/target/product/generic_x86/system/framework/core.odex’ vs. ‘/system/framework/core.odex’
    E/dalvikvm(28100): /home/K/Android22/out/target/product/generic_x86/system/framework/android.policy.jar odex has stale dependencies
    I/dalvikvm(28100): Zip is good, but no classes.dex inside, and no valid .odex file in the same directory
    I/dalvikvm(28100): DexOpt: mismatch dep name: ‘/home/K/Android22/out/target/product/generic_x86/system/framework/core.odex’ vs. ‘/system/framework/core.odex’
    E/dalvikvm(28100): /home/K/Android22/out/target/product/generic_x86/system/framework/services.jar odex has stale dependencies
    I/dalvikvm(28100): Zip is good, but no classes.dex inside, and no valid .odex file in the same directory
    Dalvik VM unable to locate class ‘hello’
    W/dalvikvm(28100): threadid=1: thread exiting with uncaught exception (group=0xf66fcb48)
    java.lang.NoClassDefFoundError: hello
    at dalvik.system.NativeStart.main(Native Method)
    Caused by: java.lang.ClassNotFoundException: Didn’t find class “hello” on path: DexPathList[[],nativeLibraryDirectories=[]]
    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:53)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
    … 1 more

    My script is as follows:

    #!/bin/sh

    # base directory, at top of source tree; replace with absolute path
    base=`pwd`

    # configure root dir of interesting stuff
    root=$base/out/host/linux-x86
    export ANDROID_ROOT=$root

    # configure bootclasspath
    bootpath=$base/out/target/product/generic_x86/system/framework

    export BOOTCLASSPATH=$bootpath/core.jar:$bootpath/ext.jar:$bootpath/framework.jar:$bootpath/android.policy.jar:$bootpath/services.jar

    export LD_LIBRARY_PATH=$bootpath/lib:$LD_LIBRARY_PATH

    # this is where we create the dalvik-cache directory; make sure it exists
    export ANDROID_DATA=/tmp/dalvik_$USER
    mkdir -p $ANDROID_DATA/dalvik-cache

    exec $root/bin/dalvikvm -Xdexopt:none -cp hello.jar hello

    Can you give me some suggestions? Thanks a lot!

  2. Thanks for your reply. I built the dalvik and some core libraries by using the command “make dalvikvm core dexopt ext framework android.policy services”. The following is the system info.

    PLATFORM_VERSION_CODENAME=AOSP
    PLATFORM_VERSION=4.2.2.2.2.2.2.2.2.2
    TARGET_PRODUCT=full_x86
    TARGET_BUILD_VARIANT=eng
    TARGET_BUILD_TYPE=release
    TARGET_BUILD_APPS=
    TARGET_ARCH=x86
    TARGET_ARCH_VARIANT=x86
    TARGET_CPU_VARIANT=
    HOST_ARCH=x86
    HOST_OS=linux

    1. I have tried your launch script, on Android 4.1, it is okay.
      so far on Android 4.2, I meet another problem(dalvik vm can not launch successfully):
      E/dalvikvm(19824): dlopen(“libjavacore.so”) failed: /home/guohai/dev/src/android/git/aosp/out/host/linux-x86/bin/../lib/../lib/libjavacore.so: undefined symbol: ucol_countAvailable_49
      E/dalvikvm(19824): dvmLoadNativeCode failed for “javacore”: /home/guohai/dev/src/android/git/aosp/out/host/linux-x86/bin/../lib/../lib/libjavacore.so: undefined symbol: ucol_countAvailable_49
      E/dalvikvm(19824): VM aborting

      I’m still checking on this.

      so maybe you could test it on Android 4.1 first, and then switch to Android 4.2 to try. sorry…

      1. Thanks.

        I also met this problem. We can solve it by using “make”. After we “make” everything, we could have “libjavacore.so”.

        1. Hi Ke
          Thanks for your suggestion, I have tested on 4.2. It works okay for me. That’s so strange. Would you like to remove your own script and just use this https://gist.github.com/guohai/5048153 for test, re-login system before executing rund script(to drive out the environment variables existing in current session).
          BTW have you made sure that dex file is okay?

  3. Thanks.

    I just used your script but it seemed not work. The dex file is OK since it could run normally in an emulator.

    I will try Android 4.0. Thanks again.

      1. Sure. I will try 4.2 later. If some clues are found, I’d be very happy to share with you. And you know my email. So we can still discuss Android through email.

    1. Hi Leon
      so far I haven’t try it on 2.3.
      maybe you can try to use core dump to narrow down the root cause.
      I get your post on Google Groups. ^_^

  4. 请问一下,虽然你提供的运行程序,只是Hello world,但是这是不是意味着你可以直接在Ubuntu上面不通过模拟器,而是通过你自己的dalvik运行安卓程序了?

    1. 确实是有这样的,比如http://software.intel.com/en-us/articles/android-4-2-jelly-bean-x86-emulator-system-image或者http://www.android-x86.org/或者http://smlsun.com/blog/2013/01/16/android-vm/,但是我这里的不行,一个完整的程序运行会调用到很多服务,操作系统会运行很多进程,我这里不能满足。

      1. 谢谢你,因为听说安卓又合并回到linux分支了,所以我一直梦想可以在linux下使用安卓的各种程序了呢,看来还不太行呀.

  5. 不知道你说的这个问题解决没:
    E/dalvikvm(19824): dlopen(“libjavacore.so”) failed: /home/guohai/dev/src/android/git/aosp/out/host/linux-x86/bin/../lib/../lib/libjavacore.so: undefined symbol: ucol_countAvailable_49
    E/dalvikvm(19824): dvmLoadNativeCode failed for “javacore”: /home/guohai/dev/src/android/git/aosp/out/host/linux-x86/bin/../lib/../lib/libjavacore.so: undefined symbol: ucol_countAvailable_49
    E/dalvikvm(19824): VM aborting
    我也遇到了这个问题,我的步骤和你的是一样的,然后脚本也是一样的。我的版本是4.1,不知道你后来有没有找到原因呢?然后我对LD_LIBRARY_PATH有点疑问,export LD_LIBRARY_PATH=$bootpath/lib:$LD_LIBRARY_PATH,按照脚本中的配置LD_LIBRARY_PATH应该是/out/target/product/generic_x86/system/framework/lib文件,但是我的out目录中并不存在这个路径,只有/out/target/product/generic_x86/system/lib,不知道是不是编译后的输出不一样呢?

      1. 解决了,确实要make整个系统,还和binutils的版本有一些关系(要求是2.22),另外我使用的LD_LIBRARY_PATH的配置是/out/target/product/generic_x86/system/lib

    1. AOSP是按照模块编译的,有可能有些模块没有编译到,所以就没有生成对应的文件夹/文件,你检查下自己是不是这样子的

      1. 还是出现这个问题,我生成的模块就是你上面的说的这几个:dalvikvm core dexopt ext framework android.policy services,不知道是为什么呢。我的lunch 2之后是:
        PLATFORM_VERSION_CODENAME=REL
        PLATFORM_VERSION=4.1.1
        TARGET_PRODUCT=full_x86
        TARGET_BUILD_VARIANT=eng
        TARGET_BUILD_TYPE=release
        TARGET_BUILD_APPS=
        TARGET_ARCH=x86
        TARGET_ARCH_VARIANT=x86-atom
        HOST_ARCH=x86
        HOST_OS=linux
        HOST_OS_EXTRA=Linux-2.6.32-38-generic-x86_64-with-Ubuntu-10.04-lucid
        HOST_BUILD_TYPE=release
        BUILD_ID=JRO03R
        OUT_DIR=out
        不是你们的AOSP呢,不知道这个是否有影响?

        1. 整个系统clean build就是直接make,后面不带参数,你这是指定编译些模块,那个缺的lib不是在这些模块当中,所以会出错,最简单的方法就是make -jX,然后你再去看就有那个lib了

Leave a Reply

Your email address will not be published. Required fields are marked *