2009-06-30 8 views
18

Estoy en el proceso de escribir un motor de reglas que realiza asignaciones simples como lo determinan las construcciones condicionales. Es un requisito previo del proyecto que las reglas estén en formato XML. He modelado mi esquema XML para que se parezca a simples bloques de código. Deseo analizar el XML y luego transformarlo en código Java. Luego deseo compilar (y ejecutar) este código en tiempo de ejecución. Si lo hace, mi motor de reglas ya no actuará como intérprete, sino que ejecutará el código nativo de Java Byte.¿Cómo puedo compilar e implementar una clase java en tiempo de ejecución?

He descubierto la etapa de análisis sintáctico y más o menos la fase de generación de código Java. Ahora me gustaría descubrir la última fase: la compilación en la fase de ejecución.

Siguiendo este hilo: Compile to java bytecode (without using Java) me he dado cuenta de las siguientes soluciones posibles:

Me encantaría una comparación de estos, así como otras sugerencias para resolver la compilación de Java en la fase de tiempo de ejecución.

+2

Un par de punteros para usted: 1) descargue la fuente de Tomcat, cuando crea las clases para JSP tiene que hacer exactamente lo que usted describe. 2) eche un vistazo a Drools (http://www.jboss.org/drools/). Lo he usado en el pasado y es bastante poderoso cuando se trata de motores de reglas. –

+0

¿Alguna vez obtuvo esta aplicación completa? Me interesaría ver cómo funciona si puedes compartir las fuentes. –

+0

@EricB. Me alegro de que haya mostrado interés. Lamentablemente, la aplicación dio un giro en otro lugar. Seguí usando la API del compilador Java 6, pero para un alcance mucho más simple. En otras palabras, los bloques de código XML aún se interpretan como no compilados hasta el día de hoy ... No puedo publicar el código que escribí porque es propiedad ... – Yaneeve

Respuesta

4

Podría transformarlo en código Clojure, y el compilador Clojure lo convertirá en bytecode.

+0

¿Podría elaborarlo por favor? – Yaneeve

+1

@Yaneeve, Clojure (http://clojure.org/) es un dialecto lisp escrito para la JVM. Si tuviera que implementar la semántica de sus etiquetas como funciones/macros de lisp, sería trivial convertir sus estructuras XML a las estructuras de lisp correspondientes, que luego pueden compilarse en una clase si lo desea. Si XML no fuera un requisito, yo diría que solo use los datos de lisp. Para una discusión java + xml-centrada de por qué, mira: http://www.defmacro.org/ramblings/lisp.html – kwatford

+2

Acabo de regresar a tu respuesta rápidamente algunos años y ahora siento como si tu sugerencia fuera la mente soplo.Lástima que yo, en ese momento, y el desarrollador/administrador promedio no pensara ni pensara en términos de ceceo y codificación funcional. Como un ejemplo de lo que habías sugerido sería, creo, Reimann: http://riemann.io/ – Yaneeve

1

Ahórrese la molestia y use BeanShell como se alude aquí Executing java code given in a text file.

¿Qué es BeanShell?

BeanShell es un intérprete integrable pequeña, libre, fuente de Java con las características del lenguaje de scripting objeto , escrito en Java . BeanShell dinámicamente ejecuta la sintaxis estándar de Java y extiende con scripting común comodidades tales como tipos sueltos, comandos, y cierres método como aquellos en Perl y JavaScript.

Puede usar BeanShell de forma interactiva para la experimentación y la depuración de Java , así como para ampliar sus aplicaciones de nuevas maneras. Scripts de Java se presta a una amplia variedad de aplicaciones, incluyendo rápida de prototipos , la extensión de secuencias de comandos de usuario, motores de reglas, configuración, pruebas, despliegue dinámico, sistemas embebidos, e incluso la educación de Java.

BeanShell es pequeño e integrable, por lo que se puede llamar BeanShell desde sus aplicaciones Java para ejecutar código Java dinámicamente en tiempo de ejecución o para proporcionar extensibilidad en sus aplicaciones. Como alternativa, puede usar scripts independientes de BeanShell para manipular las aplicaciones Java ; trabajando con Java objetos y API dinámicamente.Desde BeanShell está escrito en Java y ejecuta en la misma VM que su aplicación, , puede pasar libremente las referencias a objetos "activos" en scripts y devolver como resultados.

En resumen, BeanShell es dinámicamente interpretarse de Java, además de un lenguaje de script y entorno flexible todo enrollado en un paquete limpio.

+0

Corrígeme si me equivoco, sin embargo, BeanShell es un intérprete y, por lo tanto, no creará el código de Java Byte como resultado de su ejecución ... – Yaneeve

+0

Sí, creo que se interpreta BeanShell. La razón por la que lo mencioné es que supongo que quiere usar Java para expresar construcciones más complicadas en su motor de reglas, en cuyo caso ¿es importante que el código de Java esté compilado o interpretado? –

+0

No importa ya que la CPU y la memoria son un problema en el entorno que debo implementar en ... – Yaneeve

2

Groovy, BeanShell o cualquier otro lenguaje de programación que está basado en JVM tienen este tipo de instalaciones para inyectar, modificar, añadir y ejecutar código en tiempo de ejecución. En realidad, se interpreta todo el lenguaje de scripting, por lo que en realidad no se están compilando en tiempo de ejecución.

1

se puede bifurcar un proceso como éste

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 

y puede compilar y ejecutarlo.

2

Javassist es casi un compilador completo de Java escrito en Java, y está completamente hecho de Java. No puede darle un archivo entero .java de una vez, pero puede darle la cadena de código para funciones individuales y agregarlas al mismo objeto CtClass, que se convierte en bytecode y luego en java.lang.Class.

Acabo de lanzar la versión 0.1 de GigaLineCompile, que usa Javassist (compilador) y Beanshell (intérprete) juntos y le da control sobre qué código optimizar y cuándo. En versiones posteriores, cambiará entre Javassist y Beanshell en una granularidad más pequeña, por lo que si tiene muchas cadenas de código que comparten algunas subcadenas, las subcadenas se compilarán y las otras partes se ejecutarán en beanshell. Es principalmente útil para la inteligencia artificial que genera código Java, pero también es una alternativa a Clojure o a los extremos de Javassist/Beanshell solo.

Javassist, Beanshell y GigaLineCompile se puede descargar (con fuente) aquí: http://sourceforge.net/projects/gigalinecompile

Cuestiones relacionadas