web-dev-qa-db-fra.com

Appeler une fonction Groovy à partir de Java

Comment appelez-vous une fonction définie dans un fichier de script Groovy à partir de Java?

Exemple de script groovy:

def hello_world() {
   println "Hello, world!"
}

J'ai consulté GroovyShell, GroovyClassLoader et GroovyScriptEngine.

24
joemoe

En supposant que vous ayez un fichier appelé test.groovy, qui contient (comme dans votre exemple):

def hello_world() {
   println "Hello, world!"
}

Ensuite, vous pouvez créer un fichier Runner.Java comme ceci:

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() ;
  }
}

compilez-le avec:

$ 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.

(Remarque: les avertissements sont laissés comme exercice au lecteur) ;-)

Ensuite, vous pouvez exécuter ce Runner.class avec:

$ Java -cp .:groovy-all-1.7.5.jar Runner
Hello, world!
Hello, world!
Hello, world!
35
tim_yates

Le moyen le plus simple consiste à compiler le script dans un fichier de classe Java et à l'appeler directement. Exemple:

// 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!
18
ataylor

Non plus

  1. Compiler comme le suggère ataylor
  2. Utilisez JSR-223 comme expliqué ici
  3. Si vous utilisez Spring , avez une classe groovy qui implémente une interface Java et injectez dans votre code avec:

<lang:groovy id="messenger" script-source="classpath:Messenger.groovy">
    <lang:property name="message" value="I Can Do The Frug" />
</lang:groovy>

L'un des avantages de l'approche printanière est le concept de «haricots rafraîchissants». C'est-à-dire que Spring peut être configuré pour contrôler les modifications apportées à votre fichier de script et les remplacer au moment de l'exécution.

9
toolkit

Vous aussi, vous pouvez utiliser Bean Scripting Framework pour incorporer n’importe quel langage de script dans votre code Java. BSF vous donne la possibilité d’intégrer d’autres langues, mais ce n’est pas une intégration native.

Si vous souhaitez clairement utiliser Groovy, GroovyScriptEngine est la solution la plus complète.

=)

2
raulsaeztapia

Juste des manières plus élégantes:

GroovyScriptEngine engine = new GroovyScriptEngine( "." )

Object instance = engine
  .loadScriptByName(scriptName)
  .newInstance()

Object result = InvokerHelper.invokeMethod(instance, methodName, args)

Et si la classe de script étend groovy.lang.Script:

Object result = engine
  .createScript(scriptName, new Binding())
  .invokeMethod(methodName, args)

Pas besoin d'étendre groovy.lang.Script si vous voulez juste appeler la méthode main de votre classe groovy:

Object result = engine
  .createScript(scriptName, new Binding())
  .run()
0
Eugene Lopatkin

Un exemple simple:

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();
    }
}

Essai

> javac -cp groovy-all-2.4.10.jar GroovyEmbedder.Java
> Java -cp groovy-all-2.4.10.jar:. GroovyEmbedder
Hello World !
0
Alfredo Diaz