How to execute AppleScript from a Java or Scala application

If you ever need to execute AppleScript from a Java or Scala application, this code shows how to solve the programming part of this problem.

Given an AppleScript command as a Scala multiline string, like this:

// press the `fn` key twice
val asCommand = """
tell application "System Events"
    key code 63
    key code 63
end tell
"""

you can execute that command by calling this executeAppleScriptCommand method:

val succeeded = executeAppleScriptCommand(asCommand)

whose source code is shown here:

/**
 * Executes the AppleScript command you supply as a String.
 * Returns `true` on success, `false` otherwise.
 */
def executeAppleScriptCommand(cmd: String): Boolean = {
    val scriptEngineManager = new ScriptEngineManager
    val scriptEngine = scriptEngineManager.getEngineByName("AppleScript")
    try {
        scriptEngine.eval(cmd)
        true
    } catch {
        case e: Throwable =>
            logger.error("EXCEPTION in AppleScriptUtils::executeAppleScriptCommand")
            logger.error(e.getStackTrace.mkString("\n"))
            false
    }
}

Of course there are other/better ways to handle the exceptions that can be thrown, but this gets you pointed in the right direction.

I use this code in my Sarah application, and I’m also using it in a new OS X “iTunes Alarm Clock” application I’m writing.

About the AppleScript command I showed

As the comment in the source code shows, the AppleScript command I shared at the start of this article emulates pressing the fn key on a Mac keyboard twice. I use this AppleScript code to automatically start the OS X speech recognition software whenever my new Sarah JFrame gets a WindowFocus event.

The AppleScript/Java configuration solution

As I mentioned, that covers the “programming side” of this solution. Starting somewhere around Mac OS X 10.7 or 10.8 and Java 7, you also need to add some configuration magic to your application. I describe that magic in this brief article, Configuring AppleScript to work with Java 7 and Mac OS X.

I don’t yet know if that solution works with Java 8 on the Mac platform, but I haven’t read anything that says there is a new approach on Java 8, so at the moment I assume it works there as well.

A more functional approach

As I mentioned, the method shown above isn’t very functional. Its return value depends on things besides its input parameter, and in other ways it can be made better. I fix all of these problems in a blog post titled, “Using functional programming (FP) thinking to make a Scala method better.”