Jython

Alles, was nicht direkt mit Python-Problemen zu tun hat. Dies ist auch der perfekte Platz für Jobangebote.
Antworten
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Ich wollte Jython ausprobieren. Ich beschäftige mich gerade beruflich mit Scripting in Java und warum nicht auch Jython als Alternative zum im JDK 6 eingebauten JavaScript?

Javas Scripting API wird in JSR 223 definiert. Die meisten Scriptsprachen - auch Jython - behaupten, dies zu unterstützen.

Der Standard bei Java zur Verwaltung von Bibliotheken ist Maven. Der Weg zu Jython sollte also (für Java-Verhältnisse) einfach ein POM mit

Code: Alles auswählen

    <dependency>
        <groupId>org.python</groupId>
        <artifactId>jython</artifactId>
        <version>2.5.0</version>
    </dependency>
sein. Die aktuelle Jython-Version ist zwar 2.5.1, doch niemand hat das zentrale Maven-Repository bislang aktualisiert. Wenigstens gibt es überhaupt einen Eintrag.

Der folgende Code lädt dann Jython und führt ein Beispiel aus:

Code: Alles auswählen

    ScriptEngine engine = new ScriptEngineManager().getEngineByName("python");
    System.out.println(engine.eval("3+4"));
Denkt man. Leider hat man bei 2.5.0 vergessen, es JSR 223-kompatibel zu machen. 6,5 MB umsonst geladen. Googlen lässt vermuten, dass die Version 2.5.1 JSR 223 unterstützt, auch wenn es Bugs bezüglich korrektem Threading oder auch nur der Verwendung der ScriptContext-Objekte gibt. Nicht sehr vielversprechend.

Dennoch, ich brauche 2.5.1, einen Download gibt es leider nur in Form eines IMHO unpraktischen Java-basierten Installers. Ich wähle Standalone, weil ich glaube, dass dies der Version aus dem Maven-Repo entspricht. Das legt mir ein 8,7 MB großes jar unter /Users/sma/jython2.5.1 ab.

Ich ändere die Maven-Dependency auf 2.5.1, installiere das jar mit ``mvn install:install-file -DgroupId=org.python -DartifactId=jython -Dversion=2.5.1 -Dpackaging=jar -Dfile=/Users/sma/jython2.5.1/jython.jar`` zumindest in mein lokales Repo und versuche es erneut.

Es geht.

Nachstehendes Testprogramm liefert jedoch (wie im Bug-Report erwähnt), das falsche Ergebnis (2x 2 statt 1x 1 und 1x 2). Dabei sind die `Bindings` schon unterschiedlich. Und `b1.get("a")` und `b2.get("a") liefert jeweils null, was IMHO auch falsch ist.

Code: Alles auswählen

    Bindings b1 = engine.createBindings();
    Bindings b2 = engine.createBindings();
    engine.eval("a = 1", b1);
    engine.eval("a = 2", b2);
    System.out.println(engine.eval("a", b1));
    System.out.println(engine.eval("a", b2));
Schade. Ein Blick in den Quelltext offenbart, dass `Bindings` gar nicht benutzt werden. Für meine Zwecke unbrauchbar. Es sei aber gesagt, dass auch JRuby nicht viel besser ist. Sind Variablen bei Jython zu langlebig, sind sie bei JRuby IMHO zu kurzlebig und eine lokale Variable überlebt trotz selben `Bindings` nicht bis zum nächsten `eval`. Alles sehr frustrierend.

Aber man kann Jython ja auch direkt - ohne JSR 223 - einbetten. Es gibt sogar ein Buch zu Jython. Leider warnt Safari davor, dass die Webseite jythonbook.com Malware enthält. Hoffentlich ist das nur welche für Windows, denn Firefox hat mir die Seite einfach angezeigt. Googles Safe Browsing Dienst sagt, dass auf der Startseite am 06.12.2009 ein schädliches Programm gefunden wurde (ob es noch existiert, sagen sie nicht). Scary.

Ist es wirklich so einfach?

Code: Alles auswählen

    PythonInterpreter interpreter1 = new PythonInterpreter();
    PythonInterpreter interpreter2 = new PythonInterpreter();
    interpreter1.exec("a = 1");
    interpreter2.exec("a = 2");
    interpreter1.exec("print a");
    interpreter2.exec("print a");
Dies liefert das gewünschte Ergebnis. Einen neuen Interpreter zu starten dauert dabei etwa 1ms. Zum Vergleich: Einen Interpreter für das eingebaute JavaScript initialisiert sich in 0,5ms.

Stefan
Antworten