-
-
Save takawitter/5479445 to your computer and use it in GitHub Desktop.
import javax.script.ScriptEngine; | |
import javax.script.ScriptEngineManager; | |
import scala.tools.nsc.interpreter.IMain; | |
import scala.tools.nsc.settings.MutableSettings.BooleanSetting; | |
public class ScalaTest { | |
public static void main(String[] args) throws Exception{ | |
ScriptEngine engine = new ScriptEngineManager().getEngineByName("scala"); | |
((BooleanSetting)(((IMain)engine).settings().usejavacp())).value_$eq(true); | |
// or | |
// ((scala.tools.nsc.interpreter.IMain)engine).settings().processArgumentString("-usejavacp"); | |
engine.put("n: Int", 10); | |
System.out.println("---"); | |
engine.eval("1 to n foreach print"); | |
} | |
} |
Thanks for your comment, rjolly!
For the classpath, even using manifest, a problem still exists when we are developing web application. The web application places classes to its WEB-INF/class folder and jars to its WEB-INF/lib folder, and scala-jsr223 doesn't have the function to recognize those classes (and no guarantee for the web-app container to read manifest).
I could use binded variable through bindings such like:
engine.getBindings(ScriptContext.ENGINE_SCOPE).put("n", 10);
1 to bindings.get("n").asInstanceOf[Int] foreach { print(_) }
Let me note requirements about variable bindings of scala-jsr223.
- support bindings through ScriptEngine#eval(script(or reader), bindings) method.
- support bindings through ScriptEngine#put(name, value) method.
- guess the type of variable (return value of Object#getClass or Any if the class is not public).
Anyway, I'm looking forward to next release and will test jsr223 compliant when its available.
thanks.
I updated the code to use binding with type -> engine.put("n: Int", 10);
I found it accidentally 😄
@takawitter Thank you very much for this helpful gist! This is the only place I found with details on how to call the Scala script engine from plain Java, rather than from other Scala code. You made all my problems go away: scijava/scripting-scala@1950c73 🍻
Hi,
Using either one of the instructions, I'm getting the following error :
Exception in thread "main" java.lang.ClassCastException: scala.tools.nsc.interpreter.Scripted cannot be cast to scala.tools.nsc.interpreter.IMain
at TestScala.main(TestScala.java:12)
Any idea why?
@DCransac I'm having this problem too. Appears that there was a change in scripting engine between 2.11 and 2.12.
Hi Takao,
Instead of usejavacp, you can list scala_library.jar classes into its manisfest with either jarsigner or (better) http://github.com/rjolly/jarlister . The interpreter runs with the usemanifestcp option by defaut and the library will be included in the classpath through this mechanism.
Regarding variable bindings, they are available in 2.11-M2 but through a unique variable "bindings" which is a map of all bound variables to their values. This is improved in forthcoming versions where bound variable are accessible by their own name.