2015-07-12

Es will einfach nicht klappen, Ausgabe 20150712

Seit vielen Versionen ist es out of the box möglich, aus Java heraus Scriptsprachen aufzurufen. Der JSR 223 (Scripting for the Java Platform) hat nämlich schon mit Java SE 6 Einzug in die Plattform gehalten.

ScriptEngineManager m = new ScriptEngineManager();

ScriptEngine engine = m.getEngineByMimeType("application/javascript");

String program = "print('Hello, World!')";

try {

    engine.eval(program);

catch (ScriptException ex) {

    LOGGER.log(Level.SEVERE, null, ex);

}


Regelmäßige Leser meines Blogs wissen, dass ich meine Java-Gewohnheiten gerne auch unter Android ausleben möchte. Warum also nicht zum Beispiel auf die oben gezeigte Weise JavaScript integrieren? Erste Antwort: weil das Paket javax.script einschließlich seiner Unterpakete nicht in der Android-Klassenbibliothek enthalten ist. Gut, aber zu jedem Java Specification Request gibt es eine Referenzimplementierung. JSR 223 macht da keine Ausnahme. Warum also nicht diese nutzen? Die wenigen Jars sind schnell hinzugefügt, der Code wird übersetzt, die App startet. ...rrruuuuuuummmmsssss...... Vielleicht erinnern Sie sich ja an meine glücklosen Versuche, JAX-WS zu nutzen. Der Pessimist in mir ist nun geneigt zu fragen, warum es gerade jetzt hätte funktionieren sollen. Aber natürlich ist einfach so aufgeben uncool, und deshalb habe ich kurz den Debugger bemüht. Das ernüchternde Ergebnis: die Implementierung möchte gerne die Klasse sun.misc.Service nutzen. Und die ist (natürlich) nicht vorhanden. Was bedeutet das?

JSR 223 setzt auf einen einfachen Serviceprovider-Mechanismus, der an unterschiedlichen Stellen in der Java-Standardklassenbibliothek Verwendung findet. Dazu wird in einem .jar-Archiv eine Textdatei META-INF/services abgelegt, die der Java-Konvention für Klassennamen folgt, zum Beispiel javax.script.ScriptEngineFactory. Sie enthält eine Liste von Klassen, die das Interface mit dem Namen der Datei implementieren. Auf diese Weise findet eine Entkopplung zwischen Vertrag und Implementierung statt. Bleibt die Frage, wie die Auflösung bzw. das Finden der implementierenden Klassen funktioniert. Tja, und hier kommt sun.misc.Service ins Spiel. Übrigens gibt es seit Java 6 die Klasse ServiceLoader. Sie scheint aus Service hervorgegangen zu sein. Die kennt Android seit API Level 9 sogar.

Dumm nur, dass die Referenzimplementierung von JSR 223 sie nicht nutzt. Mal sehen, ob ich mir in einer ruhigen Minute mal ansehe, wie aufwendig der Umzug wäre...

No comments:

Post a Comment