Shipping J2V8 as an AAR

Shipping J2V8 as an AAR

We built J2V8 to bring highly performant JavaScript to Java in general, and to the Android platform in particular. By exposing Google’s V8 JavaScript API in Java, developers can now embed V8 into their Java applications on Windows, Linux, MacOS and Android. The approach has worked very well both for Tabris.js as well as many other consumers of J2V8.

The hardest technical challenge we faced while building J2V8 was not bridging the different technologies, but rather picking the right native bits at runtime. In order to support a variety of platforms (including 64 and 32 bit Windows, Linux, MacOS, and several different Android architectures) we developed a library loader that would pick the proper native library based on current architecture. The correct library would be unpacked and dynamically loaded. We developed this to make consuming J2V8 much easier, but we quickly learned that the road to hell is paved with good intentions.

LoadLibrary

The System.loadLibrary() method on Android will load a library from a number of predefined locations, however, none of these locations are writeable at runtime. The System.load() method, which allows you to load a library given an absolute path, does not work in many cases. To solve this, consumers of J2V8 needed to manually extract the native libraries from our jar and include them in the correct jniLibs directory within their own apk. This was complicated, error prone and would often result in duplicate copies of the same native library in your final apk.

To solve this problem, we’ve changed the way J2V8 is packaged for Android. Instead of shipping J2V8 as a jar with a smart library loader, we now ship J2V8 as an aarAnd aar is a binary distribution of an Android Library Project. An aar file can contain both a jar as well as resources. In our case, j2v8-3.1.0-SNAPSHOT.aar contains the Java bindings as well as pre-built native bits for Android ARM and x86. If you consume this library in your build, the native bits will be assembled into the right locations at build time, making the library loading much easier.

Usage

To use J2V8 in your Android application, simply add the following to your build.gradle file.

<pre lang="gradle">dependencies {
    compile 'com.eclipsesource.j2v8:j2v8:3.1.0-SNAPSHOT@aar'
}
</pre>

This is currently available in 3.1.0-SNAPSHOT. You will need to consume this from the maven snapshot repository https://oss.sonatype.org/content/repositories/snapshots. You can also consume it in Maven projects with the following pom dependency:

<pre lang="xml">
<dependency>
  <groupId>com.eclipsesource.j2v8</groupId>
  <artifactId>j2v8</artifactId>
  <version>3.1.0-SNAPSHOT</version>
  <type>aar</type>
</dependency>
</pre>

With this change, there is no need to provide a location to extract the native libraries when creating the V8Runtime.

A special thanks goes to my colleague Moritz Post who did the hard work of creating the gradle build for J2V8.

If you’re working with J2V8 on Android, please give this new format a try and let me know if it works. If things are working well, I’ll publish a 3.1.0 final.

For J2V8 information, and Java to JavaScript tips & tricks, follow me on Twitter.

5 Comments
  • Andrew Kirmse
    Posted at 02:38, 2015-12-03

    Thanks for this library; we’re integrating it and it looks very easy to use compared to the alternatives. Two questions:

    – The library is quite large; our APK has gone from 2M with Rhino to 30M with J2V8. In JavascriptCore, ICU was the culprit: https://github.com/appcelerator/hyperloop/wiki/Shrinking-JavaScriptCore . Any plans to look into the size?

    – The included version of V8 is years old. Is there any thought of moving to a more recent version?

    Feel free to email me.

  • DanV
    Posted at 20:27, 2015-12-09

    Hi,
    Will it work on devices like Nexus 5x running on armv8 abi and above?
    or old devices running armv5 abi?

    Thank you,
    Dan.

  • DanV
    Posted at 09:44, 2015-12-10

    The question is whether the .so file in the armv7 folder will work for armv5 devices and whether non armv7 devices will look for the .so in the armv7 folder..