Shine and Poverty Java for Desktop

Shine and Poverty Java for Desktop

 
You will not believe it, but in 2018 you still need to develop a Desktop application.
 
 
Imagine such a club of anonymous Java programmers, drunken and unrestrained, who sit and share their problems.
 
 
- Hello, my name is Yuri, I am writing Desktop applications in 2018.
 
- Hello, Yuri, let's pat him, he could share his problem!
 
 
Yes, indeed, we are still writing a Desktop application. Usually, I do not really want to do this, most often it's legacy projects. But it happens that you need to write and new desktop applications.
 
 
Why do we still do this if there is a web with its new advanced features: Progressive Web Apps, Service Worker, Web RTC, Web GL, etc?
 
 
Under the cut I'll tell you how to live with this and where does Java.
 
Oracle decided to kill Web Start technology .
 
 
Everything goes to one - specialized UI frameworks for desktop applications die.
 
 

Where to run!?


 
And now, about how to re-use your web development experience and web-UI in the development of desktop systems in Java. So that you do not have to develop separate web and desktop applications.
 
 
Electron.js Is a well-known framework that allows you to use web technologies to develop desktop applications. This is the technology on the basis of which the editor GitHub Atom is built. Atom - the first widely-known desktop application, built on HTML /jаvascript /CSS and Node.js.
 
 
Electron.js is an Open Source framework that allows you to write UI for desktop applications on a web-based stack. You might be surprised, but a whole bunch of tools and applications are now built on this framework: Slack /Skype and VS Code are used for UI Electron.js.
 
 
In a nutshell, Electron consists of server-side jаvascript - Node.js and an integrated Chromium web browser in a single executable process, which allows you to use the native features of the operating system: windows, notifications, tray icons and much more.
 
 
Until recently, this framework assumed the development of applications only in jаvascript. But we figured out how to apply it to our Java applications!
 
 
There are two options for developing applications:
 
 
 
Compile Java into JS
 
Run JVM quietly from the user and show the UI in the web browser
 
 
If you already have a frontend on JS, then there is nothing to think about, it remains to pack it in Electron.js and get a desktop application. So do, for example, in the Slack messenger.
 
 
And if you have a lot of Java code? And while it can not just be assembled in JS, you immediately lose reflection, access to the hardware and the possibility of using common libraries.
 
 
In this case, you can use the special module Node.js - child_process , allowing to start child processes in all major operating systems. In fact, we need to implement one JS file that will launch the JVM and open the Electron window:
 
 
if (platform === 'win32') {
serverProcess = require ('child_process')
.spawn ('cmd.exe',['/c', 'demo.bat'],
{
cwd: app.getAppPath () + '/demo /bin'
});
} else {
serverProcess = require ('child_process')
.spawn (app.getAppPath () + '/demo /bin /demo');
}

 
The main thing is not to forget then to kill this process when the application window is closed, which is easy to do with the module. tree-kill :
 
 
const kill = require ('tree-kill');
kill (serverProcess.pid, 'SIGTERM', function (err) {
console.log ('Server process killed');
.
serverProcess = null;
mainWindow.close ();
});

 
The full code of such integration is in my tutorial . It uses Vaadin as the framework for UI, which allows you to write all the code in Java without JS, and the Jetty servlet container is integrated directly into the application. We can run the application without deployment, like the same Spring Boot.
 
 
In this version, our frontend will access the JVM over the network, which is somehow strange. I somewhat sweetened the pill, changing the transport between the browser and the JVM to the WebSocket protocol. Vaadin allows you to do this extremely simply . So we significantly reduce the time to send messages from the frontend to the JVM on the network, literally up to 1ms and get rid of unnecessary HTTP garbage: headers and cookies, and also do not create a connection, but always use the ready one.
 
 
On this stack I wrote small TODO application .
 
 

 
There you will find some more cool tricks:
 
 
 
