Andreas Rozek Lesehinweise letzte Änderungen Gästebuch-Eintrag Mitteilungen an den Autor  English Version  zur Leitseite zum vorherigen Thema zum nächsten Thema  zur ersten Seite zur vorherigen Seite zur nächsten Seite

Eine einfache Laufzeitumgebung für Rhino-Skripte

Die vorliegende Seite beschreibt eine einfache Laufzeitumgebung für Rhino-Skripte, die sich von der zur Rhino-Distribution gehörenden "Shell" durch einen veränderten Funktionsumfang unterscheidet und für die Ausführung der Beispiele in der "Schritt für Schritt"-Reihe benötigt wird.

Rhino.java - eine einfache Laufzeitumgebung

Die hier vorgestellte Laufzeitumgebung ist ursprünglich aus dem Wunsch des Autors entstanden, die Vorgänge innerhalb des zur Rhino-Distribution gehörenden "Shell"-Beispieles zu verstehen. Schon bald kamen jedoch weitere (interne) Funktionen hinzu, wodurch das Programm zur Grundlage der "Schritt für Schritt"-Beispiele wurde.

Die "Rhino"-Umgebung des Autors ist keine interaktive Shell, sondern ermöglicht lediglich die Ausführung von beim Aufruf benannten (oder zur Laufzeit nachgeladenen) Skript-Dateien.

Übersetzung

Der Quelltext der "Rhino"-Umgebung ist frei verfügbar und kann wie folgt übersetzt werden:

  javac Rhino.java

Bitte beachten Sie, daß das Programm eine zusätzliche Klasse namens sunda.rhino.System benötigt, die ein Rhino-"Host Object" mit Funktionen aus der Java-Klasse java.lang.System implementiert. Diese Klasse sollte zuvor separat übersetzt worden sein.

Aufruf

Der Aufruf der "Rhino"-Umgebung ist denkbar einfach:

  java Rhino <filename> [<argument> ...]

Darin bedeuten:

filename

Datei- bzw. Pfadname der auszuführenden Rhino-Skriptdatei. Sofern diese Datei die Endung ".js" trägt (und keine andere Datei mit demselben Namen, aber ohne die ".js"-Endung vorliegt), muß die Endung nicht mit angegeben werden. Inwieweit die Groß-/Kleinschreibung des Dateinamen für das Auffinden der Datei wesentlich ist, hängt von dem Betriebsystem ab, unter welchem die "Rhino"-Umgebung ausgeführt wird;

argument

ein optionales Argument, welches von "Rhino" beim Aufruf als Bestandteil eines (globalen) "arguments"-Feldes an das auszuführende Skripte übergeben wird. Im Rahmen der verfügbaren Resourcen sind beliebig viele Aufrufargumente zulässig;

Das ausgeführte Skript hat Zugriff auf die Datenströme "stdin", "stdout" und "stderr" und kann am Ende mithilfe der (internen) Funktion "exit" einen numerischen "return code" zurückliefern.

Interne Funktionen

Die "Rhino"-Laufzeitumgebung verfügt über folgende eingebaute Funktionen:

complain ([<argument>, ...])

gibt die angegebenen (optionalen) Argumente (nach Konvertierung in Zeichenketten) ohne Zwischenräume und abschließenden Zeilenvorschub auf "stderr" aus. "Ausgelassene" Argumente (zwischen zwei unmittelbar aufeinanderfolgenden Kommata) werden als "undefined" ausgeschrieben;

complainln ([<argument>, ...])

gibt die angegebenen (optionalen) Argumente (nach Konvertierung in Zeichenketten) ohne Zwischenräume, aber mit einem abschließenden Zeilenvorschub auf "stderr" aus. "Ausgelassene" Argumente (zwischen zwei unmittelbar aufeinanderfolgenden Kommata) werden als "undefined" ausgeschrieben;

defineClass (<classname> [, ...])

