Java8のNashornでJavaScriptのエラー表示がわかりやすくなっている!

またまた今更ですが、id:skrbさんの記事Java技術最前線 - 「Java SE 6完全攻略」第59回 Javaでマルチリンガル - スクリプト言語のサポート その2:ITproを写経してJava8のNashornを試してみました。


JavaScriptJavaから実行するのですが、JavaScriptにエラーがあった場合のエラーは表示がNashornではとてもわかりやすくなっていました。

  • Nashornでのエラー表示

  • Rhinoでのエラー表示

  • Java8でNashornを使用してエラー表示している実装
import java.io.Reader;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class ScriptSample3 {
    public ScriptSample3() {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("Nashorn");  // *** ここで「Nashorn」を指定
        System.out.println(String.format("*** Engine:%s", engine.getFactory().getEngineName()));
        Path path = Paths.get("/Users/tomo/Hello.js");  // 対象のJavaScriptファイルを指定
            try (Reader reader = Files.newBufferedReader(path, Charset.defaultCharset())) {
                engine.put(ScriptEngine.FILENAME, path.getFileName().toString());
                engine.eval(reader);
            } catch (ScriptException se) {
                System.out.println(se.getMessage());  // ここでエラーを表示
            } catch(IOException ioe) {
                System.out.println(ioe.getMessage());
            }
    }

    public static void main(String[] args) {
        new ScriptSample3();
    }
}
  • Java7でRhinoを使用(上記のJava8とはScriptEngineを「rhino」に指定している以外は同じ)

Rhino」とするとエラーになるので「rhino」としてます)

import java.io.IOException;
import java.io.Reader;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class ScriptSample3 {
    public ScriptSample3() {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("rhino"); // ***ここで「Rhino」を指定
        System.out.println(String.format("*** Engine:%s", engine.getFactory().getEngineName()));
        Path path = Paths.get("/Users/tomo/Hello.js");
            try (Reader reader = Files.newBufferedReader(path, Charset.defaultCharset())) {
                engine.put(ScriptEngine.FILENAME, path.getFileName().toString());
                engine.eval(reader);
            } catch (ScriptException se) {
                System.out.println(se.getMessage());
            } catch (IOException ioe) {
                System.out.println(ioe.getMessage());
        }
    }

    public static void main(String[] args) {
        new ScriptSample3();
    }
}
var names = ['world', 'Java'];
for ( i=0; i< names.length;i++) {
    print('Hello ' + names[i] + '\n';  //ここの最後にカッコがないのでエラー
}

実装の詳細は、上記の記事を参考にして下さい。

  • 参考までにサポートされているScriptを表示してみました。

ここで「rhino」となっていることを確認しました。ここでもJava技術最前線 - 「Java SE 6完全攻略」第59回 Javaでマルチリンガル - スクリプト言語のサポート その2:ITproを写経して使っています。

import java.util.List;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;

public class ScriptSample {
    public static void main(String[] args) {
        ScriptEngineManager manager = new ScriptEngineManager();
        List<ScriptEngineFactory> factories = manager.getEngineFactories();
        for (ScriptEngineFactory factory : factories) {
            System.out.println("----------------------------------------------------------------------");
            System.out.println(String.format("Engine Name:%s", factory.getEngineName()));
            System.out.println(String.format("Engine Version:%s", factory.getEngineVersion()));
            System.out.println(String.format("Language Name:%s", factory.getLanguageName()));
            System.out.println(String.format("Language Version:%s", factory.getLanguageVersion()));
            System.out.print("Name:");
            for (String name : factory.getNames()) {
                System.out.print(String.format("%s, ", name));
            }
            System.out.println();
            System.out.print("Extention:");
            for (String ex : factory.getExtensions()) {
                System.out.print(String.format("%s, ", ex));
            }
            System.out.println();
            System.out.print("MIME:");
            for (String mime : factory.getMimeTypes()) {
                System.out.print(String.format("%s, ", mime));
            }
            System.out.println();
        }
    }
}

いろいろ勉強不足ですが、記事を写経することで新たな発見があって楽しいです♪