Download static files (CSS /JS) directly from disk bypassing JVM
 
access to the Electron.js API from Java
 
custom window cap on HTML and CSS
 
automatic installation of Node.js from Gradle
 
 
Well, now let's completely get rid of the network! Since ancient times, in the * nix and Windows operating systems, there is an API for interprocess communication - IPC. In Windows, it's called named pipes, and in * nix, it's called Unix sockets. This is a buffer /virtual file in RAM that is under OS control and allows two independent processes to transfer data.
 
 
For the sake of diversity, I implemented this approach on Kotlin and Kotlin.js .
 
 
In Node.js we can easily create both named pipe and Unix socket using the module - net :
 
 
const pipeServer = net.createServer (function (stream) {
stream.on ('data', function (c) {
.console.log ('Pipe:', c.toString (). trim ());
}};
Stream.on ('end', function () {
PipeServer.close ();
});
.
PipeStream = stream;
Console.log ('Pipe is connected'
.
Global.pipe.send ('hello', {});
} Listen (PIPE_PATH, function () {
//start JVM process here
});
}

 
To work with the named pipe from Java /Kotlin, you need to use the RandomAccessFile class:
 
 
val pipe: RandomAccessFile
try {
pipe = RandomAccessFile (". pipe demo", "rw")
} catch (f: FileNotFoundException) {
println ("Unable to open communication pipe")
exitProcess (-7)
}
var dаta: String? = pipe.readLine ()
while (data! = null) {
//do something
data = pipe.readLine ()
}

 
So we can completely get rid of the network and do not run the HTTP server on the user's machine. Well, of course, the performance of such a solution is better than transferring data via the network stack.
 
 

And why do we need this?


 
As you probably know, we make a tool for developers - CUBA Studio , allowing you to quickly write business applications on the CUBA Platform.
 
 
We used the Vaadin framework in the CUBA Platform and CUBA Studio, which allowed us to re-use a large number of developments. Since the very first release, CUBA Studio has been a web application that runs locally and shows the UI in a web browser.
 
 
With this approach, we finally were able to give developers the convenience of using a desktop application: windows, browser independence, Alt + Tab switching and an icon in the taskbar.
 
 

 
CUBA Studio still uses the network, but instead of AJAX, WebSocket is involved. This is enough to ensure that users do not feel any UI delays.
 
 
Ecosystem Electron.js pleased us and with additional tools .
 
 
  •  
  • modules for creating installation files and packages  
  • smooth auto-update  

 
As you might guess, CUBA Studio is not the ultimate goal.
 
 

How to replace Swing in our

applications.
 
From the very first public release of the platform, we provide two technologies for building a UI: a Web client based on Vaadin and a Desktop client based on Swing. Implementing Generic UI allows us to write code that works in two versions automatically, of course, with the appropriate restrictions.
 
 
Desktop-client was developed in 2011 on the basis of Swing, because then there was no other stable and viable technology for desktop applications in Java.
 
 
But everything changes.
 
 
Today we are faced with new requirements for user interfaces on Desktop: responsive UI, animation, integration with network services, such as Google. In fact, applications are moving towards web UI technologies, and we can not ignore this movement.
 
 
I see only one alternative to Swing and Java FX - Electron.js. Therefore, I tried to adapt this approach for our applications:
 
 
  1.  
  2. We take the Web client  
  3. Add Electron.js  
  4. We pack everything and give it to the client  

 

 
Applications on the CUBA Platform can be distributed as Uber JAR . This version of the application allows the application to be started with a simple command:
 
 
> java -jar app.jar
 

 
 
We can only add a special launch script to Electron and get the Desktop client from the finished web application!
 
 
You will find the full application code here .
 
 

Yes you are crazy!


 
I also thought that the guys from GitHub were crazy. But gradually I was imbued. I want to have a flexible tool for creating UI, and the most flexible tool today is HTML /JS /CSS.
+ 0 -

Add comment