Android Platform Implementation Details
The JDK 9 Android port supports both x86 and arm execution on Android emulators or devices. The x86 implementation uses the standard Hotspot JIT but the ARM 32-bit implementation is restricted to the Zero interpreter.
Build Requirements
Build machine
The Android JDK 9 build requires a 64-bit Linux System capable of running the Android NDK and SDK binaries.
Android NDK & SDK
Our JDK 9 Mobile project requires the Android NDK and SDK which can be downloaded from Android developer site. When downloading the SDK, select the Linux package from the "SDK Tools Only" section. The sources can currently be built using NDK version r10e and compiling for API level 19.
https://developer.android.com/sdk/index.html
Follow the instructions here for installing the Linux 64-bit (x86) Android NDK.
https://developer.android.com/ndk/guides/setup.html
Generating standalone toolchains for the builds
The dependent libraries and JDK build require a traditional standalone gnu toolchain to be available rather than the default layout of the Android NDK distribution. In addition, the JDK requires the toolchain to be in the form of a devkit. This amounts to having a devkit.info at the top directory of each required toolchain. Follow these instructions for this setup.
$HOME/jdk9mobile/android-ndk-r10b/build/tools/make-standalone-toolchain.sh \ --arch=arm \ --platform=android-19 \ --install-dir=$HOME/jdk9mobile/android-ndk-r10b/generated-toolchains/android-arm-toolchain Put the following three lines in a file named devkit.info in the generated toolkit DEVKIT_NAME="Android ARM" DEVKIT_TOOLCHAIN_PATH="$DEVKIT_ROOT/arm-linux-androideabi/bin" DEVKIT_SYSROOT="$DEVKIT_ROOT/sysroot" i $HOME/jdk9mobile/android-ndk-r10b/build/tools/make-standalone-toolchain.sh/build/tools/make-standalone-toolchain.sh \ --arch=x86 \ --platform=android-19 \ --install-dir=$HOME/jdk9mobile/android-ndk-r10b/generated-toolchains/android-x86-toolchain Put the following three lines in a file named devkit.info in the generated toolkit DEVKIT_NAME="Android X86" DEVKIT_TOOLCHAIN_PATH="$DEVKIT_ROOT/i686-linux-android/bin" DEVKIT_SYSROOT="$DEVKIT_ROOT/sysroot" For more information, please refer to this URL: http://developer.android.com/ndk/guides/standalone_toolchain.html
libffi (required for ARM builds only)
The Zero interpreter used in our Android arm port requires a third party library for calling native functions. This library is libffi (Foreign Function Interface Library). We are currently working with version 3.2.1 of this library.
The libffi 3.2.1 sources can be downloaded from here:
https://sourceware.org/libffi/
Download the bundle and untar it to a working directory, "cd" into that directory and then execute the following commands:
# !/bin/csh # # I coulnd't get the --prefix=`pwd`/build_android-arm to cause the include # and lib to show up in ./build_android-arm. The build copied the lib # but not the includes. The current prefix is the default location for # generated binaries which already included the header files so I # just linked the directory name I wanted. # # Customize the following paths to match your setup # setenv ANDROID_DEVKIT $HOME/jdk9mobile/android-ndk-r10b/generated-toolchains/android-arm-toolchain setenv PATH $ANDROID_DEVKIT/bin:$PATH # bash configure --host=arm-linux-androideabi --prefix=`pwd`/arm-unknown-linux-androideabi make clean make make install rm build_android-arm ln -s arm-unknown-linux-androideabi build_android-arm
The "make install" will build the library and populate the include and lib directories in build_android-arm with the built libffi library artifacts needed to build the JDK.
libfreetype
The FreeType 2.6.2 sources can be downloaded from here:
http://freetype.org/download.html
To build an Android x86 distribution, download the sources, cd to the top directory and run these commands:
# !/bin/csh # # Customize the following paths to match your setup # setenv ANDROID_DEVKIT $HOME/jdk9mobile/android-ndk-r10b/generated-toolchains/android-x86-toolchain setenv PATH $ANDROID_DEVKIT/bin:$PATH # ./configure --host=i686-linux-android \ --prefix=`pwd`/build_android-i686 \ --without-zlib \ --with-png=no \ --with-harfbuzz=no make clean make make install
The output of the build will be stored in the build_android-i686 directory
To build an Android arm distribution, run these commands:
# !/bin/csh # # Customize the following paths to match your setup # setenv ANDROID_DEVKIT $HOME/jdk9mobile/android-ndk-r10b/generated-toolchains/android-arm-toolchain setenv PATH $ANDROID_DEVKIT/bin:$PATH # bash configure \ --host=arm-linux-androideabi \ --prefix=`pwd`/build_android-arm \ --without-zlib \ --with-png=no \ --with-harfbuzz=no make clean make make install
The output of the build will be stored in the build_android-arm directory
Building the JDK
Once you have the required tools and libraries built, download the mobile/dev sources, customize the build commands below to match your build system setup and run the build script.
Downloading the sources
hg clone http://hg.openjdk.org/mobile/dev mobile-dev cd mobile-dev sh get_source.sh
Build command for x86
# !/bin/csh # # Customize the following paths to match your setup # setenv FREETYPE_DIR $HOME/jdk9mobile/freetype-2.6.2/build_android-i686 setenv CUPS_DIR $HOME/jdk9mobile/cups/include setenv ANDROID_DEVKIT $HOME/jdk9mobile/android-ndk-r10b/generated-toolchains/android-x86-toolchain # cd mobile-dev bash configure \ --enable-option-checking=fatal \ --build=x86_64-unknown-linux-gnu \ --host=i686-linux-android \ --target=i686-linux-android \ --disable-warnings-as-errors \ --enable-headless-only \ --with-jdk-variant=normal \ --with-jvm-variants=client \ --with-cups-include=$CUPS_DIR \ --with-devkit=$ANDROID_DEVKIT \ --with-debug-level=release \ --with-freetype-lib=$FREETYPE_DIR/lib \ --with-freetype-include=$FREETYPE_DIR/include/freetype2 cd build/android-x86-normal-client-release make images
Build command for arm
# !/bin/csh # # Customize the following paths to match your setup # setenv FREETYPE_DIR $HOME/jdk9mobile/freetype-2.6.2/build_android-arm setenv CUPS_DIR $HOME/jdk9mobile/cups/include setenv ANDROID_DEVKIT $HOME/jdk9mobile/android-ndk-r10b/generated-toolchains/android-arm-toolchain setenv LIBFFI_DIR $HOME/jdk9mobile/libffi-3.2.1/build_android-arm cd mobile-dev bash configure \ --enable-option-checking=fatal \ --build=x86_64-unknown-linux-gnu \ --host=arm-linux-androideabi \ --target=arm-linux-androideabi \ --disable-warnings-as-errors \ --enable-headless-only \ --with-jdk-variant=normal \ --with-jvm-variants=zero \ --with-libffi-include=$LIBFFI_DIR/include \ --with-libffi-lib=$LIBFFI_DIR/lib \ --with-cups-include=$CUPS_DIR \ --with-devkit=$ANDROID_DEVKIT \ --with-debug-level=release \ --with-freetype-lib=$FREETYPE_DIR/lib \ --with-freetype-include=$FREETYPE_DIR/include/freetype2 cd build/android-arm-normal-zero-release make images
Running your built Java 9 binaries on Android
Make sure you have the Android SDK tools and platform-tools directory on your path.
# Create a 32-bit ARM AVD and then startup the Android emulator. Skip this step if you intend on running Java on Android ARM devices. emulator64-arm -avd {your_arm_avd} # Push the Java JRE binaries to the emulator cd mobile-dev/build/android-arm-normal-zero-release/images adb push jre /data/app/jre # run a shell on the emulated device adb shell # Setup an environment variable required to run Java setenv LD_LIBRARY_PATH /data/app/jre/lib/arm/jli:/data/app/jre/lib:/data/app/jre/lib/arm/server:$LD_LIBRARY_PATH cd /data/app/jre/bin # Run Java ./java -Djava.home=/data/app/jre -version OpenJDK Runtime Environment (build 9-internal+0-2016-01-26-135852.bvandett.mobile-dev) OpenJDK Zero VM (build 9-internal+0-2016-01-26-135852.bvandett.mobile-dev, interpreted mode)
Known Issues
1. If you get a message that the binary can't be run due to PIE issues, the JDK build needs to have some additional CFLAGS (-fPIE -pie) added to produce compatible binaries. This issue appears to only impact the "java" executable and does not impact shared libraries. Also, this issue only impacts newer Android running API level 21 or newer.