Frage

Wie kann ich Java-Code aus einer beliebigen Zeichenkette (im Speicher) in Java 5 und Java 6, laden Sie es kompilieren und eine spezifische Methode auf sie (vordefinierten) laufen?

Bevor Sie diese Flamme, sah ich bestehende Implementierungen über:

  • Die meisten setzen auf Java 6 Compiler API.
  • Diejenigen, die dies nicht tun, verlassen sich auf Tricks.
  • Ja, ich ausgecheckt commons-jci. Entweder bin ich zu dicht zu verstehen, wie es funktioniert, oder es funktioniert einfach nicht.
  • Ich konnte nicht finden, wie der Compiler meinen aktuellen Klassenpfad zu füttern (was ziemlich riesig ist).
  • Auf der Implementierung, die (in Java 6) arbeitete, kann ich nicht finden, wie man richtig innere Klassen laden (oder innere anonyme Klassen).
  • Ich würde ganz wie es, wenn die ganze Sache im Speicher war, als das, was auf mehreren Umgebungen ausgeführt wird.

Ich bin sicher, dass dies vor gelöst worden ist, aber ich kann nichts finden, dass auch nur halbProduktionsQualität auf Google sieht (außer jci, die, wie ich schon gesagt habe, ich habe zu verwenden, es nicht geschafft) .

Edit:

  • Ich schaute über JavaAssist - ich brauche innere Klassen, Java 5.0 Sprache Level-Support und Kompilieren mit dem gesamten Classpath. Außerdem würde ich gerne neue Klassen on the fly erstellen. ich könnte sich irren, aber ich konnte nicht finden, wie dies mit JavaAssit zu tun.
  • Ich bin bereit, eine Datei-System-basierte Lösung (Aufruf javac) zu verwenden, aber ich weiß nicht, wie die Classpath prophezeien, noch wie man später die Dateien geladen werden (die nicht in meinem Classpath) mit einem speziellen Classloader das kann für mehrere Anrufungen recycelt werden. Während ich weiß, wie es zu erforschen, würde ich eine fertige Lösung bevorzugen.

Edit2: Denn jetzt, ich bin zufrieden mit Beanshell „bewerten“. Anscheinend hat es alles, was ich es (bekommen einen String benötigen, bewerten sie im Rahmen des ‚aktuellen‘ Classpath. Es ist einige Java-5-Funktionen vermissen, aber es kann Aufzählungen verwenden (nicht definieren) und kompiliert ‚Generika‘ (gelöscht ) Klassen, so sollte es genug sein, was ich will.

Ich will nicht, um die Antwort markieren noch akzeptiert, da ich für eine bessere Lösung hoffen zu kommen.

Edit3. Den Vorschlag akzeptiert Beanshell - es ist wirklich wunderbar funktioniert

War es hilfreich?

Lösung

Wenn Sie nicht vollständig gebunden zu kompilieren, Lösungen wie Beanshell, stark und die anderen Skriptsprachen leicht eingebettet sind (in-fact, Java hat eine integrierte Unterstützung für in einer Skriptsprache Aufstecken so Ihr Code nicht einmal tut wissen, welche Sprache wird das Skript geschrieben in)

Beanshell sollte alle 100% Java-Code IIRC laufen, und ich glaube, Groovy können die meisten Java-Code ausführen -. Möglicherweise alle

Andere Tipps

JCI sieht gut aus. Dieser Code-Schnipsel sollte Ihre Basis sein:

JavaCompiler compiler = new JavaCompilerFactory().createCompiler("eclipse");

MemoryResourceReader mrr = new MemoryResourceReader();
mrr.add("resource name string", yourJavaSourceString.getBytes());

MemoryResourceStore mrs = new MemoryResourceStore();

CompilationResult result = compiler.compile(sources, mrr, mrs);

// don't need the result, unless you care for errors/warnings
// the class should have been compiled to your destination dir

Gibt es Gründe, dies nicht funktionieren sollte?


Edit:. ein MemoryResourceStore hinzugefügt, um die kompilierte Klasse Ausgabe an den Speicher zu senden, wie angefordert

Auch Einstellung javac Einstellungen, wie Classpath in Ihrem Fall kann über setCustomArguments(String[] pCustomArguments) in JavacJavaCompilerSettings Klasse.

Sie möchten vielleicht Janino überprüfen als auch.

Von ihrer Website:

Janino ist ein Compiler, der einen Ausdruck JavaTM liest, block, Klasse Körper, die Quelldatei oder einen Satz von Quelldateien und erzeugt JavaTM-Bytecode, die geladen wird, und direkt ausgeführt. Janino ist nicht als ein Entwicklungswerkzeug gedacht, sondern ein Embedded-Compiler für Laufzeit Kompilierung Zwecke, z.B. Ausdrucksauswertungen oder "Server Pages" Engines wie JSP.

http://www.janino.net/

Im mit derzeit in einem ziemlich großen unternehmenskritischen Projekt und es funktioniert gut

Javassist könnte Sie interessieren

Führen Sie in einem Web-Container wie Tomcat und erzeugen zunächst eine JSP-Seite, und dann aufrufen.

Dies ermöglicht es Ihnen, auch die Beseitigung der alten Klassendefinitionen zu erhalten, indem einfach die JSP-Seite zu überschreiben, anstatt mit Ihren Klassenlader langsam voll laufen.

Ist die „In-Memory“ Anforderung aufgrund der Geschwindigkeit oder aufgrund nicht die Code-Basis zu ändern?

EuGH Eclipse-Java-Compiler

Eclipse-liefert und verwendet einen eigenen Compiler, der nicht javac

ist
  • Der Eclipse-Compiler ist in der IDE (Eclipse)
  • verwendet
  • Der Eclipse-Compiler kann auch als reine Batch-Compiler verwendet werden außerhalb von Eclipse

Erstellen Sie eine Quelldatei

$ java -jar ecj-3.5.2.jar HelloWorld.java

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top