Though I fancy myself a backend developer, I love the frontend. It’s always magic to me to be able to see the code you just wrote unwraps itself in front of you. Believe it or not, more than 15 years ago, I wrote JavaScript to dynamically add rows to an HTML table for Internet Explorer 5.5. At that time, there was no XMLHttpRequest object. No AJAX if you prefer. And DOM manipulation was called DHTML .

But I was still a Java developer at heart. I tried to teach myself Swing. It was an interesting case to learn Event-Driven Programming. While it was quite easy to distribute Swing apps to Intranet users, it was an issue to do the same over the web. However, Java Web Start was exactly aimed at that. I loved it. The only requirement to distribute AWT/Swing apps was to create an external deployment descriptor using the JNLP format. JaWS took care of downloading and launching the app. It also included features such as offline mode, differential downloads, etc.

However, if you’re a fan of such technologies, I’m very sorry for you. Java 9 brought dire news:

Java Deployment Technologies are deprecated and will be removed in a future release Java Applet and WebStart functionality, including the Applet API, The Java plug-in, the Java Applet Viewer, JNLP and Java Web Start including the javaws tool are all deprecated in JDK 9 and will be removed in a future release. — Java 9 release notes

http://www.oracle.com/technetwork/java/javase/9-deprecated-features-3745636.html

Moreover, Swing (and AWT even more so) require so fundamental understanding of how it works: for example, run long computations on the Event Dispatch Thread. This is the reason why some apps display a gray background instead of refreshing. Also, theming in Swing is hard: most Swing apps are really ugly. Though JavaFX does help on the theming side, I’m afraid it came too late and suffers from too much competition from the Web.

On the other hand, there are lots of Java developers already doing webapps, using widespread technologies such as Spring MVC or Vaadin. Even better, Spring Boot allows to create fat JARs, and provide top-of-the-notch Vaadin integration.

And webapps packaged as simple JARs still allow standard desktop integration.

Most of you dear readers probably know about H2. But did you ever tried to execute the H2 JAR instead of using it as a library on the classpath? Doing so launches a web server and opens the browser to display its homepage. It also displays an icon in the system icon tray.

It does so by using the Java platform ability to integrate with the user’s desktop, which is part of the Swing API. For example, here’s a quick way to open a browser at a dedicated page, just like the H2 console:

with ( Desktop . getDesktop ()) { if ( isSupported ( Desktop . Action . BROWSE )) { browse ( URI ( "http://localhost:8080" )) } }

In essence, it’s possible to start a web application, then run the above snippet to access its homepage.

Unfortunately, if using Spring Boot, this will fail with the following:

Exception in thread "restartedMain" java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) Caused by: java.awt.HeadlessException at java.awt.Desktop.getDesktop(Desktop.java:142) at ch.frankel.renamer.RenamerAppKt.main(RenamerApp.kt:24) ... 5 more

By default, Spring Boot apps are headless, which makes sense in most cases.

To disable headless mode, use the following:

SpringApplication . run ( RenamerApp :: class . java ) (1) SpringApplicationBuilder (). headless ( false ). run () (2)

1 Default headless mode 2 Desktop integration possible

Running the above snippet will now work as expected.