node-java でリフレクションする

Node スクリプトから( jar にある)Java 実装の情報を集めたい。

Node から Java を操りたい人向けのライブラリがなぜか存在している。 node-java
インストール方法は特に説明しないが、私は “node-gyp” でコケたので “windows-build-tools” を使ってインストールできた。

JavaScript から Java を動かす、と言うと、ややこしい。

インストール

1
$ yarn add java

リフレクションにより、 ArrayList<T>add<T> を取得して実行している。 “node-java” のオプションは指定していない。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const java = require("java");

function getClassObjectOfSync(name) {
return java.callStaticMethodSync("java.lang.Class", "forName", name);
}

const list1 = java.newInstanceSync("java.util.ArrayList");
console.log(list1.sizeSync()); // 0
list1.addSync('item1');
console.log(list1.sizeSync()); // 1

const arrayListClass = java.callStaticMethodSync("java.lang.Class", "forName", "java.util.ArrayList");
console.log(arrayListClass.getMethodsSync().map(x => ({
name: x.getNameSync(),
params: x.getParameterTypesSync().map(y => y.getNameSync())
})));

const objectClass = java.callStaticMethodSync("java.lang.Class", "forName", "java.lang.Object");
const list1Add = arrayListClass.getMethodSync("add", objectClass);
console.log(list1Add.toGenericStringSync());
list1Add.invokeSync(list1, 1234);
console.log(list1.sizeSync()); // 2

console.log(list1.getSync(0)); // item1
console.log(list1.getSync(1)); // 1234

Tips

  • foo.MyClass.class という表現は使えないので、変わりに java.lang.Class.forName("foo.MyClass") を使う。つまり、java.callStaticMethodSync("java.lang.Class", "forName", "foo.MyClass") を実行する。
  • 補完や型チェックは効かない。
  • Java コードの eval や新たな定義はできないため、回り道を探すか、本当に必要なら Java で実装して jar を classpath につっこむ。
  • その他は、 Java のリフレクションで躓くところを気をつければ良い。