Java-6-Scripting mit JRuby

Know-how  –  Kommentare
Anzeige

Java 6 enthält eine Schnittstelle für den Einsatz von Script-Sprachen auf der Java Virtual Machine (JVM). Mit ihr lassen sich generisch Scripts in Sprachen wie Ruby und JavaScript aus Java-Programmen heraus aufrufen, und man kann damit von den Sprachen aus auf Java-Bibliotheken zugreifen, was die Wiederverwendung von Java-Bibliotheken erleichtert. heise Developer zeigt das Vorgehen am Beispiel von JRuby.

Oftmals stehen Entwickler vor der Situation, dass Java-Projekte mit Code aus anderen Programmiersprachen interagieren müssen. Das kann beispielsweise der Fall sein, wenn ein Systemmanagementwerkzeug in Java geschrieben ist, die Administratoren Erweiterungen aber lieber in Ruby oder Python schreiben wollen. Es gibt zwar den Weg, Programme oder Scripts via java.lang.Runtime.exec() aufzurufen. Das ist aber aufwendig und wenig performant, wenn das Script häufiger interagieren soll. Außerdem ist das Übergeben und Auslesen von Parametern und Rückgabewerten mühsam.

Vor JDK 6, Codename Mustang, gab es einige proprietäre Optionen, Script-Sprachen aus Java heraus aufzurufen. Da die Java Virtual Machine (JVM) schon lange nicht mehr nur eine Umgebung für die Programmiersprache Java bereitstellt, sondern sie auch viele andere Sprachen als Ablaufumgebung nutzen, lag es nahe, das Einbinden der Sprachen von Java aus zu vereinheitlichen.

Der JSR 223 führt mit javax.script ein Paket ein, das die Aufrufe dieser Sprachen in einer generischen Form erlaubt. Das prinzipielle Vorgehen ist immer dasselbe (Pseudocode):

1: ScriptEngineManager m = new ScriptEngineManager(); // Manager erzeugen
2: ScriptEngine engine = m.getEngineByXXX(); // Spezielle Engine
// laden
3: engine.eval(); // Skript ausführen

Der große Charme, die API des JSR 223 zu nutzen, liegt darin, dass das Vorgehen unabhängig von der eigentlichen Script-Sprache ist.

Eine Engine lässt sich auf unterschiedliche Weise suchen:

  • nach Namen mit getEngineByName(String name). Hier sucht man die Engine nach dem registrierten Namen der Script-Sprache; etwa getEngineByName("jruby"); für JRuby oder getEngineByName("JavaScript"); für JavaScript.
  • nach Dateinamenerweiterung mit getEngingeByExtension(String extension). Man sucht nach dem Suffix des Dateinamens (zum Beispiel .js oder .rb).
  • nach Mime-Typ. Das erlaubt, die Engine nach dem passenden Mime-Typ zu suchen. Dies ist allerdings nur in den wenigen Fällen sinnvoll, in denen eine Sprache einen registrierten Mime-Typ hat (etwa für JavaScript).

Damit das für eine Sprache funktionieren kann, muss eine Engine vorhanden sein, welche die Namen und Dateisuffixe registriert und die Brücke in die jeweilige Script-Sprache bietet. Mustang enthält mit der Rhino-Engine eine für JavaScript – andere Engines findet man unter hier, wobei manche recht alt sind wie die der Ruby-Implementierung für Java, JRuby. Man ist mit dem Download von der Projektseite besser bedient, da seit JRuby 1.4 die Integration Teil des JRuby-Downloads (jruby-complete.jar) ist, sodass man recht schnell loslegen kann.

Benutzern der JVM von Apple steht standardmäßig auch AppleScript als Script-Sprache zur Verfügung. Für Benutzer des Open JDK sieht die Welt leider anders aus: in einigen Versionen fehlt die Rhino-Engine, da Sun sie anscheinend aufgrund von Bedenken zur Lizenzierung herausgenommen hat. Hier lässt sich die Engine herunterladen und im Classpath installieren.

Generell lässt sich das Vorhandensein einer Script-Sprache über das Programm jrunscript herausfinden:

jrunscript -l <sprache> -e "Script-Ausdruck"

Ist die Sprache vorhanden, wird der Script-Ausdruck ausgewertet, ansonsten erhält man eine Fehlermeldung. Für die Sprache kann man sowohl den Namen als auch die Erweiterung verwenden, beispielsweise jrunscript -l js -e "1+1". Eine ausführliche Liste verfügbarer Sprachen findet sich unter hier.

Anzeige