lädt die namentlich angegebenen Klassen (für Rhino "Host Objects") und stellt sie unter JavaScript zur Verfügung. Die Klassennamen müssen zusammen mit dem vollen Namen des Java "Package" angeschrieben werden, zu dem sie gehören. Fehler beim Aufsuchen, Laden oder Initialisieren der Klasse haben das Werfen einer Ausnahme zur Folge;

exit (<return code>)

beendet sowohl das Rhino-Skript als auch die zugehörige Laufzeitumgebung und gibt den angegebenen (numerischen) "return code" zurück;

input () -> String

liest ein einzelnes Zeichen von "stdin" und liefert dieses als Zeichenkette an das aufrufende JavaScript-Makro zurück - falls "stdin" keine weiteren Zeichen mehr enthält, liefert input() das null-Objekt zurück. Fehler beim Lesen von "stdin" haben das Werfen einer Ausnahme zur Folge;

inputln () -> String

liest von "stdin" alle Zeichen bis zur nächsten (Plattform-abhängigen) Zeilenendebedingung (oder bis zum Ende von "stdin") und liefert diese als Zeichenkette an das aufrufende JavaScript-Makro zurück - falls "stdin" bereits vor Aufruf der input()-Funktion keine Zeichen mehr enthält, liefert diese das null-Objekt zurück. Fehler beim Lesen von "stdin" haben das Werfen einer Ausnahme zur Folge;

load (<filename> [, ...])

lädt alle namentlich angegebenen Skript-Dateien und führt diese in der angegebenen Reihenfolge nacheinander aus. Sofern eine Datei die Endung ".js" trägt (und keine andere Datei mit demselben Namen, aber ohne die ".js"-Endung vorliegt), kann die Endung auch entfallen. Inwieweit die Groß-/Kleinschreibung des Dateinamen für das Auffinden einer Datei wesentlich ist, hängt von dem Betriebsystem ab, unter welchem die "Rhino"-Umgebung ausgeführt wird. Fehler während der Ausführung einer Skript-Datei haben das Werfen einer Ausnahme zur Folge;

print ([<argument>, ...])

gibt die angegebenen (optionalen) Argumente (nach Konvertierung in Zeichenketten) ohne Zwischenräume und abschließenden Zeilenvorschub auf "stdin" aus. "Ausgelassene" Argumente (zwischen zwei unmittelbar aufeinanderfolgenden Kommata) werden als "undefined" ausgeschrieben;

println ([<argument>, ...])

gibt die angegebenen (optionalen) Argumente (nach Konvertierung in Zeichenketten) ohne Zwischenräume, aber mit einem abschließenden Zeilenvorschub auf "stdin" aus. "Ausgelassene" Argumente (zwischen zwei unmittelbar aufeinanderfolgenden Kommata) werden als "undefined" ausgeschrieben;

sleep (<duration>)

setzt die Ausführung des laufenden Rhino-Makros für die angegebene Anzahl von Millisekunden aus;

Zusätzlich stellt die "Rhino"-Umgebung ein globales "System"-Objekt bereit, mit dessen Hilfe eine Reihe von Plattform- und Umgebungsspezifischen Einstellungen abgefragt werden können.

Rhino.js - Beispiele für die Funktionen der "Rhino"-Umgebung

Die Skript-Datei "Rhino.js" enthält Beispiele für eine Reihe der zuvor angegebenen, von der "Rhino"-Umgebung bereitgestellten globalen Funktionen und kann gleichzeitig als einfacher Funktionstest für diese Umgebung dienen.

Das Skript selbst ist sehr einfach und bedarf keiner weiteren Erklärung - von besonderem Interesse ist höchstens die Funktion "printable(<String>)", welche nicht-druckbare Zeichen aus einer gegebenen Zeichenkette entfernt und gegen eine gleichwertige Ersatzdarstellung austauscht. Dabei wird von der Möglichkeit Gebrauch gemacht, in der "replace"-Methode für den Ersatztext statt eines Literals eine JavaScript-Funktion anzugeben, die den Ersatztext (in Abhängigkeit vom zu ersetzenden Zeichenketten-Ausschnitt) zur Laufzeit berechnet:

