← All Posts

Java "portability" has always been kind of a joke

Posted by

  critique tech

5 min read | 1368 words | 3 views | 0 comments

The portability of Java has always been kind of a weird thing. Compared to C, for instance, where a lot of things can vary from system to system (or be undefined altogether), and you need to target various platforms and architectures, Java boasted the ability to "write once, run anywhere", freeing developers from having to worry about the differences between different platforms. Thanks to the JRE, a sort of middle layer between an application and the OS, you only need to write and maintain one version of the application that can "run anywhere" — so the story goes, anyway.

In reality, this has always been kind of a joke. The Java bytecode itself may be portable, but the JRE is certainly not. And I don't mean in the sense that the JRE between platforms differs (although it does) — I'm referring to the fact that the JRE itself is not present on every system. In fact, I'd go so far to say that it's far from universal, and the presence of Java on most systems has probably been declining considerably for some time now, making the idea of "portability" amongst programs dependent on the JRE more and more of a joke everyday.

The other day, I had need to install a Gopher client on my system. A search turned up the "Gophie" client, which seemed to be pretty popular. Unfortunately, it has one major problem: it's dependent on the Java Runtime Environment. Even the Gophie 1.0 "standalone executable", which you would think would come bundled with anything it needs to run, requires the JRE to run. I immediately gave up and soon found another Gopher client, one which didn't require the JRE to be present.

While it is possible to build a truly self-contained Java program, this experience has repeated itself so many times over the years that, in a way, "Java program" is almost vernacular for "non-portable" in my dictionary. Amongst Windows applications, there are broadly two different families of dependencies that programs tend to have — one is the .NET framework, and the other is the JRE. The .NET framework, at least, comes from and is updated by Microsoft, and is something you could reasonably expect many systems to have.

Java has neither of these things going for it. The JRE has frequently fallen victim to various security exploits over the years, leading to the wisdom that Java is best not installed unless absolutely required. Security blogger Brian Krebs welcome the death of the Java plugin, which at one point bundled adware with it. No wonder the JRE has such a horrible reputation in users' minds.

Then, there's the dual existence of the Open JDK with the Oracle JDK, the latter of which is known for its punitive and expensive licensing terms, which creates uncertainty and volatility in business environments. Oracle JDK is effectively dying, with users either moving to Open JDK or abandoning Java on the desktop altogether. I once worked somewhere where we received a memo from the very top, that Java was to be immediately uninstalled on all systems organization-wide, with very few limited exceptions carved out, to avoid running afoul of Oracle's latest licensing terms. Mind you, we're talking about thousands, possibly tens of thousands of desktops here, so "immediately uninstall Java" at scale was a pretty big deal.

While Java can certainly be used responsibly, I have, for these reasons and others, long been skeptical of software dependent on Java. For one, half of the JRE-dependent applications out there seem to be half-baked applications out of some university (probably written by some undergrad, no less). The other half seem to be half-baked applications out of somebody's parent's basement. "This application requires Java" is almost synonymous with clunky, ugly, and unrefined user interfaces. While in academia, and sometimes in business, I can certainly understand the need for such software, which may truly be one-of-a-kind, for most end-user facing software in the home, there are usually Java-free alternatives available that are better in almost every way.

What does all this demonstrate? Java has virtually no benefits at all to users for client-side applications. Historically, any benefits always accrued to the developer. "Portability" via the JRE allowed developers to avoid the extra work of writing code to target multiple OSes (Windows, maybe Mac OS, and maybe maybe Linux). In turn, all the hassle of running the application gets passed to the end user, who then needs to decide whether your special application is worth the inconvenience of installing Java or not (hint: if there are alternatives that don't require Java, it's probably not).

Contrast this with "native" applications, which directly target Windows, Mac OS, or Linux. The end-user experience is far superior — no controversial dependencies to deal with it, just install it and go. There's no dependencies on software that may or may not be present — consequently, I would argue that this is more portable amongst users, as they can truly install your software anywhere (in the context of a particular platform). In return, the developer needs to do a little more work (okay, maybe a lot). But, in the end, I would argue it's worth it, at least if you care about users. User experience should trump the developer experience, and I think this lesson is sadly getting lost as more and more developers jump on the bandwagon of various frameworks that boast "portability" across platforms. Inevitably, they all ship with some kind of bloatware. The latest examples of this are various web-based middle layers, like Electron, that are synonymous with bloat and excessive resource consumption. Streamlined developer experience, sure, but what a horrible user experience.

Python, for its part, is also worth mentioning, if only because it's become incredibly popular. To be perfectly transparent, I have a particular disdain for Python — it has wonky formatting rules, it clashes with the norms and constructs of virtually every other language, and it's pathetically inefficient. It's also, as it happens to be, a non-portable environment for programs in much the same way that Java has been, historically. Every Windows machine out there does not have Python pre-installed, ready to go for your application. Worse, Python versioning creates its own headaches that manifest directly in end user software. A great example of this is the yt-dlp command-line video downloader tool, which is available for Windows. yt-dlp is written in Python, and as a result, its support for Windows 7 is tied to Python's support for Windows 7. As a result, yt-dlp is no longer supported on Windows 7, which has resulted in a fork of yt-dlp that ports newer Python versions to Windows 7 and, by extension, yt-dlp. How did we get into this spaghetti mess in the first place?

There are always trade-offs when developing software. There are different kinds of portability, and there are also trade-offs between them. One camp is "portability of development", historically exemplified by Java and these days more so by Python[1] and Electron and other web-based frameworks. The other is "portability of usage", whereby with just one, two, or three[2] different flavors of an application, users can install it on any Windows machine, maybe any Mac, and possibly even any Linux system as well. As a user, I've always preferred the latter experience, and I'd venture to say most other users do too.

In the same vein that "the customer is always right", "the end user is always right". End users' needs (usability, the performance of your program on their machine, and the ease of installing it) should generally come before a developer's needs (the ease of writing and shipping software). Yes, it will take more time, and yes, it's more effort, but so also are most things worth doing.


[1] If you like using Java and Python, that's fine. But restrain them to your server-side code, where your choices don't directly affect and inconvenience your users!

[2] Yes, there's also the x86/x64 split on Windows, and x86 and ARM on other platforms, so it's not quite this simple — but there's usually a fairly small finite set of platforms and architectures that most programs target. And for the most popular programs, which target an even wider variety, it's all the more important that your program prioritize the user experience.

← All Posts


Comments

Log in to leave a comment!