Groovy Groovy zum Scripten

A

anonym

Gast
Hallo,

Ich nutze in einem Projekt Rhino als Engine für Embedded JavaScript. Leider ist das ganze ziemlich langsam. Hinzu kommt, dass Rhino seit 2009 nicht mehr gepflegt zu werden scheint (keine Bugfixes seitdem, es findet sich keine Roadmap für Erweiterungen, dass Projekt, aus dem es ursprünglich hervorgegangen ist, nutzt inzwischen eine andere ScriptEngine, viele Links auf der Projekthomepage führen ins Leere oder zu Dokumenten des Dachprojekts).

Für uns stellt sich die Frage, ob es sich lohnt, noch einmal umzuziehen, vielleicht auf Groovy. Deshalb hätte ich gerne eure Meinung, zu folgenden Punkten:

(a) Wird das schneller sein?

(b) Kann ich Groovy nach Bytecode kompilieren um oft benutzte Scripts noch schneller zu bekommen?

(c) Sicherheit. In Rhino haben wir es so hingebogen, dass nur Javaklassen mit einer bestimmten Annotation und/ oder Methoden mit einer bestimmten Annotation vom Script aus ansprechbar sind, alles andere bricht die Scriptausführung ab. So halten wir User effektiv von Dingen fern, an denen sie nicht herumspielen sollen (Klassen aus der Java- Standard- API, insbesondere die Reflection API, aber auch Klassen aus unserem Code, die schlicht und einfach nicht dafür gedacht sind, in den Scripts verwendet zu werden).

Und, mehr Zucker als Requirement:

(d) Ich muss teilweise Objekte, die die Nutzer im Script erstellen, aus einer Factory kommen lassen. Kann man den normalen Objekt- Erstell- Mechanismus aus Groovy (embbeded) auf eine Factory in Java umlenken? (Notfalls dürfen Scripts die Objekte halt garnicht instanzieren, sondern bekommen eine Instanz der Factory, deren Methoden sie nutzen dürfen).

Ich hoffe, ihr könnt wenigstens zu ein paar Fragen was sagen und bedanke mich schonmal. Falls ihr andere Languages als Groovy empfehlen möchtet, ich bin da nicht festgelegt.

Schöne Grüße,
anonym
 
B

bygones

Gast
(a) Wird das schneller sein?
selbst ein Ferrari kann falsch gefahren einen Trabbi nicht überholen....
ist abhängig - kann man nicht allgemein sagen. Groovy selbst ist etwas langsamer als Java zb, aber wenn Zeit für dich kritisch ist, ist zb mit Groovy++ dann fuer dich

(b) Kann ich Groovy nach Bytecode kompilieren um oft benutzte Scripts noch schneller zu bekommen?
??? Groovy wird immer zu Bytecode kompiliert ? Was dachtest du denn ?

alles was du in Java gemacht hast ist in Groovy umsetzbar. Jede Java Klasse/Programm ist automatisch Groovy.

(d) Ich muss teilweise Objekte, die die Nutzer im Script erstellen, aus einer Factory kommen lassen. Kann man den normalen Objekt- Erstell- Mechanismus aus Groovy (embbeded) auf eine Factory in Java umlenken? (Notfalls dürfen Scripts die Objekte halt garnicht instanzieren, sondern bekommen eine Instanz der Factory, deren Methoden sie nutzen dürfen).
die Frage verste ich nicht... "den normalen Objekt- Erstell- Mechanismus aus Groovy" - was soll das sein ? es ist der selbe wie in Java ?
 
A

anonym

Gast
oh, mhhh. Vermutlich hab ich nicht ganz klar gemacht, dass es darum geht Groovy als Scriptsprache in eine Java- Anwendung einzubetten. Dh. der Benutzer der Java- Application tippt seine Scripts ein, die dann ausgeführt werden. Die Groovy- Dokumentation nennt das "embedded Groovy" und ist, bis auf ein paar Details eben, sehr ausführlich.

selbst ein Ferrari kann falsch gefahren einen Trabbi nicht überholen....
ist abhängig - kann man nicht allgemein sagen. Groovy selbst ist etwas langsamer als Java zb, aber wenn Zeit für dich kritisch ist, ist zb mit Groovy++ dann fuer dich
Es geht darum, ob es schneller ist als Rhino. Das es langsamer ist als Java, ist klar.

??? Groovy wird immer zu Bytecode kompiliert ? Was dachtest du denn ?
Jop, ich weiß. Wenn ich es embedded als Scripts ausführe, müsste es aber eigentlich einen interpretierten Modus haben, oder sehe ich das falsch? Naja, dieser Teil der Frage hat sich eh erledigt, es geht ;) Bleibt nur die Frage, ob das Zeug überhaupt so einen interpretierten Modus hat...

alles was du in Java gemacht hast ist in Groovy umsetzbar. Jede Java Klasse/Programm ist automatisch Groovy.
Es geht darum, dass ich das ganze als dynamische Scriptsprache in eine andere Anwendung einbetten will. Dabei kommen die Skripte von anderen Leuten als die Original- Anwendung und ich möchte gerne verhindern, dass die Skript- Autoren Funktionalitäten nutzen, die nicht für sie gedacht sind. Überleg mal, was man in einer Anwendung alles anrichten kann, wenn man z.B. über Reflections an die Klassen dran geht...ich möchte also genau nicht, dass alles, was Java ist unter Groovy zur Verfügung steht. Die Frage ist, ob ich die Möglichkeiten, die Groovy bietet, beschneiden kann.

