The Decline and Fall of Java on the Desktop Part 2 (2004-2007)
The release of Google Maps in 2004 marked the end of Java's desktop dynasty and changed what it means to be "cross-platform" on the desktop.
This is the second in a series of articles about the history of Java on the Desktop, from my perspective as a developer who started working with Java in the late ‘90’s. I’m writing this, partly as a background for why I created jDeploy, a developer-friendly desktop deployment tool for Java. Despite the ominous tone of this article’s title, I believe that Java is a compelling platform for modern desktop applications. Stick around for the whole series to find out why.
In my last instalment, I chronicled the dissolution of Java’s hype on the desktop between 1999 to 2005. The feeling, at the beginning of this period was one of manifest destiny. Java was still riding the wave of its successful debut in the form of applets, and it was poised to redefine “the desktop” in the age of the internet. The future was cross-platform, and Java had “cross-platform” in its DNA. Surely, then, Java was the future. Unfortunately, the definition of “cross-platform” was about to change.
The Final Days of the Desktop Dynasty
Circa 2002, I had a call centre job doing phone support for computers and printers. I worked in a cubicle with my trusty companion, a desktop application that allowed me to look up customer and product information, and to write notes about each call.
On a typical call, I would ask the customer for their serial number, which I would enter into the system. If they had ever called before, it would open up a window with a full history of the product, along with any previous support calls made by the customer. It included fields for me to add notes about the call, as well as tabs and buttons for me to initiate workflows like ordering a replacement machine for the customer.
I don’t recall the name of this application. It may have been custom-built for the company, or a generic application built for call centres. I think it was a PeopleSoft product, but I’m not sure. In any case, it was a desktop app - not a web app - running on Windows 2000. It was relatively complex, with lots of menus, and forms, but once you got the hang of it, the experience was pretty good - fast and responsive. There was almost no lag, for example, loading customer records by phone number. You just typed the phone number into the “Phone” field, and the rest of the form would instantly populate with the customer’s details.
To my knowledge, this particular app wasn’t written in Swing, but there were probably thousands of similar enterprise desktop apps used in production at other companies around the world at this time that were written in Swing, and offered comparable, or better, user experience. That is to say, in 2001/2, this is precisely the kind of app that Swing excelled at.
Six months after I started, they replaced this app with a web application. We were told that this new system would make our jobs easier, but ten minutes into the first training session it was clear that that we’d been sold a bill of goods. This new system sucked!
I don’t recall whether we were running IE 5.5 or IE6, but in either case, this was the pre-AJAX web. Now, when I entered a serial number into the product field, a window would pop up saying “Loading… DO NOT CLOSE THIS WINDOW”. After a few seconds, the window would close on its own, and the customer details would populate the form. That window would pop up again whenever it needed to fetch something from the server. We were discouraged from hitting “Refresh” in the browser as that would screw up the state. I would often have to log out and log back in when things started going sideways.
I couldn’t understand why the company would ditch our perfectly good desktop app with this clunky beater of a web app. It was like Starfleet replacing Data with an 80’s robot. Probably it was a cost decision. Web apps were cheaper to develop and maintain than desktop apps. It could have also been forced on them by the software vendor. E.g., “Next version is web-based. Everyone must update!”. Or they could have just been visionaries: “The web is the future!”.
A key takeaway from this episode is that the web was eating the desktop even before it was “good”. The only question was how long would it be before it improved to the point where it offered a user experience comparable to the desktop. As it turned out, not very long.
The Uncanny Valley
Meanwhile, back in Java-land. The Dukes were diligently working to grow the Java empire across the entire desktop landscape. Their zeal for WORA (Write-Once-Run-Anywhere) guided them into an uncanny valley between cross-platform applets and “native” applications. The Java IDEs of the time generally gave you three build targets:
Applet
Java Web Start
Executable Jar file
There were no options for native apps. There were 3rd-party tools to convert that Jar file into a native app1, but those required such complex and inconvenient build workflows, that you would only take that step if you had an affinity for painful tedium. Java was banking on a future where native, desktop applications were a relic of the antiquity - a future not unlike the present, as it would happen. So their oracle was correct; it was just off by a few years.
Through the lens of 2022-hindsight, Java’s problem was obvious. You could deploy your app to both the web and the desktop, but it wouldn’t feel “native” in either context. Web deployments (applets) operated inside their own “sandbox”, and integrated about as well into the webpage as a doddering, old Marcus Brody wandering the streets of Iskenderun (“Uhhh, does anyone here speak English?”).
The Rise of HTML5
While Java was fortifying this swampy middle-ground between the web and the desktop, they were being outflanked by the web itself. By 2002, many enterprises were choosing to deploy web applications for things that they would have previously deployed to the desktop. These web apps were cheaper to build, maintain, and deploy than their desktop counterparts, even if their user experience left something to be desired.
It was around this time that Java started embracing the term “Rich Internet Application” to differentiate itself from the unwashed masses of web apps. Web apps may have been cheaper, but they still couldn’t offer as rich an experience as a desktop app. This all changed when, in 2004, Google unveiled Google Maps, the flag-bearer for a new generation of rich, web applications, that are colloquially referred to as HTML52 apps.
I recently watched an old video of Bill Atkinson demonstrating MacPaint for the first time to an auditorium of Apple enthusiasts. He received authentic “oooh”s, “aaah”s, and applause when he used the paint brush tool to draw a picture with his mouse. It was ground-breaking. This is how I felt when I used Google Maps for the first time. You could zoom and pan around the map seamlessly, without it ever seeming to run out of tiles. It was using a brand new technology known as AJAX (Asynchronous Javascript and XML), which, for the first time in a web app, allowed you to make seamless background network requests to the server. We take this for granted now, but in 2004, you needed to employ all kinds of ugly hacks involving hidden frames or popup windows in order to load new data from the server without refreshing the whole page.
As a web developer, I was drooling over the new possibilities that were available to me. As a desktop developer, however, I was blind to the zero-sum implications that this advancement held for the desktop, in general, and Java in particular.
Before HTML53, “cross-platform” meant “Windows, Mac, and Linux” - at least on the desktop. I didn’t recognize it at the time, but HTML5’s Bar Mitzvah represented the coming of age of a new platform - one that would become the de-facto standard for client applications and, importantly, a platform that Java didn’t support4. All of a sudden, WORA needed an asterisk. You can deploy your Swing app to every platform, except for the one that matters most: the browser.
The Java Diaspora
So where did all of the Java desktop developers go? There were three primary destinations for these refugees:
The server
The browser (HTML5)
Desktop Apps
If you fancied yourself a “Java developer” first and foremost, and “client-side developer” second, then you probably ended up on the server, where Java was (and still is) thriving. If you were more interested in developing user-facing (client) applications, and had primarily been using Java because of its cross-platform value-proposition, then you probably shifted to HTML5 (Javascript/HTML/CSS) development. And if you were a stubborn old loyalist to the Queen (like me), you continued to develop desktop apps and periodically looked around and wondered where everybody went.
GWT: Java in the Browser (sort of)
In the early 2000’s Javascript’s development tools were still in their infancy. Most web developers used nothing more than a text editor to edit their .js files. This worked well for simple validation scripts and interactivity, but it didn’t scale well to large, enterprise apps that involved teams of developers. The Javascript language also lacked features, such as static typing, that developers depend on for important operations, like refactoring.
Java, by contrast, already boasted a comprehensive suite of development tools that could scale to any size of project with ease. By 2004, the leading Java IDEs had matured to become the gold standard for development environments, and the language’s static-typing greatly simplified the maintenance of large projects. Unfortunately, Java apps wouldn’t run inside the web browser (applets notwithstanding).
To solve this problem, Google created GWT (Google Web Toolkit), a Java-to-Javascript compiler and runtime library that would allow you to write your app in Java, using Java’s world-class development tools, and deploy it as a Javascript app that would run natively in the browser. The runtime library included implementations of many of the core Java APIs (e.g. java.lang
, java.util
) so that your business logic could be shared between your GWT app and your server app.
For the user interface, GWT provided its own widgets, which were Java bindings to the native HTML widgets provided in the browser. You couldn’t use your Swing code, obviously, and most 3rd-party libraries were out of bounds, but, you could use your familiar Java development environment and core APIs.
This wasn’t quite Java in the browser - large portions of the standard JavaSE library weren’t supported, and core features like threads didn’t work, but it close enough for many use-cases.
Google used GWT to develop many popular HTML5 applications, Gmail being the most notable, and the project spawned a small but active open-source community that continues to this day, though its relevance has been on the decline for some time. Improvements in Javascript tooling have eroded GWT’s raison d'être, and other, more modern solutions5, have been developed in the past decade that allow you to run Java in the browser with fewer trade-offs.
The Server Gold-rush
HTML5 was certainly disruptive to Java’s desktop ambitions, but it wasn’t all bad news. In fact, it ushered in even greater boon on the server, where Java was already well-positioned to meet the newfound demand for back-end services to power web apps.
Java’s popularity on the server-side would continue to grow over the next few years, resulting in massive investment in the eco-system as a whole. The selection of third-party libraries continued to grow and the introduction of Maven in 2005 made it easier than ever to make use of those libraries. No need to download libraries and hunt down dependencies anymore. Just paste a snippet into your pom file, and it will automatically download all of the necessary dependencies.
Java’s development tools also continued to improve thanks, in no small part, to the increased investment that came from the server-side popularity. Most of these improvements had a positive impact on desktop developers also, since we used the same IDEs, compiler, VM, and libraries as they did on the server. However, it seemed that the survivors of the desktop rapture were on their own for desktop-specific issues such as UI library improvements, and deployment.
When I get stuck on issues, I usually google them, to see if anyone else has run into the issue before, and better yet, if they’ve solved it. For Swing issues, I started to notice a trend that all of the search results were from 2005 or earlier. Sometimes I wouldn’t find a solution at all, so I would blog about it. Two years later, when I ran into a related issue, I’d google again, only to find that same blog post that I’d written two years earlier. Were there any Swing developers left? I wasn’t sure.
“The Desktop app” Redefined
In many ways, the emergence of the web brought clarity to what it means to be a “desktop app”. Java’s original cross-platform vision for client development didn’t offer a clear divide between a thin clients, which primarily interacted with remote servers, and full desktop apps, which interacted with the local machine. This resulted in a security model that was difficult to understand, and even more difficult to implement. Java viewed the platform as the computer itself, and it used an awkward sandbox to limit access to APIs that presented a security threat, such as access to the file system. This is the source almost all of the Java security exploits that ultimately led its banishment from the browser.
Developing for this “sandbox” was an unpleasant experience, in part, because it was too easy to accidentally step “out of bounds” and trigger a security exception. The end result was that nearly all Java clients would request “trusted” access to the system, so that they could bypass the sandbox restrictions entirely.
HTML5, by contrast, defines a clear divide between the web page and the desktop. The default assumption for web apps is that they don’t have any access to the client computer itself. The browser is the platform, and that makes it much easier to handle security for client applications.
This realignment has resulted in a much smaller “desktop” category, as many of the applications that would have previously been regarded as “desktop” apps, can now be placed in the “client app” category, leaving a new “desktop” category with well-defined requirements. If the app only provides a UI for the user to interact with a server, then it is a client app. The “desktop” is now reserved for apps that need to integrate with the local machine in some way. This includes applications that access the file system, such as development tools and file conversion utilities, as well as apps that require platform-native APIs not available in the browser, and apps that perform processor-intensive activities.
This isn’t to say that there is no overlap between “client” apps and “desktop” apps - there are! Both classes of app involve a GUI, and many modern desktop apps connect to a server of some kind. This means that improvements to GUI toolkits, support for media (audio/video), and networking can be leveraged by desktop and client apps alike.
The Next Chapter for Desktop Java
In 2004, I had a few commercial desktop Java applications that I distributed on Mac and Windows. The immediate impact of HTML5 on these apps was minimal. Swing still worked fine for my purposes, and all of the desktop deployment tools that I used to make the native bundles still worked, although I really would have preferred something like jDeploy back then.
Unfortunately, in the tech world, you can’t afford to stand still for very long. Over the next few years, the web platform improved by leaps and bounds while Swing stayed stagnant. By 2007, it was clear that Swing needed some major investment in order to stay relevant. It needed to respond to HTML5 in a big way. That response would come in the form of JavaFX, a fancy new UI toolkit for Java that would bring Java into the modern world of GPU-acceleration, scene-graphs, 3D graphics, Web Views, and support for modern audio and video codecs like MP3 and MP4.
In the next episode we’ll talk more about JavaFX, including its reception and its impact, as well as other developments in both the desktop and Java landscape leading up to the introduction of the Mac app store in 2011, which precipitated an existential crisis for, Java desktop development on the Mac. Don’t forget to subscribe so you won’t miss it.
Launch4J, which allows you to wrap a Jar file as a Windows .exe, was first released in 2004. There were also several Mac tools available around that time for wrapping Jars as native apps, including JarBundler
While the W3C didn’t release the first working draft of the HTML5 specification until 2008, The Web Hypertext Application Technology Working Group (WHATWG) had been working on the standard since 2004, and many of the features used by Google Maps to achieve its rich experience (e.g. AJAX) are generally regarded as parts of HTML5.
HTML5 refers primarily to new features in the web that allowed applications like Google Maps to be built. One of the primary advancements was AJAX, the ability to make background network requests to the server without “iframe” tricks. But there were several improvements in HTML5, that cumulatively amounted to it becoming a viable platform for interactive client development.
Technically Java apps could be deployed to the browser as applets, but as we’ve already discussed, the result was decidedly non-native, and were increasingly viewed as security threats. Even in 2005, the consensus was that Applets were a dead technology.
Excellent article!
I always had a love-hate relationship with Java on the client. I also have used C++ Builder with VCL and Qt occasionally but the company I work is mostly a Java shop.
I think is interesting to mention the embedded space where Java clients have been used for many years.
At my company we have been using Java AWT for POS devices (with a highly custom Touchscreen interface) for more than 20 years, started with PersonalJava, Java 1.1.8, Java 1.3, Java 1.6 and now Java 1.8. Over these years we have deployed +500.000 devices.
Sadly, the latest product uses HTML5 for UI (with an internal backed in Java to access peripherals and run the business logic). But we still have many customers with POS devices running Java AWT.
just a typo comment... change instalment --> installment