-
-
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"); | |
} | |
} |
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.
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.
execution result(stdout):