die Frage verste ich nicht... "den normalen Objekt- Erstell- Mechanismus aus Groovy" - was soll das sein ? es ist der selbe wie in Java ?
Okay, dass beantwortet die Frage ;)
Die Situation ist: Das Script erstellt ein Objekt mit "new MyObject()". Der Konstruktor erwartet aber eigentlich ein Argument. Dieses Argument muss die Skript- Runtime irgendwie reinbringen. Unter Rhino ging das nur, wenn man im Context eine statische Methode createMyObject() bereitstellte. Unter Groovy offenbar auch (eine Alternative scheinen ASTTransformations zu sein, da ist nur wieder die Frage, ob das mit dem interpreted mode geht (falls es den einen interpreted mode gibt...))

Trotzdem danke,
anonym
 
A

anonym

Gast
So, nachdem die Dok mir nicht aussagekräftig genug war, hab ich mal Sources gelesen. Für mich sieht das so aus, als ob alles kompiliert würde. Also kein Interpreted mode, womit ein paar Fragen schon geklärt wären.

Für mich bleibt eigentlich nur die Geschwindigkeitsfrage und die Frage, ob ich das ganze so abgedichtet bekomme, dass ich definitiv alle von der Java- Standard- API, der Groovy- Standard- API (jeweils bis auf Basissachen wie Strings, Numerisches...) und meinem Applicationcode fernhalten kann.

Der GroovyShell kann ich einen ClassLoader mitgeben. Mit einer eigenen Classloader- Implementierung könnte ich hier schonmal eine ganze Reihe Java- Klassen ausschließen. Zumindest, wenn das Teil dann nicht hinterher doch einen anderen ClassLoader nimmt. Fraglich ist, ob das auch die Groovy- Standard- Api erfolgreich verbirgt.
 
G

Gelöschtes Mitglied 5909

Gast
Für mich bleibt eigentlich nur die Geschwindigkeitsfrage und die Frage, ob ich das ganze so abgedichtet bekomme, dass ich definitiv alle von der Java- Standard- API, der Groovy- Standard- API (jeweils bis auf Basissachen wie Strings, Numerisches...) und meinem Applicationcode fernhalten kann.

Der GroovyShell kann ich einen ClassLoader mitgeben. Mit einer eigenen Classloader- Implementierung könnte ich hier schonmal eine ganze Reihe Java- Klassen ausschließen. Zumindest, wenn das Teil dann nicht hinterher doch einen anderen ClassLoader nimmt. Fraglich ist, ob das auch die Groovy- Standard- Api erfolgreich verbirgt.

Wenn ich jetzt nicht komplett daneben liegt, macht man das doch normalerweise mit nem SecurityManager ?!?!?!?

Die Situation ist: Das Script erstellt ein Objekt mit "new MyObject()". Der Konstruktor erwartet aber eigentlich ein Argument. Dieses Argument muss die Skript- Runtime irgendwie reinbringen. Unter Rhino ging das nur, wenn man im Context eine statische Methode createMyObject() bereitstellte. Unter Groovy offenbar auch (eine Alternative scheinen ASTTransformations zu sein, da ist nur wieder die Frage, ob das mit dem interpreted mode geht (falls es den einen interpreted mode gibt...))

3 Möglichkeiten:

1. Muss es wirklich der Konstruktor sein? was spricht gegen ein Interface mit nem setter, das von deinem Framework automatisch aufgerufen wird?
2. Mit Groovy Meta Programming sollte das auch möglich sein.
3. AOP
 
A

anonym

Gast
Was mich bisher davon abgehalten hat, Java Security zu verwenden, war, dass ich damit (1) nicht den Zugriff auf ganze Klassen oder einzelne Methoden in einer Klasse sperren kann und (2) nur sehr schwer User Scripts und Application Code sauber trennen (Merke: Der User darf Datenbankzugriffe ausführen, aber nicht mit beliebigen Queries. Ein Security Manager kann nur die ganze DB sperren).

Wie ich inzwischen festgestellt habe, bietet Groovy unter dem Namen Groovy Security eine Möglichkeit, genau das zu machen: Saubere Trennung anhand des Codeursprungs. Ich bin mir noch nicht ganz sicher, ob das meinen Anforderungen entspricht, aber erste Tests wirken vielversprechend. Ich werde de Nutzer damit zwar nicht davon abhalten, die Klasse java.io.File in seinen Scripts zu verwenden, aber Aufrufe an createNewFile(), delete() o.ä. und insbesondere der Versuch, aus einer Datei zu lesen oder in eine Datei zu schreiben, werden gefangen. Für Reflections, DB- Zugriffe usw. gilt selbiges.

Das Sperren einzelner Methoden wird nur in selbst geschriebenen Klassen mittels eigener Permissions gehen. Oder alternativ gestalte ich die Interfaces so, dass alles, wo der Nutzer nicht dran darf, protected oder private ist. Damit löse ich vermutlich sogar das Problem mit dem Konstruktorargument. Ich werde es, so wie auch RaiL es vorgeschlagen hat, über einen Setter erst später einbringen.

Also, vielen Dank für eure Hilfe.

anonym
 

Ähnliche Java Themen

Neue Themen


Oben