Sunday, 2 August 2015

HTML5 Browser Apps with Java - TeaVM part 3

Continuing my trials with TeaVM, after establishing how to do some common tasks, it was time to try it out on a more substantial project.

As well as offering a developer-friendly way to create shiny new browser apps using Java, TeaVM also provides an opportunity for old client-side Java apps to be updated into the modern age. I turned to some of my existing Java software that would benefit from being ported into modern, HTML5-compatible browser applications. A perfect example is old code that was originally a Java Applet - from over 15 years ago! Of course, the user interfaces for web and client-side Java are significantly different, so these parts would need to be re-written. But hopefully the task would be made much easier by the fact the much of the core logic could hopefully remain intact.

Some time ago I wrote about how existing client-side Java code could be ported to Android. TeaVM offers the possibility of something similar by making it easy to port Java apps to the browser. In fact, with Java being the common starting point, it's possible to have an app on multiple different platforms - native Java, Android, and Web, using the same core code, with platform-dependent differences only for the UI elements.

Here is such an example - a simple arcade style game called Super Bunny. Originally written as a Java applet, I ported it to Android in around 2010. So the question is, would it be possible using TeaVM to now port it to HTML5/Javascript? The answer turned out to be a definite Yes, and here it the proof:
Play the Web version created using TeaVM

The game logic code was almost entirely re-usable, and is shared by the original applet, the Android version, and now the Web version too. Although re-writing the GUI was tricky in places, many of these problems stem from limitations in Javascript itself, such as lack of good multithreading or inbuilt resource management. It's fair to say, I did come across a number of bugs or missing features in TeaVM itself, but that's to be expected for a project still in its early stages. Having reported these back to the TeaVM developers, I found they were quickly fixed or workarounds suggested, and so progress with my trial was nevertheless rapid.

All in all I am satisfied with the results of my experiments with TeaVM. I recommend it to the Java developers out there that would like to do client-side web development but have an aversion to writing native Javascript. It has the potential to displace older, competing technologies like GWT, and I look forward to seeing how the project progresses. Nice work TeaVM Team!

Monday, 13 July 2015

HTML5 Browser Apps with Java - TeaVM part 2

I took an initial look at TeaVM - a technology for developing HTML5/Javascript web applications using Java as the development language. The first signs were promising - it was easy to get started, and the learning curve looked to be a fairly shallow one for any developers who are already familiar with Java.

The next task was to determine how easy it would be to develop real applications. That means knowing how to implement commonly needed application features: creating a user interface, responding to user actions, loading data, and manipulating on-screen elements. To that end, here are some of code examples to illustrate how to do common tasks...

1. Handling user interface events
<button id="myButton">Click Me</button>
HTMLButtonElement myButton = (HTMLButtonElement) 
    myButton.addEventListener("click", new EventListener<Event>() {
    public void handleEvent(Event evt) {
        //button was clicked
2. Loading an image
HTMLImageElement imgElt = (HTMLImageElement)
imgElt.addEventListener("load", new EventListener<Event>() {
    public void handleEvent(Event evt) {
        //loaded image successfully
imgElt.addEventListener("error", new EventListener<Event>() {
    public void handleEvent(Event evt) {
        //failed to load image
3. Displaying an image
HTMLCanvasElement canvasElement = (HTMLCanvasElement)
CanvasRenderingContext2D context = (CanvasRenderingContext2D)canvasElement.getContext("2d");
context.drawImage(imgElt, posx, posy, width, height);

For a web application, the user interface is of course defined in HTML, so in the Java code we simply need to get handles of the existing elements (Example 1), or create them on the fly (Example 2). The classes HTMLButtonElement, EventListener, HTMLCanvasElement, CanvasRenderingContext2D and HTMLImageElement are all provided by TeaVM. If you are familiar with Javascript, you'll recognise the similarity. But of course being Java, you get the benefit of strongly-typed classes, which aid with clarity and help reduce bugs.

Another elegant feature of TeaVM is the ability to extend it if you need to use Javascript features that may be missing or not yet implemented. For example, I wanted to make use of Javascript's toFixed() method to format decimal numbers. TeaVM does not provide direct access to this function via its own APIs, but does provide a method to access arbitrary Javascript using a mechanism called JSO. It works using Java annotations to declare Javascript references, like this:
import org.teavm.jso.JSBody;

public class JSFormatter {
    @JSBody(params = { "f", "n" }, script = "return f.toFixed(n);")
    public static native String toFixed(float f, int n);
I'll write up my conclusions on TeaVM in the next article.

Thursday, 18 June 2015

HTML5 Browser Apps with Java - TeaVM part 1

Let's take a moment reminisce about the late 1990s... Probably the first thing you thought of wasn't Java Applets! But there was a brief period back then where Java was the new and exciting language and one of the cool things you could do was create Java Applets - self contained programs that could be embedded in a web page.

But the glory days of Applets are long gone. While Java went from strength to strength for server-side development, the technology acquired a bad reputation on the client-side - especially for browser-based applets. Problems of perceived slowness, the need to download the large Java plugin, numerous security concerns, and competition from competing technologies such as Flash, saw Java Applets quickly fall into technological obscurity.

These days the preferred way of creating browser-based apps is using HTML5 and the associated goodies - JavaScript and canvas element. While this means a better and more secure user experience, it does present a problem if you want to develop such apps as a Java developer. If you are used to Java with its strong Object Orientation, static types, and excellent development environments, programming in JavaScript seems by comparison awkward and developer-unfriendly.

In an ideal world there would be a convenient way of developing in Java, but produce code that runs as client-side, HTML5 browser applications. The good news is: Now at last there is.

There are now several Java-to-JavaScript compilers on the scene, and so recently I started to take a look at them. The one I am particularly impressed with is TeaVM. Another interesting one is Back2Brwsr.

Google Web Toolkit, a similar technology in some respects, has been around for a while. But my experience with it was disappointing. It was awkward to use - requiring source code of any Java libraries you need to use, additional configuration for your included classes, and is slow to compile. The big benefit of these new generation of tools, is they work on compiled Java bytecode rather than source code, which makes them more convenient and easy to use, and faster to run too!

I decided to try out TeaVM a little, and to subjected it to the "10 minute test" - is it possible to create something trivial but which demonstrates its basic capabilities, just within a 10 minute period? Making use of the provided maven archetype, I created a project template and loaded it into my IDE. No problems there. Then it became very easy to make use of TeaVM's intuitive system for Java code to HTML elements. I ended up with something like this:

HTML source
    <title>TeaVM Test</title>
    <script charset="utf-8" src="teavm/runtime.js" type="text/javascript"></script>
    <script charset="utf-8" src="teavm/classes.js" type="text/javascript"></script>
<body onload="main()">
    <canvas width="400" height="400" id="canvas" tabindex="0">

Java source
    private static Window window = (Window) JS.getGlobal();
    private static HTMLDocument document = window.getDocument();
    private static HTMLCanvasElement canvas = 
    public static void main(String[] args) {
         CanvasRenderingContext2D context = 
         context.fillText("Hello World!", 20, 20);

Using the provided maven tasks, TeaVM converts the compiled Java bytecode into JavaScript (the two files runtime.js and classes.js), and hey presto, a simple canvas "Hello World" program.

The ease with which it was possible to get started, combined with the simple, intuitive way to deal with HTML elements, including canvas, makes TeaVM look very promising. I'll look at it in more detail in the next article.