I have been using Merapi for about six months now and so far I have been very pleased. However, in the project I have been working on there were two issues that we needed to solve that were not really addressed by Merapi or other members of the community.  They were:

  1. Installing Java and AIR with one installer
  2. Managing the Java and AIR sides of the application

Installation

This post is for Windows installers, for Mac-based installers, see my more recent Mac installer post. For the installation, the plan we came up with was that our installer would unpack 2 executables.  The first EXE would start the Java part of our application and would be the one that users would use to start the application (i.e. Shortcuts to this executable in the Quick Launch, Program Files, and the Start Menu).  The second EXE would be for the installed AIR application, and would be hidden from the user.  The jist of the plan was that the Java executable would start the AIR application. 

Here are the installation steps I took to accomplish this plan.

  1. Get the Adobe AIR Runtime for distribution
  2. Create an EXE to start the Java side of our application
  3. Package both the AIR and Java runtimes into an installer
  4. Figure out how to silently install the AIR runtime and our AIR application

Get the AIR Runtime

First, we obtained a license to distribute the Adobe AIR Runtime by applying here.  Once this was approved, we downloaded the Runtime, a sidecar installer, and some documentation from Adobe.  After evaluating the sidecar installer, we decided to create an NSIS installer for Windows instead.

Create an EXE to start the Java-side

Second, I created an EXE file out of our Java-side Jar file.  I used Launch4j to do this.  Launch4j allowed me the ability to reference the Merapi jar as well as other jars we are using for the project, and it allows you to reference the location for a Java Runtime that we could bundle in our installer.  We decided to package the JRE because it would give us more control over the version that all of our users had on their computer.

Package AIR and Java runtimes

Third, I had to package the Java and AIR runtimes in our installer.  This part was pretty easy.  Using NSIS, I bundled the JRE and AIR runtime into the installer.  The only trick was to make sure that my Launch4j configuration referenced the JRE installation directory. 

Silently install AIR runtime and AIR app

Finally, after packaging all of the necessary files into the installer, I had to instruct the installer to silently install the AIR runtime and the AIR-side of our application.  This was actually surprisingly easy to do.  The command to do a silent install from the Windows command line is:

1
ExecWait '"$INSTDIR\resources\AIR_Win_installer_files\Adobe AIR Installer.exe" -silent -location "$INSTDIR\resources" "$INSTDIR\resources\MyAirApp.air"'

$INSTDIR is a variable for the installation directory in NSIS.  The nice thing about this is that the user only needs to specify this directory one time.  Then, you can reference the Adobe AIR Installer.exe path in the installation directory.  The -silent option makes it so the user has no idea the AIR Runtime is being installed.  The -location option allows you to specify where the AIR application file should be installed to.  Finally, you can specify the location of the AIR file and the silent installer will automatically install it immediately following the silent install of the AIR Runtime.  Pretty sweet!

Managing Java and AIR

With the installation under control, we turned our attention to figuring out how to manage both sides of the installed application.  Our plan for this was that Java would immediately start the AIR application as soon as the user ran the Java executable.  Then, when AIR closed, it would send a message through Merapi to the Java-side telling it to close itself.  As a fail-safe, we also decided to include a kill switch for the Java-side in the event that somehow the AIR application had an exception and was unable to send a close message.

Here was the process in a nutshell:

  1. Start the AIR-side application from Java
  2. Kill the Java-side of the application when AIR closes
  3. Stop the Java-end if the AIR-side has an exception and is unable to tell Java it is closing

Start the AIR application

First, I figured out the path to the AIR executable by using the following line of code in Java:

1
String[] path = {System.getProperty("user.dir") + "\\resources\\MyAirApp\\MyAirApp.exe"};

The System Property: “user.dir” is the path of the Java executables installation location.  I used this to locate the AIR application’s executable.  Then I was able to start it by using:

1
Runtime.getRuntime().exec(path);

Kill Java-side when AIR closes

Second, to close the Java-side after AIR has closed, all I had to do was register an event handler to the close event on the Windowed Application in Flex.  In that handler, I sent a message to Java via Merapi to tell it to close itself.

Java Auto-Kill

Third, I built in an auto-kill switch on the Java process in the event that AIR closed without being able to dispatch a kill message to Java.  To do this, I used a Timer that would count down from 120 seconds.  Every time a message was received through Merapi, I would reset the Timer.  If that 120 seconds expired, I sent a ping to the AIR-side.  If AIR received a ping, it would immediately respond back to Java.  If Java didn’t hear back from AIR after 3 pings, it would close itself.

I hope this information is helpful for those who like to create an AIR app, but can’t rely on AIR alone.  Hopefully some of the shortcomings of AIR (starting/closing another programs, interacting with hardware, etc.) can be addressed and we won’t have to worry about having to integrate AIR with other technologies like Java.