2009-06-30 18 views
18

Sono in procinto di scrivere un motore di regole che esegue assegnazioni semplici come determinato dai costrutti condizionali. È un prerequisito del progetto che le regole siano in formato XML. Ho modellato il mio schema XML per assomigliare a semplici blocchi di codice. Desidero analizzare l'XML e quindi trasformarlo in codice Java. Quindi desidero compilare (ed eseguire) questo codice in fase di esecuzione. Ciò significherebbe che il mio motore di regole non agisce più come interprete ma esegue il codice byte Java nativo.Come posso compilare e distribuire una classe java in fase di runtime?

Ho capito la fase di analisi e più o meno la fase di generazione del codice Java. Vorrei ora capire l'ultima fase: la compilazione in fase di runtime.

A seguito di questa discussione: Compile to java bytecode (without using Java) sono venuto a conoscenza delle seguenti soluzioni possibili:

Mi piacerebbe un confronto tra questi così come altri suggerimenti per risolvere la compilazione Java in fase di runtime.

+2

Un paio di indicatori per te: 1) scarica il sorgente Tomcat, quando crea le classi per JSP deve fare solo ciò che descrivi. 2) dare un'occhiata a Drools (http://www.jboss.org/drools/). L'ho usato in passato ed è piuttosto potente quando si tratta di motori di regole. –

+0

Hai mai completato questa applicazione? Sarei interessato a vedere come funziona se sei in grado di condividere le fonti. –

+0

@EricB. Sono contento che tu abbia mostrato interesse. Sfortunatamente l'applicazione ha preso una svolta altrove. Ho continuato a utilizzare l'API del compilatore Java 6, ma per un ambito molto più semplice. In altre parole, i blocchi di codice XML vengono interpretati ancora non compilati fino ad oggi ... Non posso pubblicare il codice che ho scritto poiché è proprietario ... – Yaneeve

risposta

4

È possibile trasformarlo in codice Clojure e il compilatore Clojure lo trasformerà in codice bytecode.

+0

Potresti elaborare per favore? – Yaneeve

+1

@Yaneeve, Clojure (http://clojure.org/) è un dialetto scritto per JVM. Se dovessi implementare la semantica dei tuoi tag come funzioni/macro lisp, dovrebbe essere banale convertire dalle tue strutture XML alle strutture Lisp corrispondenti, che possono quindi essere compilate in una classe, se lo desideri. Se XML non fosse un requisito, direi che basta usare i dati di Lisp per iniziare. Per una discussione java + xml-centric del perché, vedi: http://www.defmacro.org/ramblings/lisp.html – kwatford

+2

Sono appena tornato alla tua risposta in avanti di alcuni anni e ora sento che il tuo suggerimento è la mente soffiaggio.Peccato che io, al momento, e lo sviluppatore/manager medio non pensasse né in termini di codifica chiara e funzionale. Come esempio di ciò che avevi suggerito sarebbe, penso, Reimann: http://riemann.io/ – Yaneeve

1

Risparmia il fastidio e utilizza BeanShell come indicato qui Executing java code given in a text file.

Che cos'è BeanShell?

BeanShell è un piccolo, libero, embeddable Java fonte interprete con caratteristiche del linguaggio di scripting oggetto , scritto in Java. BeanShell dinamicamente esegue la sintassi Java standard e lo estende con lo scripting comune comodità quali i tipi liberi, i comandi e le chiusure di metodo come in Perl e JavaScript.

È possibile utilizzare BeanShell interattivamente per Java sperimentazione e il debugging così come per estendere le applicazioni in modi nuovi. Scripting Java presta stesso per una vasta gamma di applicazioni, tra cui rapida prototipazione, l'estensione di script utente, motori di regole, configurazione, test, distribuzione dinamica, sistemi embedded, e anche l'istruzione Java.

BeanShell è piccolo e integrabile, così è possibile chiamare BeanShell dalle applicazioni Java per eseguire codice Java dinamicamente a run-time o per fornire estensibilità nelle applicazioni. In alternativa, è possibile utilizzare gli script BeanShell standalone per manipolare le applicazioni Java ; lavorare con Java oggetti e API in modo dinamico.Dal BeanShell è scritto in Java ed esegue nella stessa VM dell'applicazione, è possibile passare liberamente i riferimenti agli oggetti "live" negli script e restituire come risultati.

In breve, BeanShell è dinamicamente interpretato Java, oltre a un linguaggio di scripting e ambiente flessibile tutto rotolato in un unico pacchetto pulito.

+0

Correggimi se sbaglio, però, BeanShell è un interprete e quindi non creerà il codice Byte Java come risultato della sua esecuzione ... – Yaneeve

+0

Sì, penso che BeanShell sia interpretato. La ragione per cui ho menzionato è che presumo che tu voglia usare Java per esprimere costrutti più complicati nel tuo motore di regole, nel qual caso è importante che il codice Java sia compilato o interpretato? –

+0

È importante dal momento che la cpu e la memoria sono un problema nell'ambiente che devo distribuire in ... – Yaneeve

2

Groovy, BeanShell o qualsiasi altro linguaggio di scripting basato su JVM hanno la possibilità di iniettare, modificare, aggiungere ed eseguire codice in fase di esecuzione. In realtà tutti i linguaggi di scripting sono interpretati, quindi in realtà quelli non vengono compilati in fase di runtime.

1

si può fork di un processo come questo

Process p = Runtime.getRuntime().exec("java -classpath "..." SomeClassContainingMain ...other arguments);  

     //you need to consume the outputs of the command if output/error is large otherwise the process is going to hang if output/error buffer is full. and create a seperate thead for it (not created here). 
     log.debug("PROCESS outputstream : " + p.getInputStream()); 
     log.debug("PROCESS errorstream : " + p.getErrorStream());   
    p.waitFor(); // Wait till the process is finished 

e possono compilare ed eseguirlo.

2

Javassist è quasi un compilatore Java completo scritto in Java ed è completamente realizzato in Java. Non puoi dargli un intero file .java in una volta, ma puoi dargli la stringa di codice per le singole funzioni e aggiungerle allo stesso oggetto CtClass, che diventa bytecode e quindi java.lang.Class.

Ho appena rilasciato la versione 0.1 di GigaLineCompile, che utilizza Javassist (compilatore) e Beanshell (interprete) insieme e ti dà il controllo su quale codice ottimizzare e quando. Nelle versioni successive, cambierà tra Javassist e Beanshell con una granularità più piccola, quindi se si hanno molte stringhe di codice che condividono alcune sottostringhe, le sottostringhe verranno compilate e le altre parti verranno eseguite in beanshell. È utile soprattutto per l'intelligenza artificiale che genera codice Java, ma è anche un'alternativa a Clojure o agli estremi di Javassist/Beanshell.

Javassist, Beanshell, e GigaLineCompile può essere scaricato (con fonte) qui: http://sourceforge.net/projects/gigalinecompile

Problemi correlati