All articles
Contents

    Leveraging the power of web UI for desktop front-ends

    Disclaimer

    The article uses CUBA Studio as an example of enriching a web application with useful features of a desktop application by settling it on top of the Electron framework. Later on, this experiment showed very good results. In fact the "standalone" version of the Studio went more used than the web-based. This trend naturally led CUBA Studio to become a part of an IDE. Since CUBA 7, the Studio is built into IntelliJ IDEA.

    What is happening to Java desktop technologies

    In these latter days, the most widely used Java technologies for desktop do not evolve: Swing implementation has been put on hold indefinitely, SWT simply does not deliver new features. The latest live technology is JavaFX.

    The impact of web technologies is great in desktop frameworks. Even JavaFX is trending towards the web techniques, borrowing more and more features from the web world. So, JavaFX supports a subset of CSS features, accompanying it with their own properties.

    However, this all is far away from what the web offers for UI. Another essential aspect is tooling. Have you seen anything in any way similar to developer tools coming along with all the popular web browsers for desktop UI design? Finally, the fact that JNLP goes deprecated in Java 9, it certainly doesn't add points to desktops.

    But then, why does desktop stay afloat? There are a few very important things that are poorly covered by a web approach:

    • Offline mode
    • Advanced integration with peripheral devices
    • Local data/file processing

    Partially, these problems are being solved using new web standards, such as Service Worker, but it would be great if we could implement a technology that brings web UI development technologies and tooling to our desktop Java applications.

    What does Electron.js have to do with it

    Electron is a well-known technology for desktop applications from the JavaScript world. It is a technology behind GitHub’s Atom editor. Atom was the first widely known desktop application built with HTML, JavaScript, CSS, and Node.js integration.

    Electron is an open-source framework that allows using web technologies for the development of desktop GUI applications. You can use front- and back-end technologies originally developed for web applications: JS for the backend and HTML/CSS/JS for the frontend. You might be surprised, but it is widely used not only for development tools, for instance, Slack and Skype are built on top of Electron.js.

    In a nutshell, Electron consists of two main components: the Node.js backend plus a Chromium web browser in a single executable, as well as additional desktop integrations: native menus, notifications, tray icons, installers, etc.

    In the previous blog post I’ve told you how to employ Electron.js to convert existing Vaadin-based web applications into full-featured desktop apps.

    In this article I’ll show you how do we use it for our development tool CUBA Studio and how to improve this approach to make it suitable for business applications.

    How do we use it for CUBA Studio

    As you know, CUBA Studio is an enterprise application development tool for applications based on CUBA Platform. With Studio, you can easily develop typical enterprise applications such as CRM, ERP, ECM and other business-oriented systems.

    We have used Vaadin Framework for both CUBA Studio and CUBA Platform and reused a lot of UI components and technical solutions between them. Since the first release CUBA Studio has been a web application that runs locally but shows the UI inside of a web browser.

    This year we introduced the new version of CUBA Studio that uses Electron to bring better UX for our users. It enables developers to use CUBA Studio as an independent Desktop application without a web browser. We can use all the advantages of an operating system, such as the taskbar, fast switching between applications with shortcuts and shutdown of the application on window close.

    text

    And what makes me so happy is that we bundled our existing Java code without any changes! Well, almost without changes, of course, we improved a couple of things.

    With this technology we delivered a lot of game-changing features:

    • Desktop Integration - taskbar, window switching, shutdown on close.
    • Controlled version of the browser, thus the application will not be broken in case of an update of Chrome. And more importantly, the same version of a UI engine we tested before release.
    • Smooth automatic updates

    In the next version, we are planning to introduce new features:

    • Multi windows support
    • Desktop notifications on build/deploy events

    Multi windows support is already implemented, and you can try it in our nightly builds.

    These features are available since we are no longer limited by the web browser.

    How it actually works in case of CUBA Studio? There are several technical details that make it possible to run CUBA Studio inside of Electron.js:

    • CUBA Studio consists of Jetty servlet container and Vaadin-based web application. Jetty is a small yet powerful servlet container that can be easily embedded. We use the same embedding approach in our UberJAR deployment.
    • The whole app is packaged as a self-containing application that can be run without deployment to a standalone web server. Usually, we start it with double click on the icon or as a single command from a console.
    • We have prepared a special JavaScript runner - studio.js that is used by Electron.js as the entry point of CUBA Studio application. You can even find it inside of the CUBA Studio installation directory and take a look at the actual JS code, it is located under /CUBA Studio SE/resources/app/.

    The process is as follows:

    1. When users click on the application icon, Electron.js binary is starting.
    2. Then Electron.js loads and runs studio.js script.
    3. The runner script finds a free network port and starts java.exe child process of CUBA Studio application. It is the same application as before, with a number of small improvements, that allows us to improve such an integration.
    4. When CUBA Studio process has started the runner script loads the web page of it inside of the Electron.js window - Chromium browser window.
    5. That’s it! CUBA Studio is up and running!

    The reverse process is the application shutdown: the runner script performs the smooth shutdown of the Java process when a user closes the last application window.

    We have slightly improved this with two-way WebSocket connection (instead of AJAX) that enables us to speed up local network communication up to just 1ms per request. If you want to try this approach for your Vaadin-based app I’d recommend that you take a look at the complete tutorial on Github.

    Benefits of the Hybrid Approach for enterprise apps

    It is a really cool approach for a development tool, but how about something for real life? It looks like kind of “hipster” way. Let’s talk about the benefits for business apps:

    • We have full control on the entire development stack: from the underlying web browser to our applications.
    • We still have full access to the Desktop machine: hardware, file system, installation, notifications and integration with the operating system.
    • We can use JS/CSS to develop UI widgets, at the same time employing Java for business logic.
    • We can reuse existing JS/CSS libraries and approaches.
    • We can even bundle our existing CUBA application for desktop usage!

    The most important point is the latest - ability to reuse existing code and business logic on desktop without additional development. We clearly understand that it will require additional work, but still, a lot of business logic can be effectively reused!

    Experimental replacement for Swing-based desktop client

    Since the first public release of the platform we provide two different UI technologies for applications: Vaadin-based Web Client and Swing-based Desktop Client. Implementation of the generic user interfaces enables you to write code that works in both clients automatically, of course, with the corresponding limitations.

    Desktop Client was initially developed in 2011 on the basis of Java Swing because there were no stable and viable UI technologies for Java desktop except it. But things are changing.

    Today, we are facing a lot of new requirements for Desktop UI: responsiveness, animations, and integration with network services and cloud providers, such as Google. Broadly speaking, applications are moving towards web UI technologies, and we cannot ignore this movement.

    Seeing all these new challenges we have decided to do research on Electron.js and web UIs not only in CUBA Studio but also for the CUBA-based applications.

    In the sample project you will find the application with the additional module: electron.

    It contains only one required file - main.js. It is pretty much the same script runner as in CUBA Studio. The script starts Java process using child_process module of Node.js:

    serverProcess = require('child_process')
       .spawn('java', ['-jar', 'app.jar'],
           {
               cwd: app.getAppPath()
           });
    

    Only 100 lines of JavaScript, and we can start our web application as desktop?! Not that fast. We have to prepare our application first:

    1. Build web client as a self-contained application using Uber JAR technology

    See build.gradle file:

    task buildUberJar(type: CubaUberJarBuilding) {
       webPort = 30550 // use non-standard port for electron app
       corePort = 8080
       coreJettyEnvPath = 'modules/core/web/META-INF/jetty-env.xml'
       appProperties = ['cuba.automaticDatabaseUpdate' : true]
    }
    
    1. Package Electron.js application with electron-packager utility. See buildJsWrapper Gradle task in build.gradle
    2. Bring all the pieces together in a single directory. See buildElectronApp Gradle task.

    After that we can start the resulting binary in ./build/electron-app/ directory. Do not forget to start the backend application from CUBA Studio, because we package only web UI to Electron.js shell.

    text

    It is alive! We can use all power of web UI and almost all features of CUBA Platform! I’ve spent only 4 hours to build the entire solution from scratch and it is a fantastic result!

    What is next?

    There is still a lot of work to do. The following features should be implemented before this approach will become viable:

    • get rid of network for Java <> Electron.js communication
    • file downloads UI
    • multi-windows support
    • crash reporting
    • packaging and updates
    • caching and offline-mode support
    • security improvements

    All these features are not that easy to implement but, at the moment, we are close enough to do that. I believe that at some point It will become our new way to build desktop clients for big enterprise solutions.

    Want to see the technology in action? Try CUBA Studio SE

    Jmix is an open-source platform for building enterprise applications in Java