PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Php-eval() unter Java?



KL47
08-12-2004, 17:15
Hi,

ich meine mal gehört zu haben, dass es unter Java auch ne Möglichkeit gibt, dynamisch Java-Code auszuführen, weiß zufällig jemand wie die Klasse heißt, oder wonach ich suchen könnte? Der Benutzer soll also zum Beispiel "System.out.println('Hallo');" in ein Textfeld eingeben und dann soll "Hallo" ausgegeben werden.

Danke im Voraus. :)

Lin728
20-12-2004, 20:34
Beanshell dürfte genau das sein, was du suchst, interpretiert ziemlich gut Java-Code, ist halt ca. 1/1000 von der Geschwindigkeit von Java, kommt halt drauf an, ob dein code eher api lastig ist, oder ob du viel selbst machst.
Für code der nur wneige male durchlaufen wird reichts vollkommen (z.B. erstellen von Oberfächen), für Harte Mathe-Sachen würd ich eher davon abraten ;-)

gaansch
20-12-2004, 23:46
Klar geht das.
Man kann doch über die Reflection API[1] Methoden aufrufen, die erst während der Laufzeit bekannt werden.
Man müsste dann nur die Eingabezeile entsprechend parsen.
Da muss man allerdings den Typ des Parameters angeben. Das heisst, es muss während der Eingabe auch angegeben werden, von welchem Typ die Parameter sind, oder halt nur eine bestimmte Menge an Methode erlauben, die eingegeben werden dürfen und dazu die Parametertypen irgendwio ablegen.
Das währe jetzt die einzige Möglichkeit, die mir so spontan einfällt. Wüsste aber auch nicht, wie es anders gehen sollte.

Da ist auch nichts statisch, man kann dynamisch irgendwelche Objekte erzeugen, deren Typ oder Name während der Programmierung nicht bekannt ist. Geht alles über die Reflection API. Ist ne ganz interessante Sache.


Gruss
Sebastian

[1] http://java.sun.com/docs/books/tutorial/reflect/object/invoke.html

Lin728
23-12-2004, 18:03
Java ist eine statisch getypte Sprache - niemand hat was anderes gesagt. Bei reflection gibts sowieso nur Typprüfung zur Laufzeit.

fs111
23-12-2004, 19:20
Könnt ihr bitte mal locker bleiben?

Danke

fs111

Lin728
23-12-2004, 22:01
......................

hbdsklf
10-12-2007, 16:44
Wenn du einen eigenen Classloader schreibst solltest du eigentlich code zur laufzeit ausführen können, sofern es sich um eine ganze klasse handelt. Ich hab mir so ein Plugin-System gebastelt und ich kann Plugins während der Laufzeit hinzuladen...

zerix
12-12-2007, 16:57
1.) Wirklich - es gibt in Java eine reflektion API? - Das ist ja der hammer!
2.) Ahh, die Reflection-API ist also ein interpreter, wie im Post gefragt?
3.) Java ist eine statisch getypte Sprache - niemand hat was anderes gesagt. Bei reflection gibts sowieso nur Typprüfung zur Laufzeit.

Zu 1
Ja, die gibts. :-)

Zu 2
Wo wird im Post nach einem Interpreter gefragt? Es wird lediglich gesagt, in welcher Richtung er etwas sucht, aber nicht, dass es ein Interpreter sein muss.


Das ganze lässt sich mit der Reflection-Api lösen, aber es ist schon aufwendig.
Wenn ich frage darf, warum möchtest du das machen?

MFG

zEriX

Waxolunist
12-12-2007, 17:33
Wie wärs mit der in Java 6 enthaltenen Scriptingengine?

PHP ist eine Skriptsprache und php-eval() führ zur Laufzeit ein Skript aus. Also ist genau dies möglich mit der Scriptingengine aus Java 6. Als Scriptsprache könnte z.B. Groovy herhalten, da kannst du sogar so etwas System.out.println hineinschreiben.

Mit Reflection kannst du das vergessen, dass müsste ja heissen, man müsste einen Compiler einbauen oder irgendwie so. That goes not.
Plugins sind nicht das gleiche.

Z.B.:


test.groovy:
println "message from outer space"

call.groovy:
engine = new GroovyScriptEngine(".")
engine.run("test.groovy", new Binding())

Ausgabe:
message from outer space

Dass man hier dynamisch ein Groovy-Skript schreiben kann und dieses dann der run-Methode übergeben, kommt dem ganzen schon sehr nahe. Man kann natürlich seine eigene ScriptEngine schreiben, die das dann kapselt, womit man dann wirklich schon sehr nahe php-eval herankommt. Dann glaube ich, kann man Groovy-Code irgendwie in Java-Code umwandeln, ob der umgekehrte Weg geht, weiß ich nicht, aber dann ist da ja ohnehin noch mehr möglich. Aber DAS ist für mich der richtige Ansatz.

mfg, Christian

Edit: Der Überhammer: Hab grad noch mal nachgelesen und die Methode aus dem Interface Scriptengine heißt sogar eval http://java.sun.com/javase/6/docs/api/javax/script/ScriptEngine.html.

Lesen bildet

Edit: Einen Link hab ich noch: https://scripting.dev.java.net/. Da wird sogar Java als Skipt-Sprache aufgeführt. Sollte man mal genauer unter die Lupe nehmen.

zerix
13-12-2007, 07:32
Sicher kann man das mit Reflection machen.

