jsr-223 - 追記中 2017/01/09
2021/03/14

jsr-223です。


javaからJVM言語をスクリプト実行したいです。
主観ですが、メジャーな言語と思えるものを調べてみました。
かなりおおざっぱです。

対象
 clojure,groovy,scala,jruby,jython,kotlin, javascript


言語 engine name(shortName) Factoryクラス JAR 特記
Clojure Clojure clojure.contrib.jsr223.ClojureScriptEngineFactory clojure-jsr223-1.2.jar  
Groovy Groovy org.codehaus.groovy.jsr223.GroovyScriptEngineFactory groovy-jsr223-2.4.7.jar  
Scala scala scala.tools.nsc.interpreter.IMain$Factory scala-compiler-2.11.8.jar -Dscala.usejavacp=true
Kotlin kotlin org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngineFactory kotlin-jsr223-local-example-1.1-M04-eap-14.jar  
JRuby jruby org.jruby.embed.jsr223.JRubyEngineFactory jruby-complete-9.1.6.0.jar -Dpython.import.site=FALSE
Jython jython org.python.jsr223.PyScriptEngineFactory jython-2.7.0.jar  
javascript javascript com.sun.script.javascript.RhinoScriptEngineFactory#java7 resources.jar java8はNashorn


jsr-223って、もともとサーバーサイドで各種スクリプト言語の実行を目指したもののようですね。

こうやってみてみるとJVM言語っていろいろありますね。かなり貪欲というか。

呼び出し方は、ScriptEngineManagerにたいして、エンジン名を指定して、ScriptEngineを取得します。取得できない場合は、nullが返ってくるようです。

ちなみに、各ScriptEngineFactoryはプログラムの起動時に行われるようです。ScriptEngineFactoryの定義は、各ライブラリ(jar)のMETA-INF/services/javax.script.ScriptEngineFactory ファイルに記述されています。
ですので、このファイルを探せばよいというのがわかります。ただし、このファイルに記述されているのに実際のクラスがない場合、不幸なことにプログラム全体が起動しません。
# 遅延ロードでできないのかしら?

参考 clojure


以下、呼び出しソース

package jsr223; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; public class TestMain { public static void main(String[] args) throws ScriptException { a(); } static void a() throws ScriptException { // まとめて実行するとjava.lang.OutOfMemoryErrorする.... jsr223_noengine(); jsr223_Clojure(); jsr223_Groovy(); jsr223_Scala(); jsr223_JRuby(); jsr223_Jython(); jsr223_Javascript(); jsr223_Kotlin(); } static void jsr223_noengine() throws ScriptException { final ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); final String shortName = "xxxx";// 存在しないものを指定 final ScriptEngine scriptEngine = scriptEngineManager.getEngineByName(shortName); if (scriptEngine == null) { System.out.println("*** 存在しないものを指定した場合は、script engineはnullになります。"); } else { scriptEngine.eval(""); } } static void jsr223_Clojure() throws ScriptException { final ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); final String shortName = "Clojure"; final ScriptEngine scriptEngine = scriptEngineManager.getEngineByName(shortName); scriptEngine.eval("(println \"clojure \")"); } static void jsr223_Groovy() throws ScriptException { final ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); final String shortName = "Groovy"; final ScriptEngine scriptEngine = scriptEngineManager.getEngineByName(shortName); scriptEngine.eval("println \"groovy \""); } static void jsr223_Scala() throws ScriptException { final ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); final String shortName = "scala"; final ScriptEngine scriptEngine = scriptEngineManager.getEngineByName(shortName); scriptEngine.eval("println(\"scala \")"); } static void jsr223_JRuby() throws ScriptException { final ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); final String shortName = "jruby"; final ScriptEngine scriptEngine = scriptEngineManager.getEngineByName(shortName); scriptEngine.eval("printf \"jruby \n\""); } static void jsr223_Jython() throws ScriptException { final ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); final String shortName = "jython"; final ScriptEngine scriptEngine = scriptEngineManager.getEngineByName(shortName); scriptEngine.eval("print 'jython'"); } static void jsr223_Javascript() throws ScriptException { final ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); final String shortName = "javascript"; // java7 Rhino java8 Nashorn final ScriptEngine scriptEngine = scriptEngineManager.getEngineByName(shortName); scriptEngine.eval("print('javascript')"); } static void jsr223_Kotlin() throws ScriptException { final ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); final String shortName = "kotlin"; final ScriptEngine scriptEngine = scriptEngineManager.getEngineByName(shortName); scriptEngine.eval("println(\"Kotlin\")"); } }


 参考

: