JavaPoly.js

Technical Details

Introduction

This document is intended to give the technical background and usage details for JavaPoly.js. The topics discussed assume familiarity with the library; if you are looking for a getting started guide, you should head over to www.javapoly.com

JavaPoly Motivation

JavaScript was originally developed in 10 days in May 1995 by Brendan Eich, while he was working for Netscape Communications Corporation. It was a high-level, very dynamic, untyped, and interpreted programming language. The language was integrated into Netscape, and usage grew rapidly. The language is now being standardized by TC-39, but the javascript language is still tied down by the early lack-of-design decisions which are difficult to undo due to widespread usage.

If the language were designed from scratch today, the specification would probably look much more similar to modern-day Java. In fact, TC-36 is working very hard to add support for basic features like ES6 classes (java classes), arrow functions (lambda functions), web workers (threads), etc. While these efforts to improve javascript are good, the efforts are largely hampered by requirements to maintain backwards compatibility with the early (poor) design decisions.

Other efforts (like typescript and flow) attempt to add type checking to the language. Unfortunately, the very dynamic nature of javascript makes it super hard to write large/sophisticated applications, and even harder to optimize the code once it's written.

It turns out, these are all problems which have already been solved within the JVM. The problem is, the JVM has historically been restricted to an isolated/sandboxed container known as an applet. This sandboxing made it difficult to perform even basic operations like manipulating the DOM, and ultimately lead to the downfall of Java within the browser.

However, there is a solution! Native support for Java within the browser! JavaPoly allows javascript engineers to easily call into Java libraries and thereby opens access to an entire ecosystem of advanced libraries and tooling.

JavaPoly Alternatives

JavaPoly is both a specification and a reference implementation. The specification is intended to be implemented by Chrome and Firefox, with other browsers to follow. The JavaPoly spec may be implemented in addition to (or in place of) other proposals.

The most prominent alternatives are:

64-bit long integers

Java supports 64-bit long integers, but Javascript (as of the latest language specification) does not support them. This means that if a Java function returns a 64-bit long, there is currently no way to represent that as a numeric type in Javascript. Until javascript supports longs, attempting to pass a large long from Java into javascript will throw an exception.

The easiest way to work around this limitation is to have your Java code convert the long into a primitive representable in Javascript. You can use Long.doubleValue() to get a numeric approximation, or use Long.toString() to get a string representation without loss of precision.

If you are calling a third-party library that returns an unboxed long, you will need to write a wrapper function in Java that calls the third-party function and returns your preferred javascript representation. The wrapper-function strategy also works when invoking functions which take a primitive long as an argument.

Java Classes using JavaPoly.type()

JavaPoly attempts to polyfill the usage of Java classes referenced by their fully-qualified name. However, this polyfill relies on Proxy objects, which were only recently introduced into the Javascript language specification and are not yet supported by all browsers. Furthermore, the polyfill is unable to make some packages (including the default package) available until after the contents of that package has been loaded into the JVM (an asynchronous operation, subject to race conditions).

For these reasons, the most reliable technique is to access classes using `JavaPoly.type('com.yourpackage.YourClass')`, which returns a promise to provide the requested class.

Browsers which natively support the JavaPoly specification can safely reference Java classes by directly referencing classes using their fully-qualified name, but until there is widespread support for this technique, using JavaPoly.type(...) is the recommended method of referencing classes when targeting legacy browsers.

Same Origin Policy

Polyfills are bound by the browser's same-origin policy, which restricts the plugin's ability to load libraries from remote hosts/protocols. If you run into an issue loading remote java files, consider setting the appropriate CORS headers (like `Access-Control-Allow-Origin: *`) on the remote server.

Initializing Multiple JVMs

By default, JavaPoly starts a single JVM for your website. However, it is sometimes useful to explicitly start your own JVMs (so you can have multiple JVMs for process isolation, or because you want to start the JVM using non-default configuration options).

Off the Main Thread

By default, JavaPoly starts in the main javascript context, because it's the most convenient. But depending on the constraints of your application, it is often better to run the JVM in a separate process/thread. Users do not need to have Java installed to use this feature.

Advantages of running in a separate thread/context:

Disadvantages of running in a separate thread/context:

Running in the System JVM

By default, JavaPoly uses a javascript implementation of the JVM. This allows JavaPoly to run even if the user doesn't have Java installed on their computer. However, the System JVM is usually able to provide better performance and more advanced features (like WeakReferences and unsandboxed network connections). For this reason, it is sometimes desirable to use the System JVM. Running in the System JVM requires that you run outside the main Javascript context (see section above). It also requires that the user has Java installed on their computer.

Contributing to JavaPoly

JavaPoly is completely open source, and contributions are welcomed. The source code is available at git.javadeploy.net/jimsproch/JavaPoly. JavaPoly utilizes the Doppio JVM, and engineers interested in contributing are encouraged to check out the Doppio source code. If you are interested in contributing to JavaPoly, the best way to get your feet wet is with the doppio starter task.