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\")");
}
}
参考