ともさんのHP >プロブラミング >自作JavaLibrary >JavaでJavaScriptを実行
JavaからJavaScriptを呼び出して実行するサンプルプログラム
Javaプログラムから
Java
楽天 Scriptを呼び出し、そのScriptからJavaのメソッドを呼び出すサンプルプログラムです。
処理の手順を図にすると、下のような感じになります。
JavaScriptを使うのではなくて、JavaがJavaScriptを解読して実行しています。
使用目的
私が製作しているフリーソフトの洋裁CADにマクロ機能が欲しかったのです。
洋裁CADはJavaで書いているのですが、いろいろ調べてみるとJavaScriptをJavaから呼び出せると知ったので、JavaScriptをマクロとして使ってみようと考えました。
CADなので線を描くのですが、複雑な数値計算を入力する事が苦手でした。
曲線Aの長さ = 直線Bの長さ + 曲線Cの長さ
くらいならよいのですが、
曲線Aの長さ = ( 直線Bの長さ + 曲線Cの長さ ) / 2 + 直線Dの長さ × Sin( 30°)
くらいになるともうお手上げ。
JavaScriptを使えば、このわずらわしさを解決できます。
それよりも効果が期待できるのは、パターンのライブラリ化です。
袖とか襟などの決まりきった部品はマクロで記述して個別にに保管しておき、必要に応じて呼び出します。
呼び出し時に必要な情報(袖であれば袖ぐり長さや袖山高さ)を渡し、呼び出した身頃に合致したサイズ形状で描画させることができます。
もう一つは分岐処理。ループ処理は洋裁CADの仕様にあるのですが、分岐も時々欲しいと感じるときがあります。
初期条件に男性か女性を選ぶようにして描画させれば、条件を変えるだけで男女別のパターン楽天 に自動製図させることも可能です。
JavaScriptエンジン
Javaの中でJavaScriptを動かすには、JavaScriptを読んで解釈するJavaScriptエンジンが必要になります。
Java7まではJavaScriptスクリプティングエンジンとしてRhinoが同梱されていましたが、Java8からはNashornが同梱されるようになりました。
普通ならNashornを使うべきところですが、このNashorn、Java11からは非推奨となり、いずれ廃止されてしまうようです。
困りましたね。
Nashornの後継としてGraalJSがあるそうですが、まだあまり情報がないので、RinoとNashornのサンプルプログラムを作ってみました。
Nashorn用サンプルプログラム
まずはNashorn用のJavaプログラム。
JavaScriptを記述したファイル「TestNashorn.js」を読み込んで実行します。
IO試験オブジェクト「iotest」を作り、JavaScriptに渡しています。JavaScriptの中でiotestに格納された数値を変更する作業をしています。
package tomojavalib.script;
import java.io.*;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
/*
ファイルに記述されたJavaScriptを読み込んでJavaで実行する
JavaScriptにオブジェクトを渡し、Script内でオブジェクトの設定を変更する
*/
public class TestNashorn {
public static void main(String[] args) {
TestNashorn t = new TestNashorn();
String s ="";
try{
File file = new File("D:/work/tmp/TestNashorn.js" );
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file) , "UTF-8" ));
String data;
while ((data = bufferedReader.readLine()) != null) {
System.out.println(data);
s=s+data;
}
bufferedReader.close();
}catch(Exception e){};
t.exe( s );
}
public void exe(String script) {
ScriptEngineManager sem = new ScriptEngineManager();
ScriptEngine se = sem.getEngineByName("JavaScript");
IOTest iotest = new IOTest();
try {
se.put( "io" , iotest );
se.eval(script);
} catch (ScriptException e) { e.printStackTrace(); }
System.out.println( iotest.getA() );
}
}
Nashorn用のJavaScriptプログラム「TestNashorn.js」
var a = io.getA() +io.getB();
print(' a = '+a);
io.setA(a);
print( io.getA() );
Rhino用サンプルプログラム
Rhino用のJavaプログラム。
JavaScriptを記述したファイル「TestRhino.js」を読み込んで実行します。
IO試験オブジェクト「iotest」を作り、JavaScriptに渡しています。JavaScriptの中でiotestに格納された数値を変更する作業をしています。
package tomojavalib.script;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
public class TestRhino {
public static void main(String[] args) {
TestRhino t = new TestRhino();
String s ="";
try{
File file = new File("D:/work/tmp/TestRhino.js" );
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file) , "UTF-8" ));
String data;
while ((data = bufferedReader.readLine()) != null) {
System.out.println(data);
s=s+data;
}
bufferedReader.close();
}catch(Exception e){};
t.exe( s );
}
public void exe(String script) {
IOTest iotest = new IOTest();
Context context = Context.enter();
try {
ScriptableObject scope = context.initStandardObjects();
Scriptable that = context.newObject(scope);
Function fct = context.compileFunction(scope, script , "script", 1, null);
Object result = fct.call( context , scope , that , new Object[] { iotest } );
System.out.println( Context.jsToJava( result , int.class ) );
} finally {
Context.exit();
}
return;
}
}
Rhino用のJavaScriptプログラム「TestRhino.js」
function abc( iotest ) {
var a = iotest.getA() +iotest.getB();
iotest.setA(a);
var x = iotest.getA();
return x;
}
IO試験用のclass「IOTest.java」
package tomojavalib.script;
public class IOTest {
int a =1;
int b =1;
public IOTest() {}
public void setA( int aa ) { this.a =aa; }
public int getA() { return a ; }
public void setB( int bb ) { this.b =bb; }
public int getB() { return b ; }
}
最終更新日: 2019-06-10 10:32:10
ともさんのHP >プロブラミング >自作JavaLibrary >JavaでJavaScriptを実行
ツイート