1<html> 2<head> 3 <title>Basic Dalvik VM Invocation</title> 4</head> 5 6<body> 7<h1>Basic Dalvik VM Invocation</h1> 8 9<p> 10On an Android device, the Dalvik virtual machine usually executes embedded 11in the Android application framework. It's also possible to run it directly, 12just as you would a virtual machine on your desktop system. 13</p><p> 14After compiling your Java language sources, convert and combine the .class 15files into a DEX file, and push that to the device. Here's a simple example: 16 17</p><p><code> 18% <font color="green">echo 'class Foo {'\</font><br> 19> <font color="green">'public static void main(String[] args) {'\</font><br> 20> <font color="green">'System.out.println("Hello, world"); }}' > Foo.java</font><br> 21% <font color="green">javac Foo.java</font><br> 22% <font color="green">dx --dex --output=foo.jar Foo.class</font><br> 23% <font color="green">adb push foo.jar /sdcard</font><br> 24% <font color="green">adb shell dalvikvm -cp /sdcard/foo.jar Foo</font><br> 25Hello, world 26</code> 27</p><p> 28The <code>-cp</code> option sets the classpath. The initial directory 29for <code>adb shell</code> may not be what you expect it to be, so it's 30usually best to specify absolute pathnames. 31 32</p><p> 33The <code>dx</code> command accepts lists of individual class files, 34directories, or Jar archives. When the <code>--output</code> filename 35ends with <code>.jar</code>, <code>.zip</code>, or <code>.apk</code>, 36a file called <code>classes.dex</code> is created and stored inside the 37archive. 38</p><p> 39Run <code>adb shell dalvikvm -help</code> to see a list of command-line 40options. 41</p><p> 42 43 44 45<h2>Using a debugger</h2> 46 47<p> 48You can debug stand-alone applications with any JDWP-compliant debugger. 49There are two basic approaches. 50</p><p> 51The first way is to connect directly through TCP. Add, to the "dalvikvm" 52invocation line above, an argument like: 53</p><p> 54<code> -agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=y</code> 55</p><p> 56This tells the VM to wait for a debugger to connect to it on TCP port 8000. 57You need to tell adb to forward local port 8000 to device port 8000: 58</p><p> 59<code>% <font color="green">adb forward tcp:8000 tcp:8000</font></code> 60</p><p> 61and then connect to it with your favorite debugger (using <code>jdb</code> 62as an example here): 63</p><p> 64<code>% <font color="green">jdb -attach localhost:8000</font></code> 65</p><p> 66When the debugger attaches, the VM will be in a suspended state. You can 67set breakpoints and then tell it to continue. 68 69 70</p><p> 71You can also connect through DDMS, like you would for an Android application. 72Add, to the "dalvikvm" command line: 73</p><p> 74<code> -agentlib:jdwp=transport=dt_android_adb,suspend=y,server=y</code> 75</p><p> 76Note the <code>transport</code> has changed, and you no longer need to 77specify a TCP port number. When your application starts, it will appear 78in DDMS, with "?" as the application name. Select it in DDMS, and connect 79to it as usual, e.g.: 80</p><p> 81<code>% <font color="green">jdb -attach localhost:8700</font></code> 82</p><p> 83Because command-line applications don't include the client-side 84DDM setup, features like thread monitoring and allocation tracking will not 85be available in DDMS. It's strictly a debugger pass-through in this mode. 86</p><p> 87See <a href="debugger.html">Dalvik Debugger Support</a> for more information 88about using debuggers with Dalvik. 89 90 91 92<h2>Working with the desktop build</h2> 93 94<!-- largely lifted from 95http://groups.google.com/group/android-porting/browse_thread/thread/ab553116dbc960da/29167c58b3b49051#29167c58b3b49051 96--> 97 98<p> 99The Dalvik VM can also be used directly on the desktop. This is somewhat 100more complicated however, because you won't have certain things set up in 101your environment, and several native code libraries are required to support 102the core Dalvik libs. 103</p><p> 104Start with: 105 106<pre> 107 . build/envsetup.sh 108 lunch sim-eng 109</pre> 110 111You should see something like: 112 113<pre> 114 ============================================ 115 TARGET_PRODUCT=sim 116 TARGET_BUILD_VARIANT=eng 117 TARGET_SIMULATOR=true 118 TARGET_BUILD_TYPE=debug 119 TARGET_ARCH=x86 120 HOST_ARCH=x86 121 HOST_OS=linux 122 HOST_BUILD_TYPE=release 123 BUILD_ID= 124 ============================================ 125</pre> 126 127</p></p> 128This configures you to build for the desktop, linking against glibc. 129This mode is NOT recommended for anything but experimental use. It 130may go away in the future. 131</p></p> 132You may see <code>TARGET_BUILD_TYPE=release</code> or <code>=debug</code> 133or possibly nothing there at all. You may want to replace the 134<code>lunch</code> command with 135<code>choosecombo Simulator debug sim eng</code>. 136</p></p> 137Build the world (add a <code>-j4</code> if you have multiple cores): 138 139<pre> 140 make 141</pre> 142 143</p></p> 144When that completes, you have a working dalvikm on your desktop 145machine: 146 147<pre> 148 % dalvikvm 149 E/dalvikvm(19521): ERROR: must specify non-'.' bootclasspath 150 W/dalvikvm(19521): JNI_CreateJavaVM failed 151 Dalvik VM init failed (check log file) 152</pre> 153 154</p></p> 155To actually do something, you need to specify the bootstrap class path 156and give it a place to put DEX data that it uncompresses from jar 157files. You can do that with a script like this: 158 159<blockquote><pre> 160#!/bin/sh 161 162# base directory, at top of source tree; replace with absolute path 163base=`pwd` 164 165# configure root dir of interesting stuff 166root=$base/out/debug/host/linux-x86/product/sim/system 167export ANDROID_ROOT=$root 168 169# configure bootclasspath 170bootpath=$root/framework 171export BOOTCLASSPATH=$bootpath/core.jar:$bootpath/ext.jar:$bootpath/framework.jar:$bootpath/android.policy.jar:$bootpath/services.jar 172 173# this is where we create the dalvik-cache directory; make sure it exists 174export ANDROID_DATA=/tmp/dalvik_$USER 175mkdir -p $ANDROID_DATA/dalvik-cache 176 177exec dalvikvm $@ 178</pre></blockquote> 179 180</p></p> 181The preparation with <code>dx</code> is the same as before: 182 183<pre> 184 % cat > Foo.java 185 class Foo { public static void main(String[] args) { 186 System.out.println("Hello, world"); 187 } } 188 (ctrl-D) 189 % javac Foo.java 190 % dx --dex --output=foo.jar Foo.class 191 % ./rund -cp foo.jar Foo 192 Hello, world 193</pre> 194 195As above, you can get some info about valid arguments like this: 196 197<pre> 198 % ./rund -help 199</pre> 200 201</p></p> 202This also shows what options the VM was configured with. The sim "debug" 203build has all sorts of additional assertions and checks enabled, 204which slows the VM down, but since this is just for experiments it 205doesn't matter. 206 207</p></p> 208All of the above applies to x86 Linux. Anything else will likely 209require a porting effort. If libffi supports your system, the amount of 210work required should be minor. 211 212</p></p> 213<address>Copyright © 2009 The Android Open Source Project</address> 214 215</body> 216</html> 217