I need to configure some attribute in ScriptEngine- or ScriptContext-level, to be used in Java methods.
So, how to get a reference to that ScriptContext
in order to retrieve the value?
Example: setting the attribute:
public static void main(String[] args) throws Exception {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.getContext().setAttribute("param1", "paramValue", ScriptContext.ENGINE_SCOPE);
engine.put("MyWindow", engine.eval("Java.type(\"" + MyWindow.class.getName() + "\")"));
engine.eval("print(new MyWindow().test());");
}
MyWindow
implementation: how to get that attribute?
public class MyWindow {
public String test() {
// how to get 'param1' value here
return "in test";
}
}
Pass it in:
engine.eval("print(new MyWindow().test(param1));");
// ^^^^^^
// vvvvvvvvvvvvv
public String test(String param1) {
// how to get 'param1' value here
return "in test";
}
Update
If you have code with a call stack like javaMethod1 -> JavaScript -> javaMethod2
, and you want a value from javaMethod1
to be available to javaMethod2
, without changing the JavaScript to pass it on, use a ThreadLocal.
Since your code is in main
you could just use a static
directly, but I'm assuming your context is more complex. The code below works even in multi-threaded contexts. The ThreadLocal
can be stored anywhere, it just has to be static and available to both java methods.
public static void main(String[] args) throws Exception {
MyWindow.param1.set("paramValue");
try {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.eval("var MyWindow = Java.type(\"" + MyWindow.class.getName() + "\");" +
"print(new MyWindow().test());");
} finally {
MyWindow.param1.remove();
}
}
public class MyWindow {
public static final ThreadLocal<String> param1 = new ThreadLocal<>();
public String test() {
String value = param1.get();
return "in test: param1 = " + value;
}
}