Browser Integration in Java Applications
When talking about combining Desktop and web applications today, you may possibly think of websites as rich internet apps such as Google Docs, which can be seamlessly integrated into your operating system as a browser app or extension. You probably don’t think of rich desktop applications with both a strong native desktop UI and a web based UI part.
We didn’t think of that either until one of our customer searched for a possibility to integrate our Java based GIS product Cadenza into an already existing Java Swing application, mainly to profit on its mature map visualization capabilities. With its integration framework, Cadenza Desktop (a Java Swing app on its own) is already providing the possibility to be used as platform: It allows to integrate custom Java application code as a part of it, which is comparable to browser plugins extending the functionality of the browser. It also provides the possibility to utilize a map viewer component in a custom Java application while using Cadenza as library.
Our challenge was the requirement of the customer to get a very lightweight Java application, which doesn’t need to load all libraries of Cadenza Desktop (which reflect about 1.4 million lines of code) into the memory of every client, while only using a small part of it (e.g. the map). Why not use our web pendant Cadenza Web instead and integrate its lightweight web appliction frontend into the customer’s Swing application?
TL;DR: We did some research about frameworks which can be used to integrate a browser into Java Swing applications for rendering a web application, such as Cadenza Web, and to interact with it.
What we were looking for
For the integration of websites in Java Swing applications, we need a browser of course. That browser, in form of a GUI component, must be integrable in existing applications. Such a component is realized as a direct or indirect implementation of java.awt.component and will cover a certain area of the application interface. Its purpose is to draw its frequently updating content — The rendered website — on that area to make it visible on the screen. This component is our basic requirement. To fulfill it we were looking for a tool (or more specific a framework) that provides us such component.
A GUI component is just one part – there are more requirements to be fulfilled. Some of those will be introduced in the following.
Interactivity
The component must allow the same interactions, which are required by the website that it renders. The map feature of Cadenza Web for instance integrates actions like panning, zooming and selecting objects on the map, as well as using GUI elements such as the toolbar or the interactive legend. Those actions introduce the need for the browser component to receive and forward input events like mouse clicks and keyboard keypresses to the website. From the viewpoint of the application, there may also be the need to satisfy OS relevant interactions, like downloading a file or utilizing the context menu. Apart from that, the use of special input features like the location API are of special interest for a geographic tool like Cadenza, too.
Bidirectional communication
To control Cadenza Web as a rich web application we need a bidirectional communication between the hosting Java application and the web application. This communication will not only allow the transfer of control commands (e.g. for switching the URL or directly calling JavaScript functions) but also the transfer of knowledge about the current user interaction and the use case on a higher level: “I am looking at the city Karlsruhe on the map right now”. As an optimal and future proof medium we aim to use the Window.postMessage() feature here.
Browser Feature Compatibility
The browser also must meet the website’s demand on browser feature compatibility to guarantee its functionality. Cadenza Web makes use of several new browser features like Web Components, color input elements and dialog elements. This requires the browser functionality to be up to date with current technologies and standards.
Platform independence
The browser component as a mediator between the hosting Java application and the web application must support the intersection of platform support requirements of both sides. Apart of browser feature compatibility, Cadenza Web luckily does not introduce any platform dependencies. To be generically compatible with Java Swing host applications, we want a browser framework which supports as many platforms as possible.
Qualitative Requirements
Beside the previously mentioned technical requirements there of course are also some qualitative ones. Those include the need of being sufficiently fast to allow a purposeful and convenient interaction with the website to provide a sufficient documentation or having a responsive support to maintain integration code, as well as the need for a living and future-proof development to keep up with technological advantages and to fix bugs. Also license requirements of the Java app and the web application must be met.
The candidates
Of course this is not a new topic and some minor and major projects have formed around it. The result is a bulk of frameworks that aim to provide the searched feature of integrating a browser into Swing applications. The following are the candidates we took a closer look at.
JavaFX WebView
The component we obviously had to take a look at is the JavaFX webview. JavaFX as the successor of Swing is part of Java (JRE and JDK) since Java 7. Although it gained a lot of criticism over time it provides us with a component called WebView which basically is what we need: A browser based on an old state of Webkit engine. Since JavaFX is practically a part of Java JDK it was our first answer to the question about how to solve the task.
JxBrowser
JxBrowser, developed by TeamDev, is a standalone library which previously aimed to embed a set of existing browsers (IE, Safari, Mozilla i.a.) into Swing and JavaFX applications. Today it focuses on the integration of the code of the project Chromium browser which is an open source (BSD license) project Google Chrome based on, too. While this base is open source the JxBrowser itself is not. It costs a minimum of $ 1,799 per developer (different options are available).
Java-CEF
Java-CEF (JCEF) is a Java wrapper for the C++ Project CEF. CEF itself is a BSD-licenced open source project founded in 2008 by Marshall Greenblatt. Like JxBrowser it is (mainly) based on the Google Chromium project and aims to facilitate embedded browser use cases in third-party applications. JCEF describes itself as project that is a “work in progress”.
The DJ Project
The DJ Project is a set of tools to improve Java capabilities on the native desktop environment. The DJ Native Swing library as a sub-project provides Swing components, including a web browser component, that focuses on the integration of native desktop components into Swing applications.
Other frameworks we sorted out
While we were focusing on an analysis of the usability of previously named frameworks we stumbled over several other projects with similar functionality that dropped out of our testing pool but might be worth to be mentioned:
The framework SWT (a toolkit for the creation of Java GUIs) also integrates a browser component based on Webkit.
Flying Saucer focuses on styling XML and XHTML with CSS 2.1 to render PDFs, images and swing components.
JavaXPCOM was a project that aimed to allow Java code to interact with Mozilla XPCOM components. The XULRunner package thus provided possibilities to integrate Mozilla browser rendered content in Java. It is an obsolete feature since Gecko 4.0.
MozSwing was another Java Swing browser based on the XULRunner and Mozilla XPCOM components.
Lobobrowser is a web browser completely written in Java. Though its homepage seems to be unmaintained some activity can be seen on their GitHub project.
Sun’s dead project JDIC aimed to bring native desktop features to a cross platform level. It included a feature to embed the native default web browser of the operating system into Java applications.
How we tested
Though we filtered out some candidates early due to unfulfilled requirements, we still had to compare their performance under practical use. That included testing of their rendering performance, feature compatibility regarding to features used by Cadenza Web and those that we might use in the future, as well as the ease of use when integrating the candidates into an existing Java application.
For that we developed a small Java Swing demo application which allowed us to test different Cadenza Web use cases under equal circumstances using different candidates to integrate Cadenza Web in a GUI component. The use cases included the main GUI features map visualization, data visualization as tables and as charts, and their combination in form of PDF reports. All use cases included intensive interaction with Cadenza Web and typical browser features like saving a file (e.g. a PDF report) to the file system.
The test cases further included browser benchmark websites to measure the performance of the embedded browser. Those were:
- http://html5test.com – To quantify the feature support
- http://browserbench.org/JetStream – To measure the performance of JavaScript execution
- http://www.zynaps.com/site/experiments/environment.html?mesh=buddha.wft – To measure the rendering performance with 2D Canvas
As a last use case we measured the performance of Window.postMessage() communication, which is previously mentioned as the targeted medium for communication between Cadenza Web and the hosting Swing application. Therefore we measured a round trip of a message (request and answer) from the Java application to the JavaScript of Cadenza Web in the browser and back.
Results
Our tests include a large amount of numbers for which we don’t have enough space to present them here. With the following we give you a quick overview of the collected data:
JetStream (ms) | HTML5Test (Points) | Budda 3D (FPS) |
PostMessage() (ms) | Start time (ms) | ||||
---|---|---|---|---|---|---|---|---|
Roundtrip | Request | Answer | Browser | View | ||||
Chrome 51 | 168.4 | 521 | 83 | 2 | 1 | 1 | - | - |
Chrome 57 | 168.6 | 528 | 85 | 2 | 1 | 1 | - | - |
Firefox 47 | 170.5 | 478 | 60 | 2 | 1 | 1 | - | - |
Firefox 57 | 168.8 | 483 | 65 | 2 | 1 | 1 | - | - |
JavaFX Webview (Hardware) | CRASH | CRASH | 3 | 15 | 4 | 11 | 200 | 340 |
JavaFX Webview (Software) | CRASH | CRASH | 3 | 15 | 4 | 11 | 200 | 390 |
The DJProject | CRASH | 356 | 71 | 3 | 1 | 2 | 130 | 550 |
JCEF | 99.0 | 515 | 90 | CRASH | CRASH | CRASH | 580 | 750 |
jxBrowser | 173.2 | 520 | 85 | 3 | 1 | 2 | 550 | 950 |
Summary
In our first thought we expected those frameworks to fight in the same class of performance and that they’ll only differ much in feature support. In case of JavaFX webview we were at least right with the latter: In the feature race the JavaFX webview failed at a base level since it wasn’t even able to run the HTML5Test or the JetStream benchmark due to a lack of JavaScript features. Though it seems to be a cheap and easy to handle browser for very (very!) simple HTML/Javascript applications it showed a bad performance in 2D canvas rendering as well, with both software and hardware rendering. Not even the Window.postMessage() communication performance was in an acceptable range. Only when comparing startup time of the browser and the time needed to load the page, together with the simplicity for integration (as a library that comes with no cost and bundled with Java) we found a clear point for JavaFX.
Continuing with The DJ Project we found the feature support of that framework to be sparse as well, with no noticeable tendency to a special kind of features. As it is introducing itself as a framework that includes the native web browser of the system (Apple WebKit on Linux, Trident on Windows 7) it showed a surprisingly bad support density on all systems. Additionally the JetStream benchmark crashed, too. With its start and load time it is in the middle segment and can be proudly compared with the standalone browsers in terms of 2D rendering and Window.postMessage() performance. Even though there isn’t a Maven distribution of that framework and must be downloaded from SourceForge.com it was easy to integrate.
The Java-CEF (JCEF) framework was the hardest to integrate, since its C++ core must be compiled in advance for every system that wants to run an application using that framework. For a platform independent Java application this might be a blocker. Another drawback is its JavaScript performance which is at about 60% of the competitor’s performance. While it surprises with its 2D rendering performance which even exceeded that one of the standalone browsers it failed at the support of the Window.postMessage() feature which in respect to our requirements definitely is a blocker.
We were very excited about the overall performance of the JxBrowser library. It comes as an easy to integrate Maven dependency and worked flawlessly. The JavaScript performance and feature support is comparable to that from the standalone browsers. Probably due to the integration of a cutting edge version of the chrome browser source, it even performed slightly better. That good performance continues with rendering speed and Window.postMessage() round trip. Only the almost tripled start-up and page load time seems to be its weakness, as well as its price – among its competitors it is the only framework that has a periodic fee. Despite that we see it as the most promising library of all.
So our bottom line is: Use JxBrowser if you are willing to buy the license, otherwise fall back to Java-CEF (JCEF) and swallow the bitter pill of handling the C++ build stack as well.