Zum Beispiel bei
System.out.println("test") kennst du die Klassen, Objecte, Methoden. Du kannst den String splitten. Du kannst dann die Klasse laden. Dann kann man das Feld der Klasse holen und die Methode darauf ausführen.
Man muss es ja nicht so machen, dass der Code neu kompiliert wird, sondern man kann die Klassen einfach dynamisch laden und die Methoden ausführen. Aber wie ich schon sagte, es ist schon ziemlich aufwendig.

Meiner Meinung nach ist es das gleiche Ergebnis, weil der Code ausgeführt wird, den der Nutzer eingegeben hat.

Ok, was natürlich nicht funktioniert ist es, wenn man eine neue Klasse schreiben möchte.

MFG

zEriX

Waxolunist
13-12-2007, 09:47
Und wie machst du das mit if-Schleifen?
Wie machst du das mit Primitiven?
Schlüsselwörter?
Du merkst hoffentlich schon, dass das alles nicht wirklich geht.

Allerdings fände ich es schon toll, wenn du mir, dass nur mit System.out.println zeigst.
Und im gleichen Code mit einem kleinen new Irgendwas.

Du musst unterscheiden zwischen Konstanten und Klassen neu zu erzeugen. Nur um mal schnell ein Problem zu nennen. Dazu irgendwie Variablen verarbeiten.

Also kurzes Beispiel (Bitte mit Reflection programmieren):

for(int i=0; i<10; System.out.println(Math.sqrt(i++)));

Scheiterpunkt 1: Du musst das Schlüsselwort for kennen und irgendwie abbilden.
2: Du musst Variablen kennen und parsen.
3: Du musst die Klasse Math finden, ohne den Paketnamen.
4: ...

Zudem ist dieser Rat, doch irgendwie trotzdem völlig aus der Luft gegriffen. Gefragt wurde nach einem Equivalent für eval und es gibt eine Methode eval in Java. Ein Rat, programmiers doch selbst mit Reflection, ist relativ unsinnig, was du bemerken wirst, sobald du selbst einmal das programmieren musst, was du vorgeschlagen hast.

@KL47: Bitte nimm keine Reflection.

lg, Christian

chris2000
13-12-2007, 09:51
Hallo

Ich nehe für diesen Zweck die Beanshell: http://www.beanshell.org/ die kann man prima in die eigene App mit einbauen und dynamsich Java Code ausführen.

SG
Christian

zerix
13-12-2007, 09:58
@Waxolunist

Ein Kollege von mir hat sowas in der Art, also nicht das gleiche, aber was man theoretisch dafür verwenden könnte, geschrieben. Er nutzt natürlich nicht ausschließlich Reflection, aber Reflection kommt auch zum Zuge.

Da ich den Code nicht kenne, kann ich auch nicht sagen, wie er es gemacht hat.

Da wir mit Java 5 arbeiten, kommt der Scriptanteil ja nicht in Frage.

Ich würde es nicht behaupten, wenn ich nicht wüsste, dass es funktioniert. Also ist mein Rat so wie du es formuliert hast, nicht aus der Luft gegriffen.


Ich hoffe damit ist das geklärt. Das es Möglichkeiten gibt, mit denen es einfacher geht, hab ich nicht abgestritten, ich wollte nur zeigen, dass es doch funktioniert.


MFG

zEriX

BLUESCREEN3D
13-12-2007, 13:58
Guckt der Threadersteller hier überhaupt noch rein, oder war das nur mal wieder jemand, der eval() nutzen wollte, weil er den richtigen Weg nicht kannte?

@zerix: Was du vorschlägst, wäre ja, selbst einen Parser für Java-Code zu schreiben ...


Und wie machst du das mit if-Schleifen?
Es gibt keine "if-Schleifen".

Waxolunist
13-12-2007, 14:14
Guckt der Threadersteller hier überhaupt noch rein, oder war das nur mal wieder jemand, der eval() nutzen wollte, weil er den richtigen Weg nicht kannte?

@zerix: Was du vorschlägst, wäre ja, selbst einen Parser für Java-Code zu schreiben ...


Es gibt keine "if-Schleifen".

I-Tüpfelchen-Reiter :)

Aber, dass es ein Parser sein müsste, habe ich eben schon gesagt. Ich hätte gerne gesehen, ob mein Beispiel lösbar ist. Aber hier auf einen unbekannten Dritten zu verweisen ist ein bisschen .... weiß nicht, irgendwie feige?

zerix
13-12-2007, 14:19
Aber, dass es ein Parser sein müsste, habe ich eben schon gesagt. Ich hätte gerne gesehen, ob mein Beispiel lösbar ist. Aber hier auf einen unbekannten Dritten zu verweisen ist ein bisschen .... weiß nicht, irgendwie feige?

Das hat nichts mit Feige zu tun. Da ich sowas leider noch nicht geschrieben hab, kann ich keinen Code präsentieren. Ich habe ja auch gesagt, dass es aufwendig ist sowas mit Reflection zu machen, deshalb kann ich das auch nicht gerade eben mal schnell schreiben.
Ich wollte lediglich mal sagen, dass es doch möglich ist, auch wenn du es nicht wahr haben willst.
In einem der ersten Posts wurde gesagt, dass es nicht möglich ist und das ist falsch, ob man es mal schnell programmiert hat oder es sehr aufwendig ist. Fakt ist, dass es möglich ist. Ich hab auch nicht behauptet, dass es Sinn macht sowas zu machen, aber es ist möglich, darum geht es mir.

Ich finde es jetzt allerdings auch blödsinn weiter darüber zu diskutieren, weil wir ja sowieso zu keinem Ergebnis kommen werden.

MFG

zEriX