2013/04/18

Node-Javaを使ってSikuliをJavaScriptで操作する

Node-Javaという、JavaScriptからJavaを利用できるNodeのライブラリがあります。

これを使ってSikuliをJavaScriptから操作するようにしたら、JavaScirptのテストフレームワークが楽に使えて便利かなあと思って試してみました。

結論から言えば、MacではNode-JavaからSikuliが使えませんでした。 Windowsでは動作するようなので備忘録も兼ねて作業手順を記しておきます。

Windowsの場合

Windowsでは問題なく動作します。

次のように、JAVA_HOMEにJDKへのパスを通して、npm installするだけです。

> set JAVA_HOME=C:\Program Files (x86)\Java\jdk1.7.0_17
> npm install java

これで実行できます。このソースは、node-sikuliを参考にしています。

sikuli = new (function() {
    this.java = require('java');

    this.java.classpath.push('C:\\Program Files (x86)\\Sikuli X\\sikuli-script.jar')

    var c =  ["Settings", "Screen", "Region", "Pattern", "Match", "Finder", "TextRecognizer", "App"];
    for (var i = 0, len = c.length; i < len; i++) {
        x = c[i];
        this[x] = this.java.import('org.sikuli.script.'+x);
    }
});

app = new sikuli.App('cmd.exe')
app.windowSync(0).clickSync('node')

Windowsでは実行するときには%JAVA_HOME%\jre\bin\clientをPATHに追加しておく必要があります。 実行結果は次のようになります。

> set PATH=%PATH%;%JAVA_HOME%\jre\bin\client
> C:\tmp\sikuli-node>node sample.js
[info] Sikuli vision engine loaded.
[info] Text Recognizer inited.
[info] Windows utilities loaded.
[info] VDictProxy loaded.
[log] CLICK on (473,265)

Macの場合

インストールは問題なくできます。

$ npm install java
npm http GET https://registry.npmjs.org/java
npm http 200 https://registry.npmjs.org/java
npm http GET https://registry.npmjs.org/java/-/java-0.2.2.tgz
npm http 200 https://registry.npmjs.org/java/-/java-0.2.2.tgz

> java@0.2.2 install /Users/safx/src/node-java/node_modules/java
> node-gyp rebuild

gyp http GET http://nodejs.org/dist/v0.10.1/node-v0.10.1.tar.gz
gyp http 200 http://nodejs.org/dist/v0.10.1/node-v0.10.1.tar.gz
  CXX(target) Release/obj.target/nodejavabridge_bindings/src/java.o
../src/java.cpp:148:3: warning: 'JNI_GetDefaultJavaVMInitArgs' is deprecated [-Wdeprecated-declarations]
  JNI_GetDefaultJavaVMInitArgs(&args);
  ^
/System/Library/Frameworks/JavaVM.framework/Headers/jni.h:1934:1: note: 'JNI_GetDefaultJavaVMInitArgs' declared here
JNI_GetDefaultJavaVMInitArgs(void *args);
^
../src/java.cpp:153:3: warning: 'JNI_CreateJavaVM' is deprecated [-Wdeprecated-declarations]
  JNI_CreateJavaVM(&jvmTemp, (void **)env, &args);
  ^
/System/Library/Frameworks/JavaVM.framework/Headers/jni.h:1937:1: note: 'JNI_CreateJavaVM' declared here
JNI_CreateJavaVM(JavaVM **pvm, void **penv, void *args);
^
2 warnings generated.
  CXX(target) Release/obj.target/nodejavabridge_bindings/src/javaObject.o
  CXX(target) Release/obj.target/nodejavabridge_bindings/src/javaScope.o
  CXX(target) Release/obj.target/nodejavabridge_bindings/src/methodCallBaton.o
  CXX(target) Release/obj.target/nodejavabridge_bindings/src/nodeJavaBridge.o
  CXX(target) Release/obj.target/nodejavabridge_bindings/src/utils.o
  SOLINK_MODULE(target) Release/nodejavabridge_bindings.node
  SOLINK_MODULE(target) Release/nodejavabridge_bindings.node: Finished
java@0.2.2 node_modules/java

ただし、実行時にエラーになります。

2013-03-28 00:06:31.971 node[77439:707] Apple AWT Java VM was loaded on first thread -- can't start AWT.
Error: Could not create class org.sikuli.script.Screen
java.lang.InternalError: Can't start the AWT because Java was started on the first thread.  Make sure StartOnFirstThread is not specified in your application's Info.plist or on the command line
    at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1827)
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1724)
    at java.lang.Runtime.loadLibrary0(Runtime.java:823)
    at java.lang.System.loadLibrary(System.java:1045)

Node-Javaのissueでも上がっていますが、MacでAWTを利用するときにエラーになります。

-Djava.awt.headless=trueを指定して、headlessモードで起動すれば大丈夫なライブラリあるようですが、Sikuliはjava.awt.Robotとかを使っているらしく、ここらへんはheadlessだと例外を発生してしまいます。

おわりに

Node-Javaを導入してSikuliをJavaScriptで利用する手順について説明しました。Node-Java自体はいろいろ便利そうなのでまた使ってみたいです。

関連リンク

0 件のコメント:

コメントを投稿

注: コメントを投稿できるのは、このブログのメンバーだけです。