/*******************************************************************************
*                                                                              *
* Printable      converts non-printable char.s of a string into printable ones *
*                                                                              *
*******************************************************************************/

  function Printable (Argument) {
    if ((Argument == null) || (typeof(Argument) == "undefined")) return "";

    return Argument.replace(
      /[\x00-\x1F\x7F-\x9F]/g,                                 // search pattern
      function (oldString, Offset, Candidate) {          // replacement function
        switch (oldString) {
          case "\b": return "\\b";
          case "\f": return "\\f";
          case "\n": return "\\n";
          case "\r": return "\\r";
          case "\t": return "\\t";
          default:   return "\\x" + oldString.charCodeAt(0).toString(16);
        };
      }
    );
  };

Das komplette Beispielprogramm kann wie folgt aufgerufen werden:

  java Rhino Rhino.js [<argument> ...]

Auf dem Rechner des Autors ergibt sich nach einem Aufruf der Form

  java Rhino Rhino.js one_word "multiple words" "multiple words with \" in between"

(von der "MS/DOS-Eingabeaufforderung" aus) folgendes Bild (Benutzereingaben sind grün markiert):

  Rhino - a simple tester for the author's Rhino shell

  given Arguments:
    1: "one_word"
    2: "multiple words"
    3: "multiple words with " in between"

  testing evaluation of "external" scripts:
    (Rhino_External.js - this script has been loaded from disk)

  testing output on "stderr":
    (this is just a test - actually there is nothing to complain)

  testing "System" object:
                 User Name = Rozek
       User Home Directory = C:\WINDOWS
    User Working Directory = C:\Rozek\Java\RhinoStudies
                   OS Name = Windows 98
           OS Architecture = x86
                OS Version = 4.10
            File Separator = \
            Path Separator = ;
            Line Separator = \r\n
        JavaScript Version = 0
             Rhino Version = Rhino 1.5 release 2 2001 07 27

  testing input from console
    please input a single character: this is a test
    You entered "t"

    please input some text and press "return" or "enter":
    You entered "his is a test"
  exiting with return code 1...

Aufgrund der direkten Texteingabe von der Konsole aus muß nach der Eingabe des angeforderten Zeichens die RETURN-Taste betätigt werden - ansonsten verbleibt die Eingabe im Tastaturpuffer der Konsole und wird nicht an die "Rhino"-Umgebung ausgeliefert. Werden mehr als die verlangten Zeichen eingegeben, so verbleiben die überzähligen Zeichen im Puffer und werden von einem späteren Aufruf der "input()"-Funktion eingelesen. Im vorliegenden Fall muß die zweite Eingabe nicht einmal mehr mit der RETURN-Taste quittiert werden, denn auch dies ist ja zuvor bereits geschehen...

Dies sind jedoch bekannte Probleme, unter denen auch Java zu "leiden" hat.

Quelltexte

Alle hier vorgestellten Programme und Skripte sind im Quelltext verfügbar:

Literaturhinweise

[1]

Norris Boyd
Shell.java
(siehe http://lxr.mozilla.org/mozilla/source/js/rhino/examples/Shell.java)
die "Rhino"-Umgebung des Autors beruht auf dem Quelltext des zur Rhino-Distribution gehörenden "Shell"-Beispieles;

[2]

(Netscape)
Tutorial: Embedding Rhino
(siehe http://www.mozilla.org/rhino/tutorial.html)
die angegebene Anleitung beschreibt verschiedene Verfahren zur Verknüpfung von Java und JavaScript (Rhino);

Haftungsausschluß

Bitte beachten Sie auch den Haftungsausschluß des Autors!

http://www.Andreas-Rozek.de/Rhino/Acquainting/Rhino.html    (letzter Stand: 06.04.2002)