1

Explanation

I'm working on a game in Java where I have scriptable objects (buttons, switches etc..) on the map. By scriptable I mean that the objects have events (onActivation, onPress, etc..) and a script file is needed to be attached to the object in order to do something when its activated or pressed.

So event handling is done via scripting. My idea is to have a Groovy Script object created in Java by GroovyScriptEngine.createScript method. Then I call Script.invokeMethod("onActivation", null) in java to run the script when onActivation occurs. This seems to work.

Problem

However I have problems in my groovy script file. Here is the file:

test.groovy

def someVariable = 'test';

def onActivation() {
    println testMessage;   // comes from bindings
    println someVariable;
}

Here is my java code where the Script object is created:

GroovyScriptEngine engine = new GroovyScriptEngine("assets/Scripts/");
Binding bindings = new Binding();
bindings.setProperty("testMessage", "Hello Script World!");
Script script = engine.createScript("test.groovy", bindings);

Later in the java code, when handling the onActivation event, I invoke the onActivation function from the script:

public void onActivationHandler() {
    script.invokeMethod("onActivation", null);
}

But my groovy script fails with this message:

Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
groovy.lang.MissingPropertyException: No such property: someVariable for class: test

If I remove the someVariable declaration and the line where I print it, my script works and prints the following message: Hello Script World!

TL;DR

Why does my script fail? Why doesn't my function see the variable named someVariable?

Edit

The same thing happens when I try to use GroovyShell instead of GroovyScriptEngine.

Edit2

If I try to get the value of someVariable in Java code by calling script.getProperty("someVariable"), it throws an exception telling me that the variable does not exists.

org.codehaus.groovy.runtime.metaclass.MissingPropertyExceptionNoStack: No such property: someVariable for class: proof
kruze
  • 361
  • 1
  • 3
  • 8

1 Answers1

1

All right, I found the answer here. My test.script should look like this:

import groovy.transform.Field

@Field String someVariable = 'test';

def onActivation() {
    println testMessage;   // comes from bindings
    println someVariable;
}

The script actually becomes a class (even if it doesn't contain class declaration). I need to add the @Field annotation to make it 'global' for the functions declared.

It also solved the problem mentioned in EDIT2. The variable became available via the script.getProperty("someVariable") call in Java.

Community
  • 1
  • 1
kruze
  • 361
  • 1
  • 3
  • 8