[Nashorn] JavaImporterでまとめてimportする

投稿日: 2015/12/13 5:04:21

1つ以上のJavaパッケージをまとめてimportしたい場合は、Rhinoと同様にJavaImporterを使用できます。OpenJDK WikiのNashorn extensionsではJavaImporterをwithステートメントと共に使う方法が紹介されていますが、JavaImporterのプロパティとしてJavaクラスを参照することもできます。

注意点として、Java.type()関数は存在しないクラス名が指定されるとjava.lang.ClassNotFoundExceptionをthrowするのに対し、JavaImporterはnullを返すことです(undefinedではありません)。

ちなみに、グローバルオブジェクトのPackagesとjavaに対して存在しないクラス名をプロパティ名として指定すると、Javaパッケージが返されてしまいます(文字列表現は[object JavaPackage])。このような方法で返されたJavaパッケージをnew演算子に対して使用すると例外を引き起こします。

1. 実行するスクリプト(javaImporter.js)

function getKeys(obj) { var keys = []; for (var key in obj) keys.push(key); return keys; }
var importerOfJavaTime = new JavaImporter(java.time, java.time.temporal);
print("Object.keys=" + Object.keys(importerOfJavaTime));
var now = importerOfJavaTime.LocalDateTime.now();
print(now.getClass() + "=${now}");
print("Object.keys=" + Object.keys(importerOfJavaTime));
with(importerOfJavaTime) {
    var dateTime = LocalDateTime.of(1999, 12, 31, 23, 59, 59);
    print("");
    print("dateTime=" + dateTime);
    print("dateTime.plusDays(1)=" + dateTime.plusDays(1));
    print("dateTime.truncatedTo(ChronoUnit.HOURS)=" + dateTime.truncatedTo(ChronoUnit.HOURS));
}
print("Object.keys=" + Object.keys(importerOfJavaTime));
print("");
print("importerOfJavaTime.BadClassName=${importerOfJavaTime.BadClassName}"); // null
with(importerOfJavaTime){ print("BadClassName=${BadClassName}"); } // null
print("java.time.BadClassName=${java.time.BadClassName}"); // [object JavaPackage]
try {
    var obj = new java.time.BadClassName();
} catch (e) {
    print(e); // java.lang.ClassNotFoundException
}

2. jjsで実行する

>jjs -scripting -fullversion javaImporter.js
nashorn full version 1.8.0_66-b18
Object.keys=
class java.time.LocalDateTime=2015-12-13T21:34:08.075
Object.keys=LocalDateTime
dateTime=1999-12-31T23:59:59
dateTime.plusDays(1)=2000-01-01T23:59:59
dateTime.truncatedTo(ChronoUnit.HOURS)=1999-12-31T23:00
Object.keys=LocalDateTime,ChronoUnit
importerOfJavaTime.BadClassName=null
BadClassName=null
java.time.BadClassName=[object JavaPackage]
java.lang.ClassNotFoundException: java.time.BadClassName