JavaUtils: Detecting and Installing Java from AIR
Adobe AIR is a great way to bring the sexiness of Flash to the desktop. However, sometimes you need more low-level power for things like connecting to peripherals. For this reason, AIR applications are sometimes paired with Java applications to accomplish such tasks. But first, the user’s system must have an adequate Java Runtime Environment (JRE) installed in order for the Java application to run in the first place.
Before we get too far, be aware that these JavaUtils are currently for Windows only. Macs have their own version of the JRE that’s deployed through the Software Update feature so the process of detecting and installing the JRE is very different and is left for another day.
The Short Story
To get started with the utilities, first download the source by checking out the git repository or installing the sample application. If you choose to install the sample application, run the app and right-click on the stage to view the source.
The utilities include two executables:
- whereis.exe — This is used internally by the tools. See the juicy details below if you care to learn more about this.
- jre-blah-blah-blah.exe — This is the Windows JRE online installer found here: http://www.java.com/en/download/manual.jsp. This is the installer that is used to install a JRE of your choice if the user’s system does not have an adequate JRE already installed. Because it’s the “online” installer, it’s lightweight and lets you avoid bundling an entire JRE with your AIR app.
There are two main utility classes:
- JavaValidationUtil — This is used to determine if the user has an adequate JRE installed. Call validate() and it will dispatch an event letting you know if the user has a JRE installed and if the version is sufficient.
- JavaInstallUtil — This is used to install the JRE if needed. Call install() and it will dispatch an event letting you know when the installation is complete.
The Juicy Details
Let’s dig into the details of how this works. Support for running other executables as described below comes from the new NativeProcess in AIR 2.0.
Validation. The first chore is to validate whether the user has a JRE installed and, if so, whether the JRE is sufficient for the application’s needs. The developer provides the validation utility with a minimum acceptable version broken into four segments: major, minor, revision, and update.
Now we need to find the version of the installed JRE to compare. But first we need to find out where the JRE is installed if one exists. On Windows there’s an environment variable called PATH which contains several directories that should be searched to find an application when a command is executed in the command shell. When you open up cmd, for example, you can type “notepad” and hit enter. The fact that it’s able to open notepad isn’t magic. Windows simply searches the PATH directories for notepad.exe and then executes it.
We need to do the same thing to find the java executable (java.exe). On *nix operating systems this is pretty easy. There’s a simple tool called whereis that comes with the operating system that searches the paths to find a given executable. On Windows, not so much. Luckily, our friends over at Synesis have released a similar tool for Windows that allows us to do the same thing. We bundle whereis.exe with our AIR application.
We execute whereis.exe, passing in name of the executable we’d like to find (java.exe) as an argument. If we don’t find java.exe, the user doesn’t have a JRE installed — at least not in the PATH paths. And if a JRE does exist that’s not in those paths it could take a long time to find and we probably don’t want to mess with it anyway. If java.exe is found, we then execute it passing in the -version argument. Java will then output the version in a specified format that we can then parse. After we parse the version, we compare with the minimum acceptable version and dispatch appropriate events.
Installation. If no JRE is installed or the one installed isn’t adequate, the application would then generally notify the user they need a newer JRE and ask if they’d like to proceed with the installation.
If the user chooses to proceed, it’s time to execute the installer. But there’s a catch. In Windows, installer applications require “elevated privileges” before executing which means Windows nags the user asking for permission to install the JRE. If I were to double-click the installer when it was on the desktop, it would appropriately nag. However, if I execute the installer using AIR’s NativeProcess, nothing happens. No error, no output, no nagging, no installing, nothing. Is this a bug in AIR? Eight ball says signs point to yes, but who knows, maybe Windows is to blame.
In my search for a workaround I found that by executing the installer from the command shell, Windows again appropriately nagged. So then I tried executing cmd from AIR and having cmd execute the JRE installer by passing the path of the installer into cmd as an argument. What do you know — Windows nagged appropriately and off goes the installation as planned. When presenting this problem on the Adobe AIR forums, not receiving a response, then proposing the workaround, a member of the AIR engineering team seemed to think it was a good trick — nay, a great trick — so I guess that’s just the way we have to do things for now.
So first we use our trusty whereis.exe to find the location to cmd.exe. Then we use cmd.exe to execute our Java installer by passing the installer path into cmd as an argument. Windows prompts the user for permission and after permission is granted the installation proceeds as expected. After the installation is complete, we dispatch an appropriate event. Of course we also stay aware of fringe cases (like if the user cancels the installation) and likewise dispatch appropriate events.
Hopefully that’ll give you some good direction as you start your journey pairing your AIR app with Java. Now go make something freaking fetching awesome.