Dienstag, 23. Oktober 2012

Dalvik "Hello World" on Harmattan (in a chroot)

Here's a quick and boring tutorial on how to get a Java "Hello World" application running on the Dalvik VM of Nitdroid within Harmattan. This requires the Nitdroid Open Mode Kernel (might or might not work with Inception), all Nitdroid files and a bit of patience. This might brick your device or worse, and require a reflash at best. As you can see from the screenshot below, it's not that exciting ;)
  1. If you want to avoid the Open Mode Warning on each boot, remove the disclaimer from the cal area (this can only be done while in closed mode, as the cal area becomes read-only when flashing open mode until closed mode is re-flashed. This is also the reason why you can't set a device lock code in open mode - the lock code is saved in the cal area) - this is an optional step, and just a cosmetic fix.
  2. Flash the Nitdroid Open Mode Kernel (be sure to read the "Known limitations" on that post) - this works both on the N950 and N9.
  3. Boot into Harmattan open mode and replace the preinit script to allow booting into Nitdroid (again, read and understand the warnings on that post)
  4. Then, download a Nitdroid tarball (the latest is alpha 5, but I had better luck with alpha 4) and extract it to /home/nitdroid/ - the post explains the steps in great detail, including the kernel flashing and preinit replacement
  5. Reboot into Nitdroid (this might be optional, but do it just to check if your Nitdroid installation is working)
  6. Reboot into Harmattan again - the following commands are all carried out as root user inside Harmattan (using "devel-su")
  7. Bind mount /dev/ and /sys/ into Nitdroid:
    mount --bind /dev/ /home/nitdroid/dev/
    mount --bind /sys/ /home/nitdroid/sys/
  8. chroot into the Nitdroid hierarchy:
    /usr/sbin/chroot /home/nitdroid/
  9. Set some environment variables (not all of them might be needed, you can find them in "setup the global environment" of init.rc -- save these commands into "setupenv.sh" or something in /home/nitdroid/ and save yourself some typing):
    export PATH=/system/bin:/system/xbin:/usr/sbin:/usr/bin:/sbin:/bin
    export LD_LIBRARY_PATH=/system/lib
    export ANDROID_ROOT=/system
    export ANDROID_ASSETS=/system/app
    export ANDROID_DATA=/data
    export EXTERNAL_STORAGE=/mnt/sdcard
    export ASEC_MOUNTPOINT=/mnt/asec
    export LOOP_MOUNTPOINT=/mnt/obb
    export BOOTCLASSPATH=/system/framework/core.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/apache-xml.jar:/sys
  10. Start the Dalvik VM:
    / # /system/bin/dalvikvm
    Dalvik VM requires a class name
Ok, great - 10 steps to start the Dalvik VM, but I promised a Hello World. For that, you need the Android SDK (and the corresponding Java JDK) and follow the "Basic Dalvik VM Invocation" instructions (steps 1 to 6 on your host computer, from step 6 on your Harmattan device):
  1. With your favorite editor (mine is vim), create a file "Foo.java" with the following content:
    public class Foo {
        public static void main(String [] args) {
            System.out.println("Hello, world");
  2. Compile it:
    javac Foo.java
  3. Use the "dx" utility (from the Android SDK) to package the Foo.class (generated by javac) into a .jar
    dx --dex --output=foo.jar Foo.class
  4. Bonus exercise: "less" the foo.jar file to see its contents:
    % less foo.jar
    Archive:  foo.jar
     Length   Method    Size  Cmpr    Date    Time   CRC-32   Name
    --------  ------  ------- ---- ---------- ----- --------  ----
          72  Defl:N       70   3% 2012-10-23 15:51 1294a38f  META-INF/MANIFEST.MF
         732  Defl:N      404  45% 2012-10-23 15:51 b6e3654e  classes.dex
    --------          -------  ---                            -------
         804              474  41%                            2 files
  5. Copy this over to your Harmattan device (assuming USB Networking + Developer Mode + "user" access, "developer" should also work):
    scp foo.jar user@
  6. SSH into your Harmattan device, become root (devel-su) and copy the .jar file into the Nitdroid hierarchy:
    cp /home/user/foo.jar /home/nitdroid/
  7. chroot into Nitdroid again and set up the environment (see above)
  8. Finally, run Dalvik VM, telling it to run the class "Foo" and using a classpath of "foo.jar":
    / # /system/bin/dalvikvm -cp foo.jar Foo
  9. ...