jDeploy vs jpackage+GitHub Actions
Solving the desktop deployment problem with two completely different, yet not necessarily mutually exclusive approaches
jDeploy is the embodiment of my self-described, successful attempt to simplify the deployment process for Java apps on the desktop. I’m proud to say that it is now possible, nay trivial, to build native bundles for all platforms, from any platform. I.e. you no longer need to have a Mac to build a native Mac app, you don’t need a Windows machine to build a Windows app, and you don’t need a Linux machine to build a Linux app. You can build them all in one shot using jdeploy package
or jdeploy publish
on any platform with a JDK installed.
Needless to say, I was pretty pleased with myself when I got this all working for the first time. As far as I was concerned, I had solved the major pain-point of a generation, second only to world peace. So, for my newsletter a couple of weeks ago, I descended the slopes of Mount Sinai to deliver this secret formula to my kin, and then drop the mic.
Unfortunately, I found that during the course of the ten years I’d spent acquiring wisdom atop the mountain, the world had moved on. When I began my expedition those many years ago, a development environment was contained wholly inside a single computer. Java software developers were free to choose whichever hardware and operating system they liked, and they could choose between a healthy assortment of IDEs (or none at all, if they preferred), but they still had to choose one. You would, of course, keep a few test machines around to be able to test your creations on different OSes, and certain occasions might require you to even provision a backup development environment on a different OS, but, for the most part, you could toil away comfortably in the one castle that you constructed on your prize plot of silicon, and churn out your beautiful, cross-platform creations for the world to wonder at.
Building native desktop installers was one of those tasks that required you to dust off the old backup development machine. You might think this is no big deal, but for me it is. Context switches are painful. Even having to switch to a different IDE on the same machine gives me cramps. Switching to a different machine, it just begging to end my productivity for the day. Instead polishing up my app, I’m spending the afternoon, installing updates on a machine that I haven’t used in a few months, running on an operating system that is a little bit foreign, trying to remember where is stored in an unfamiliar file system.
Imagine the excitement that I would inspire world-wide when I announced that Java developers no longer needed to fire up that rickety backup development machine every time they wanted to build their app for Windows. Cue confetti and “We are the Champions”, by Queen.
Well, to a few die-hards, my announcement was received well, but I haven’t heard any reports of confetti, and none of the coincidental playings of “We are the Champions” could be definitively traced back to my newsletter. The reason it didn’t make a “huge” splash is because recent advances in continuous integration technologies have mitigated this pain point via an entirely different approach.
GitHub Actions: “You were saying?…”
GitHub actions was introduced in October 2018 for paid accounts only, and was opened up to free accounts also just over a year later, in November 2019. It allows you to trigger jobs to be run on machines of your choice in response to various events related to your GitHub repository. For example, you can have it compile your project and run unit tests in response to every commit. If the tests fail, GitHub will send you an email letting you know that your project is broken. Cool, eh?
But the “unit tests” workflow is just the tip of the iceberg. Want to run your unit tests on five different flavours of linux, 3 different Mac versions, and a few different versions of Java? You can do that to. All you need to do is create a simple little workflow file inside the .github directory of your project that tells GitHub what to do. It will automatically fire up containers to run your workflows on demand. If you request jobs on multiple different operating systems, it can even run those in parallel, and you can monitor the progress in real time.
So while I was busy trying to find a way to build native bundles in a platform-independent way, GitHub had gone out and drastically reduced the amount of pain involved in maintaining multiple development environments.
In light of this, it shouldn’t be surprising that someone, Will Iverson, posted a reply to my newsletter on Twitter sharing his GitHub repository that includes workflows to generate native bundles on Linux, Windows, and Mac - and sign and notarize the Mac bundles using GitHub actions. He uses jpackage in his workflow, which is the “official” tool for building native bundles. It really is a nice project template - accessible and well-documented. If you’re looking to distribute a Java desktop app as a native bundle, I recommend you check it out. At the very least, you can check the arguments he uses for jpackage, and how he automates the code-sign and notarization process, even if you don’t want to use the template in its entirety.
Will’s reply received far more retweets than my newsletter Tweet. And for good reason. I was solving 2011’s problem. Will has solved 2022’s.
Sidebar: I haven’t been living under a rock. I was well aware of GitHub actions, and I use them in many of my projects - including in jDeploy to automate many aspects of the build and test process, including the signing and notarization of the jDeploy installer. I am also contemplating adding better support for using jDeploy inside GitHub actions. That said, many of the pain-points that I intended to address with jDeploy are were more prevalent in the world before GitHub actions, and as the proud owner of a LaserDisc player, I adapt to new paradigms with caution and reluctance, if at all.
So is jDeploy Redundant?
I used to watch a TV show called Doogie Howser, MD, about child-prodigy who becomes a doctor at the age of 14. It starred Neil Patrick Harris of How I Met Your Mother, and er.. Doogie Howser fame. In one episode I remember Doogie’s dad proudly declaring that his decade-long research study was complete. After describing its significance, Doogie, says, “Hold on a minute”, then goes to his bedroom to find a magazine - some sort of medical journal. “It sounds a lot like this study”, he says, as he folds it open and shows it to his dad. The Dad, recognizing that his “life’s work” had already been published by someone else, closes the magazine and sulks back to his room, where, he begins a period of soul searching, and depressed resignation.
Am I the Dad in this story? Did “old man” jDeploy just get shown up by the new, hip thing? Maybe, but I don’t think so. I’ll admit that I still work in an old-school mindset where I want to be able to build everything on my local machine, but I do recognize, if only dimly, the great possibilities that GitHub actions promises. I just prefer to think of these CI goodies as “nice-to-haves”; frosting on the cake. I still like to the cloud at arms length. Using it when it suits me, but not so dependent I’d be helpless in its absence.
It is also worth noting that a “cross-platform” deployment process is only one of several goals I had for jDeploy. I also wanted to make it easier to distribute updates to my users. jDeploy’s auto-update mechanism makes this process seamless, as the app will automatically check for updates every time it launches, and download updates as required.
A Closer Look
Let’s take a closer look at Will’s repo for a moment, to get a feel for what would be involved in deploying an app. On Mac, it looks like the process is roughy:
Create a development certificate if you don’t have one yet.
Enter your certificate identify name in the pom.xml file:
<macos.sign.identity>--mac-signing-key-user-name "Company Name, Inc. (BXPXTXC35S)"</macos.sign.identity>
Based on the Workflow file, you need set some secrets. He has kindly commented which secrets you need to set:
# MACOS_CERTIFICATE (base64 Certificates.p12 | pbcopy) # MACOS_CERTIFICATE_PWD (password for the .p12 file) # APP_EMAIL (Apple ID Email address used for notarization) # APP_PASS (App specific password for Apple ID email address, https://support.apple.com/en-us/HT204397)
This template doesn’t eliminate all of the tedium in deploying apps, but it helps significantly. You still need to have an Apple developer account, and you still need to generate a developer certificate, import it into your keychain, export it from your keychain, convert it to a base64 string, copy it into GitHub settings as a “secret”, generate an app-specific password (in your Apple Developer account), and then copy these details into GitHub actions. That all is still a huge PITA - but you only need to do it once in a while, and then it will just happen for you magically every time you release a new version on GitHub. That’s super cool!
The GitHub Project Templates Trend
Will’s project template is an example of a wider trend that I’ve noticed over the past few years, which is the proliferation of project templates distributed as GitHub repositories. Rather than starting projects “from scratch” using your IDE’s “New Project” wizard, or via a command-line project creation tool (e.g. mvn archetype:generate
), you simply find a template on GitHub for a project that is already configured to do most of what you need, and simply “Fork it”.
The power of this approach to disseminating project templates lies in its simplicity and accessibility, both to the producer and the consumer. Anyone can create a GitHub repo, and anyone can fork it. It is orders of magnitude easier than, for example, creating and publishing a custom Maven archetype, or creating a custom plugin for IntelliJ or NetBeans. In addition, tying the template’s distribution to GitHub allows it to seamlessly incorporate GitHub actions directly into the project.
One weakness of this approach is that it doesn’t deal with project “personalization”. E.g. If you fork Will’s repo, you get a project with sources that use his package namespace, and possibly other aspects that you would likely wish to customize. In some cases you can safely just open the project in your IDE and refactor the package to “com.yourdomain.xyz”, but it is possible that his packages are referenced in parts of the project that IntelliJ can’t deal with, so that, in doing this refactor, you are breaking things inadvertently. This can be resolved by providing a “configure” script that allows users to customize aspects of the project in a more controlled fashion. I’m almost certain that someone somewhere has already created a tool that solves this problem, but I haven’t seen or used any tools like this myself - other than my own configure scripts.
Are Desktop Development Tools Obsolete?
Over the past 20 years, we’ve seen the importance of desktop apps decline to niche status. Most applications have emigrated to the web for its ease of deployment, but a few stubborn app categories have survived the exodus thus far. “Development tools” is one such genre that has remained strong on the desktop, but it would appear that the the writing is on the wall, and the cloud will soon be coming for it also. Many cloud IDEs have already sprung up, but I wouldn’t say they have reached even close to mainstream yet.
I have a suspicion that the takeover will happen in a similar fashion to the original HTML5 coup, when Google Maps proved its case definitively. The thing about development tools that have kept them on the desktop is that they need to operate on local files. Moving these files to the cloud was complicated because many other, mature, parts of the toolchain were developed for local machine also. With GitHub actions, however, the pieces are now in place to plausibly have a good development experience entirely in the cloud, using a web-based UI.
I think this is a very cool trend, but, as always, I’ll be one of the late adopters - dipping my toe into the waters to see what goodies the new paradigm can offer, and incorporating them where I can, without supplanting my current, beloved paradigm. But eventually, I’m sure that I too will be dragged into the future, probably kicking and screaming, clinging to my desktop environment by my bloody fingernails.
Where does jDeploy fit in?
So where does jDeploy fit into this brave new “cloud” world? I think it fits nicely. The goal of jDeploy is to make Java a more compelling platform for desktop development, and it already does this by making the deployment process trivial. Projects like Will’s serve as an inspiration to help guide new features. For example, why not add support for a more conventional workflow into jDeploy where it makes sense. Additionally, why not fork Will’s repo and add a Github Actions workflow that uses jDeploy. This is what I love about open source - it is simultaneously collaborative and competitive. We’re all working toward the same goal of making the world a better place be building cool things.
New Demos
Before I close out this week’s newsletter, I’d like to highlight a couple of new demos that I’ve added to the jDeploy homepage. Actually, they’re not “demos” per-se, they are real applications - I’m just calling them “demos” because they are demonstrations of apps that use jDeploy for their desktop deployment.
JFXCentral. JFXCentral is your one-stop destination for anything JavaFX: people, libraries, real world examples, tools, documentation, videos, books, tutorials, tips and tricks, downloads.
SnapCharts. SnapCharts is a chart design app and library for Java and JavaScript. It was developed in SnapKit, which I discussed in a previous newsletter. One cool thing about SnapCharts, and SnapKit in general, is that is deployed as both a desktop app and a web app - and the user experience in web and desktop are both very high quality, and practically indistinguishable from one another. Read more about SnapCharts here.
If you want your app added to the jDeploy demos section, please contact me.
Finally, if you enjoy reading about topics related to Java desktop development, please consider subscribing to this newsletter. By subscribing you are letting me know that I’m not the only one who still cares about Java on the desktop - and you’re ensuring that you won’t miss an issue.
Until next time, I wish you peace and happy coding!
When I started my degree, logging into UNIX (or mainframe) development server, and use remote editors, or for those lucky ones with X Windows terminals IDEs, was common practice in universities and most big corporations healthy enough to have computing rooms.
If anything, the modern cloud, with browser based terminals, or IDEs, is yet another cycle of everything new is old again, where we mostly changed the underlying technologies while keeping most of the concepts.
This is specially relevant in an age where most developers seem only keen to pay for development tools when they are placed behind a SaaS paywall, hence the push to go back into the classical timesharing development workflows.
Gitpod convinced me that browser-based IDEs work. But it will take some time to replace Intellij...