peliculas - groovy vs java
Llamar a una funciĆ³n Groovy desde Java (6)
¿Cómo se llama a una función definida en un archivo de script de Groovy desde Java?
Ejemplo de script maravilloso:
def hello_world() {
println "Hello, world!"
}
Miré GroovyShell, GroovyClassLoader y GroovyScriptEngine.
Un simple ejemplo:
import groovy.lang.GroovyClassLoader;
import groovy.lang.Script;
public class GroovyEmbedder {
static public final String GROOVY_SCRIPT=
"println (''Hello World !'')";
static public void main(String[] args) throws Exception {
((Script) new GroovyClassLoader().parseClass(GROOVY_SCRIPT).newInstance()).run();
}
}
Pruebas
> javac -cp groovy-all-2.4.10.jar GroovyEmbedder.java
> java -cp groovy-all-2.4.10.jar:. GroovyEmbedder
Hello World !
La forma más simple es compilar el script en un archivo de clase java y simplemente llamarlo directamente. Ejemplo:
// Script.groovy
def hello_world() {
println "Hello, World!"
}
// Main.java
public class Main {
public static void main(String[] args) {
Script script = new Script();
script.hello_world();
}
}
$ groovyc Script.groovy
$ javac -classpath .:$GROOVY_HOME/embeddable/groovy-all-1.7.5.jar Main.java
$ java -classpath .:$GROOVY_HOME/embeddable/groovy-all-1.7.5.jar Main
Hello, World!
Solo formas más elegantes:
GroovyScriptEngine engine = new GroovyScriptEngine( "." )
Object instance = engine
.loadScriptByName(scriptName)
.newInstance()
Object result = InvokerHelper.invokeMethod(instance, methodName, args)
Y si la clase de script extiende groovy.lang.Script
:
Object result = engine
.createScript(scriptName, new Binding())
.invokeMethod(methodName, args)
No es necesario extender groovy.lang.Script
si solo desea llamar al método main
de su clase groovy:
Object result = engine
.createScript(scriptName, new Binding())
.run()
Suponiendo que tiene un archivo llamado test.groovy
, que contiene (como en su ejemplo):
def hello_world() {
println "Hello, world!"
}
Entonces puedes crear un archivo Runner.java
así:
import groovy.lang.GroovyShell ;
import groovy.lang.GroovyClassLoader ;
import groovy.util.GroovyScriptEngine ;
import java.io.File ;
class Runner {
static void runWithGroovyShell() throws Exception {
new GroovyShell().parse( new File( "test.groovy" ) ).invokeMethod( "hello_world", null ) ;
}
static void runWithGroovyClassLoader() throws Exception {
// Declaring a class to conform to a java interface class would get rid of
// a lot of the reflection here
Class scriptClass = new GroovyClassLoader().parseClass( new File( "test.groovy" ) ) ;
Object scriptInstance = scriptClass.newInstance() ;
scriptClass.getDeclaredMethod( "hello_world", new Class[] {} ).invoke( scriptInstance, new Object[] {} ) ;
}
static void runWithGroovyScriptEngine() throws Exception {
// Declaring a class to conform to a java interface class would get rid of
// a lot of the reflection here
Class scriptClass = new GroovyScriptEngine( "." ).loadScriptByName( "test.groovy" ) ;
Object scriptInstance = scriptClass.newInstance() ;
scriptClass.getDeclaredMethod( "hello_world", new Class[] {} ).invoke( scriptInstance, new Object[] {} ) ;
}
public static void main( String[] args ) throws Exception {
runWithGroovyShell() ;
runWithGroovyClassLoader() ;
runWithGroovyScriptEngine() ;
}
}
compilarlo con:
$ javac -cp groovy-all-1.7.5.jar Runner.java
Note: Runner.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
(Nota: las advertencias se dejan como un ejercicio para el lector) ;-)
Entonces, puedes ejecutar este Runner.class con:
$ java -cp .:groovy-all-1.7.5.jar Runner
Hello, world!
Hello, world!
Hello, world!
También puede usar Bean Scripting Framework para incrustar cualquier lenguaje de scripting en su código Java. BSF le da la oportunidad de integrar otros idiomas, pero no es integración nativa.
Si está claramente enfocado en usar Groovy, GroovyScriptEngine es la solución más completa.
=)
Ya sea
- Compilar como ataylor sugiere
- Use JSR-223 como se explica here
- Si está utilizando Spring , tenga una clase groovy que implemente una interfaz Java e inserte en su código con:
<lang:groovy id="messenger" script-source="classpath:Messenger.groovy">
<lang:property name="message" value="I Can Do The Frug" />
</lang:groovy>
Una ventaja del enfoque de primavera es el concepto de "granos refrescables". Es decir, Spring se puede configurar para supervisar las modificaciones del archivo de script y reemplazarlo en tiempo de ejecución.