A Javaworld tutorial describes how to write and integrate your own script engine with Java SE 6, using the "Scripting for the Java Platform" JSR (223). The article sets up an example scripting language, and proceeds to enable Java applications to use this new language via the JSR 223 API.
While several scripting languages have integrated with the JVM, enabling Java programs running in a VM to be "scriptable," JSR 223, "Scripting for the Java Platform," defines how to integrate any scripting language with the Java SE 6 platform. The JSR's name is a bit misleading, as such integration is not limited to scripting languages: JSR 223 allows integration of any language interpreter and compiler to integrate with the JVM.
Chaur Wu's recent Javaworld article, Build your own scripting language for Java, provides a detailed JSR 223 tutorial. It starts by defining a simple scripting language and that language's interpreter. It then shows how to integrate such a scripting language with the VM:
A script engine provider needs to package all the classes that implement a script engine plus one extra file in a jar file. The extra file must have the name javax.script.ScriptEngineFactory. The jar file must have the folder META-INF/services, and the file javax.script.ScriptEngineFactory must reside in that folder. [...] The content of [that] file [...] must contain the full names of the classes that implement ScriptEngineFactory in the script engine. [...] Users of the script engine install the script engine by putting the jar file in the Java classpath.
A script engine so packaged can be discovered at runtime, and even associated with a file extension for files containing the script code.
The interface for data exchange between a script running in the script engine and Java code invoking that script, occurs through Bindings and ScriptContext:
You can think of a context as a bag that contains data you want to pass back and forth between a host Java program and a script engine. The construct that JSR 223 defines to model the context is the interface javax.script.ScriptContext. [...] A script context [...] partitions data it holds into scopes. The construct that JSR 223 defines to model the concept of scope is the interface javax.script.Bindings.
Wu then explains that a script engine contains a script context, and the script engine manager (that potentially manages multiple script engines) contains a global scope shared by multiple script engines. A scope is a collection of name-value pairs, and is an instance of javax.script.Bindings. Context in a single script engine contains the global scope, an engine scope, and zero or more other scopes.
Wu's final example shows that a script integrated via JSR 223 into the JVM can be both interpreted and compiled:
This whole process of evaluating BoolScript [Wu's example scripting language] code is called interpretation, as opposed to compilation. And in this role, the BoolScript engine is called an interpreter, as opposed to a compiler. To be a compiler, the BoolScript engine needs to transform the textual BoolScript code into an intermediate form so that it won't have to parse the code into an abstract syntax tree every time it wants to evaluate it.
Wu mentions, but does not illustrate, that scripting language code can be compiled into Java bytecode via the Java Compiler API (JSR 199).
Several recent discussions on Artima focused on domain-specific languages (DSLs) and code generation. Integrating a language interpreter into Java allows yet another way to use a custom DSL, or any other language, that operate on, or is invoked from, Java classes.
To what extent do you think scripting language interpreter integration will make developing Java applications easier? Do you envision yourself creating a language interpreter for a DSL and use JSR 223's integration mechanism to tie that into your Java program? Or do you think that JSR 223's use will be limited to integrating already established scripting languages with Java?