Java Language
Javaで他のスクリプト言語を使用する
サーチ…
前書き
Java自体は非常に強力な言語ですが、そのパワーはさらに拡張することができます。JSR223(Java Specification Request 223)により、スクリプトエンジン
備考
Java Scripting APIにより、外部スクリプトはJavaと対話できます。
Scripting APIは、スクリプトとJavaの間の対話を有効にすることができます。スクリプト言語は、クラスパス上にScript Engineの実装を持たなければなりません。
デフォルトでJavaScript(ECMAScriptとも呼ばれます)はデフォルトでnashornによって提供されています。すべてのスクリプトエンジンには、すべての変数、関数、メソッドがバインディングに格納されたスクリプトコンテキストがあります。バッファリングされたWriterに出力をリダイレクトし、別のものにエラーをリダイレクトするのをサポートするので、複数のコンテキストを使用することがあります。
JythonやJRubyのような多くのスクリプトエンジンライブラリがあります。クラスパス上にある限り、コードを評価することができます。
バインディングを使用して変数をスクリプトに公開することができます。エンジンに変数を公開することは、基本的にはそのエンジンのみに変数を公開することになるため、複数のバインディングが必要な場合があります。同じタイプのすべてのエンジンでシステム環境とパスなどの特定の変数を公開する必要があります。その場合、グローバルスコープであるバインディングが必要です。同じEngineFactoryで作成されたすべてのスクリプトエンジンに公開する変数を公開する
nashornのスクリプトモードでのjavascriptファイルの評価
public class JSEngine {
/*
* Note Nashorn is only available for Java-8 onwards
* You can use rhino from ScriptEngineManager.getEngineByName("js");
*/
ScriptEngine engine;
ScriptContext context;
public Bindings scope;
// Initialize the Engine from its factory in scripting mode
public JSEngine(){
engine = new NashornScriptEngineFactory().getScriptEngine("-scripting");
// Script context is an interface so we need an implementation of it
context = new SimpleScriptContext();
// Create bindings to expose variables into
scope = engine.createBindings();
}
// Clear the bindings to remove the previous variables
public void newBatch(){
scope.clear();
}
public void execute(String file){
try {
// Get a buffered reader for input
BufferedReader br = new BufferedReader(new FileReader(file));
// Evaluate code, with input as bufferdReader
engine.eval(br);
} catch (FileNotFoundException ex) {
Logger.getLogger(JSEngine.class.getName()).log(Level.SEVERE, null, ex);
} catch (ScriptException ex) {
// Script Exception is basically when there is an error in script
Logger.getLogger(JSEngine.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void eval(String code){
try {
// Engine.eval basically treats any string as a line of code and evaluates it, executes it
engine.eval(code);
} catch (ScriptException ex) {
// Script Exception is basically when there is an error in script
Logger.getLogger(JSEngine.class.getName()).log(Level.SEVERE, null, ex);
}
}
// Apply the bindings to the context and set the engine's default context
public void startBatch(int SCP){
context.setBindings(scope, SCP);
engine.setContext(context);
}
// We use the invocable interface to access methods from the script
// Invocable is an optional interface, please check if your engine implements it
public Invocable invocable(){
return (Invocable)engine;
}
}
今の主な方法
public static void main(String[] args) {
JSEngine jse = new JSEngine();
// Create a new batch probably unecessary
jse.newBatch();
// Expose variable x into script with value of hello world
jse.scope.put("x", "hello world");
// Apply the bindings and start the batch
jse.startBatch(ScriptContext.ENGINE_SCOPE);
// Evaluate the code
jse.eval("print(x);");
}
あなたの出力はこれに似ているはずです
hello world
あなたが見ることができるように、露出変数xが印刷されています。今すぐファイルをテストします。
ここにはtest.jsがあります
print(x);
function test(){
print("hello test.js:test");
}
test();
そして、更新されたmainメソッド
public static void main(String[] args) {
JSEngine jse = new JSEngine();
// Create a new batch probably unecessary
jse.newBatch();
// Expose variable x into script with value of hello world
jse.scope.put("x", "hello world");
// Apply the bindings and start the batch
jse.startBatch(ScriptContext.ENGINE_SCOPE);
// Evaluate the code
jse.execute("./test.js");
}
test.jsがアプリケーションと同じディレクトリにあると仮定すると、このような出力が得られるはずです
hello world
hello test.js:test