Resurrecting Swing Desktop Apps on the Web
What happens when you convert an old Swing desktop app to a web app? Let's find out
A few weeks ago, I needed to create a class diagram for some documentation I was writing, and realized that I no longer had any desktop apps that were suited to this task. I am aware that there are many high-quality options for creating diagrams, ranging from text-notation generators (PlantUML), to full-featured SaaS diagram editors (Lucid Chart), but for the moment, I was nostalgic for 2002, when my Powerbook was filled with desktop apps to suit every purpose, including drawing UML diagrams.
If it were 2002, I might have used ArgoUML, an open source UML CASE tool written in Swing, or its commercial cousin Poseidon. ArgoUML was a bit rough around the edges, but it worked okay, and it was free. Then I got to wondering what ever happened to it. Maybe it was still out there with a small cult following, churning out releases to feed its die-hard UML-drawing fans. The beauty of living in 2024, is that it is actually quite easy to find out information like this. All it took was a Google search.
ArgoUML was indeed still around…. sort of. All of the source is on GitHub, and some old builds were posted in the releases section. Unfortunately, the Mac app release seems to be too old to work on my 2024 version of MacOS. When I downloaded it and tried to open it, I got the “ArgoUML is damaged and should be moved to the trash” error, which usually points to an issue with codesigning.
Oh well. It was a thought. But then another thought. Maybe I can generate modern desktop installers using jDeploy. I can use the jDeploy GitHub action to automatically build the sources and generate new builds whenever a change is detected in the source. Then I can use it to create UML diagrams, just like I did in Comp-Sci 275. (Side note: I’m not sure, at what point you call it “Yak Shaving”, but this must be getting pretty darn close).
So, I set up my own GitHub repo and created a workflow that clones the ArgoUML repo, builds it, and deploys it using jDeploy, so that there are always current builds available through GitHub releases.
I get the little “ArgoUML” icon on my dock, and I can now run it, in 2024, as a first-class desktop application.
I also created a second workflow that is triggered nightly, and checks for changes in the source. If changes are found, it triggers the first workflow to generate the new builds.
Safe to say that I was mighty pleased with myself. Sure, the app is dated, and is missing many of the features I’ve grown accustomed to in more modern power-house apps like Lucid Chart, but it still worked. It served the purpose that it was originally designed for, just as well as it did the day it was released, over 20 years ago.
Getting Greedy: Building as a Web App
Now I can use ArgoUML again, but why stop there. jDeploy includes built-in support for web app generation, using CheerpJ. I wondered how well ArgoUML would work in a web browser, so I enabled web app support, so that each time jDeploy generated desktop installers, it would also generate a web version hosted on GitHub pages.
You can try it out here.
The Good Parts
So it the best part is that it to works out of the box.
On a relatively modern machine (I’m using an M1 Mac Mini), it is quite usable, once it has finished loading, with no impactful lag.
The Parts that Could Use Work
Open and Save File Dialogs
Now that I’ve created my diagram, how do I get it out in some format I can use? The app was designed to “export” diagrams to the file system. CheerpJ provides it with an IndexedDB-backed file system so that the functionality “works”, but there is no easy way to access these files from my computer. Therefore, the only way for me to export my diagrams is to take a screenshot, which is less than ideal.
This limitation made me think about a fundamental difference between desktop apps and web apps, when working in a web app, your app is not running in the context of your personal computer, like it is when your using a desktop app. Rather it is running in the context of the cloud - or the internet as a whole. You expect to be able to interact with resources via URLs without any regard to where they are physically stored. Therefore, features of an application that read and write to the local file system are never going to translate well to the web.
An “Export” function should either allow the user to save the file to cloud storage (e.g. Google Drive), or simply download the file to the user’s “Downloads” folder. It doesn’t make much sense to save to a virtual file system stored in the browser’s local storage unless that file system is exposed in some way to allow the user to download the file to their local machine.
And even if it did add such functionality, it would seem foreign to the user that this web app doesn’t retain files between different browsers. Users expect content that the create inside a web app to live outside of the machine that they are using, and will be thrown for a loop if, for example, they move to a different computer or browser and have apparently lost all of the things that they “saved” earlier.
Clipboard
In the current version of the app, the clipboard only works internally to the app. You can’t paste things from other applications. This actually won’t be difficult to remedy as CheerpJ includes options to interact with the OS clipboard, they are just turned “off” by default.
Making it Better
As I find time I may add an option so that jDeploy will automatically integrate a cloud storage solution into the web app as it is built, without having to modify the original Swing app. The idea would be to require the use to log in to their cloud storage provider (e.g. Google Drive) to access the app, and then their drive would be mounted as a virtual file system, so that it would be available in the Open/Save dialogs.
I may also experiment with solutions to open a “Download” dialog in place of the AWT/Swing FileDialogs so that these will upload/download from the local machine instead of just interacting with the virtual file system inside the browser’s sandbox.
Can you think of any other modifications that would help old Swing apps make the transition to the web?
Credits
This little experiment is only possible because CheerpJ has matured to the point where it can run Swing apps in a web browser without any modifications. It is really a magical piece of work.
Please read the CheerpJ license if you plan to deploy your own apps apps on the web, to ensure that you are compliant with its terms.
Whoops - get to answer my own question.
While the Swing is very old, the compile and jar package are new this year: javac -version = 19.x
Finally spotted the error: "Uncaught (in promise) CheerpJ only supports Java 8 at this time. Unsupported class ColoradoLakefinder"
Maybe catch this error and save us ancient programmers a long hunt?
Well, had no issues running ArgoUML. I have an old Swing .jar file that I would like to use in a browser. It works well from the command line >java -jar. I double checked that I was using the virtual mount point /app. The output from npx http-server -p 8080 shows an apparently successful GET <> for my jar file but the CheerpJ window stops with a spinning design. Since I am able to modify the size of the window in cheerpjCreateDisplay(), I assume it is stuck on the await function. But this is where my debugging skills fail me. Any suggestions on how to debug this would be most appreciated. System details: Firefox 123, Ventura 13.6, mini M2, blocking and virus scanning off, full-disk-access for JavaLauncher, Firefox.