I had to find a way to call existing ActionScript code from a Java application. The options that I could find are these:
Calling an AIR application as a program from Java
One option is to call the AIR application as a program from Java. This may be the best for tiny interfaces where the AIR application has to do a task where the results are naturally a file or files, and / or an exit status. The disadvantage is the performance loss due to the process start / stop overhead of the child processes. So if really many processes have to be started (probably more than 0.5-10 a second on average, depending on what the processes must do), it is advisable to use the Merapi Java/AIR bridge, as the AIR process keeps running there.
- The AIR standalone application would be called from within Java using the a java.lang.Runtime#exec method. See http://www.exampledepot.com/egs/java.lang/Exec.html . Or better, a preexisting wrapper class that allows comfortable execution of external programs from within Java.
- AIR allows file system access to write the output files: http://de.wikipedia.org/wiki/Adobe_Integrated_Runtime
- AIR allows reading command line arguments for input (which might be file names of XML files for more comlex input). [Source]
- You probably want the AIR application to run like a command line tool, just performing its task and then exiting. For that, you perhaps need to configure it specially to run without a graphical interface resp. to start without a desktop environment being available. For that, the “
--display” option of X86-based programs might help.
The Merapi AIR/Java bridge
The Merapi project seems to be another good option. It is a messaging framework, including two-way remote procedure calls. It uses the Flex Message Service, but between a Java and an AIR desktop application, avoiding the overhead of local HTTP communication and J2EE containers. Source: http://forums.adobe.com/thread/24523. (This overhead is present in remoting frameworks using the Flex Message Service, such as BlazeDS, detailed below. However, Merapi still has performance limitations as it uses socket-based inter-process communication, which is necessarily slower as pipe-based communication with stdin, stdout, stderr.) The Merapi website is at http://www.merapiproject.net/ .
The Flex message service
Another option could be to use a library based on the Flex Message Service, which is a message bus for communication of client and server. Available libraries include open source BlazeDS (http://opensource.adobe.com/wiki/display/blazeds/), commercial Livecycle Data Services, Granite DS, WebOrb or Exadel Flamingo. They allow to remote procedure calling of Java server methods from a Flex client, but not the other way. However, there is also the two-way messaging implementation in the libraries which allows to “send messages from Java to Flex that can trigger some sort of action on a Flexmessage listener object” (see http://groups.adobe.com/posts/f9e2699ee3), and thus to emulate reverse RPC calls. However the disadvantage is, the Flex Message service is a remoting framework, thus requiring the overhead of local HTTP communication and a local web server when using it to communicate between Java and an Adobe AIR desktop application. Introduction to the FMS: http://www.adobe.com/devnet/flex/articles/intro_fms.html.
Setting up the AIR application as a server
This is possible (as AIR applications can listen to ports), but it has some performance restrictions because it would involve local HTTP communication, just as the Flex message service. There are discussions on the Internet how to implement e.g. a HTTP server with AIR.
Loading ActionScript Code as a JNI library
Another option could be to compile the ActionScript code into a shared library (DLL on Windows) and then include that using the JNI interface. However, it could not be found out how to create a shared library from ActionScript code. Probably, it is impossible: ActionScript is normally running on a virtual machine (called AVM2), so one would need a special compiler that creates native binaries instead, comparable to what gcj does for Java. One can use the haXe compiler for that job; but while haXe is also ECMAScript, it is not ActionScript, which means that extensive changes will be necessary, esp. if one uses large ActionScript libraries. (These changes seem to be not that trivial, as for example Away3D took a long time before their haXe version of Away3D Lite came out. Also, if your ActionScript code depends on Flash classes like flash.display.Sprite, it seems that haXe cannot create a native library out of your application, as it does not have the source of the Flash and AIR runtime libraries available. Perhaps this could be solved with the just-in-time compiler included in the ECMAScript virtual machine Tamarin, but it would be a good amount of hacking.)
Creating your own AIR launcher
This is hardcore AIR hacking, and not apt for commercial distribution because of Adobe licensing restrictions [source]. The outlines of this have been discussed in the stackoverflow.com article “How can I load the AIR runtime as a in-process shared library from a C program” [link].
One possible architecture would be using the ECMAScript virtual machine Tamarin, then including some new ActionScript classes which are implemented in a native language (possible with Tamarin).
Additional tip for all alternatives
There are good chanes you might want to run your Java and AIR applications on a headless Linux server. Which is kind of a problem, as AIR needs always a running X server. For the solution, see my article How to run ActionScript in headless mode (on Linux without X server)?.