2015年10月4日
node.jsからjavaのモジュールを呼び出し、実行する
1.child_processモジュールを使う
通常、nodejsから外部モジュールを動かす場合、通常child_processモジュールを使う。
/* Spawn on Node JS (Windows Server 2012) http://stackoverflow.com/questions/18334181/spawn-on-node-js-windows-server-2012 node.jsのchild_processをWindowsで使う http://hack.aipo.com/archives/11522/ usage node pipe.js > a.html ”あさイチ”のデータはこちらのサイトから http://www.officiallyjd.com/archives/450455/ 市原悦子がNHK『あさイチ』で放送禁止用語を連発 有働由美子アナが謝罪する事態に */ var iconv = require('iconv-lite'); var spawn = require('child_process').spawn; var cp = spawn(process.env.comspec, ['/c', 'java', '-cp', './;commons-codec-1.10.jar;juniversalchardet-1.0.3.jar;', 'NGWord', 'ngword.csv', 'あさイチ2.txt']); cp.stdout.on("data", function(data) { console.log('<!DOCTYPE HTML><html><head><meta charset="UTF-8"></head><body>'); console.log(iconv.decode(data, "Shift_JIS")); console.log('</body></html>'); });
2.javaモジュールを使う
node.jsにはJavaを動かすためのjavaモジュール(ブリッジAPIモジュール)がある。このモジュールを用いると、下記のようなプにJavaの各クラスをnode.jsで制御しているようなコードになる。classpath.pushでjarファイルなどの環境を整えることができ、java.newInstanceSync("NGWord")で"NGWord"のインスタンスを派生させることができる。何かをアクセスするとき、○○Syncとすることが必須である。
child_processモジュールはstdin、stdoutを介して、node.jsに結果を取り込む。一方javaモジュールはJavaの各メソッドの戻り値をそのまま扱うことできることが特徴である。
/* Bridge API to connect with existing Java APIs https://github.com/joeferner/node-java usage java -cp "./;commons-codec-1.10.jar;juniversalchardet-1.0.3.jar;" NGWord ngword.csv あさイチ.txt node jv.js ngword.csv あさイチ.txt > b.html */ var fs = require("fs"); var java = require("java"); java.classpath.push("./"); java.classpath.push("commons-codec-1.10.jar"); java.classpath.push("juniversalchardet-1.0.3.jar"); var ng = java.newInstanceSync("NGWord"); var tm = java.newInstanceSync("TreeMatcher", process.argv[2]); var tb = java.newInstanceSync("TwoByteToOneByte"); fs.readFile(process.argv[3], 'utf8', function(err, data) { console.log(''); var lines = data.split("\r\n"); for(var i in lines){ var line = tb.convertSync( lines[i], false ) ; //半角変換 tm.matchSync( line ) ; var s = ng.toHigtLightSync( lines[i], tm.getDataSync( ) ) ; console.log(s); } console.log(''); });
”socket.io”を利用し、HTTP通信のようにブラウジングできるシステム形態の実現。
メモ1. windowsへ、javaモジュールのインストール
C:\node\chat\ng>npm install -g java
\
> java@0.6.0 install
C:\Users\osaka\AppData\Roaming\npm\node_modules\java
> node-gyp rebuild
C:\Users\osaka\AppData\Roaming\npm\node_modules\java>if
not defined npm_config_n
ode_gyp (node "C:\Program Files\nodejs\node_modules\npm\bin\node-gyp-bin\\..\..\
node_modules\node-gyp\bin\node-gyp.js" rebuild ) else (node rebuild )
このソリューション内のプロジェクトを 1 度に 1 つづつビルドします。並行ビルドを有
効にするには、"/m" スイッチを追加してください。
java.cpp
javaObject.cpp
javaScope.cpp
methodCallBaton.cpp
nodeJavaBridge.cpp
C:\Program Files (x86)\Microsoft Visual
Studio 12.0\VC\include\xlocale(337): wa
rning C4530: C++ 例外処理を使っていますが、アンワインド セマンティクスは有効には
なりません。/EHsc を指定してください。 (..\src
\java.cpp)
[C:\Users\osaka\AppData\Roaming\npm\node_modules\java\build\nodejava
bridge_bindings.vcxproj]
C:\Program Files (x86)\Microsoft Visual
Studio 12.0\VC\include\xlocale(337): wa
rning C4530: C++ 例外処理を使っていますが、アンワインド セマンティクスは有効には
なりません。/EHsc を指定してください。 (..\src
\methodCallBaton.cpp)
[C:\Users\osaka\AppData\Roaming\npm\node_modules\java\bui
ld\nodejavabridge_bindings.vcxproj]
C:\Program Files (x86)\Microsoft Visual
Studio 12.0\VC\include\xlocale(337): wa
rning C4530: C++ 例外処理を使っていますが、アンワインド セマンティクスは有効には
なりません。/EHsc を指定してください。 (..\src
\javaObject.cpp)
[C:\Users\osaka\AppData\Roaming\npm\node_modules\java\build\no
dejavabridge_bindings.vcxproj]
C:\Program Files (x86)\Microsoft Visual
Studio 12.0\VC\include\xlocale(337): wa
rning C4530: C++ 例外処理を使っていますが、アンワインド セマンティクスは有効には
なりません。/EHsc を指定してください。 (..\src
\nodeJavaBridge.cpp)
[C:\Users\osaka\AppData\Roaming\npm\node_modules\java\buil
d\nodejavabridge_bindings.vcxproj]
utils.cpp
C:\Program Files (x86)\Microsoft Visual
Studio 12.0\VC\include\xlocale(337): wa
rning C4530: C++ 例外処理を使っていますが、アンワインド セマンティクスは有効には
なりません。/EHsc を指定してください。 (..\src
\utils.cpp)
[C:\Users\osaka\AppData\Roaming\npm\node_modules\java\build\nodejav
abridge_bindings.vcxproj]
ライブラリ C:\Users\osaka\AppData\Roaming\npm\node_modules\java\build\Relea
se\n
odejavabridge_bindings.lib とオブジェクト
C:\Users\osaka\AppData\Roaming\npm\n
ode_mo
dules\java\build\Release\nodejavabridge_bindings.exp
を作成中
コード生成しています。
コード生成が終了しました。
nodejavabridge_bindings.vcxproj ->
C:\Users\osaka\AppData\Roaming\npm\node_mo
dules\java\build\Release\\nodejavabridge_bindings.node
> java@0.6.0 postinstall
C:\Users\osaka\AppData\Roaming\npm\node_modules\java
> node postInstall.js
npm WARN unmet dependency
C:\Users\osaka\AppData\Roaming\npm\node_modules\foreve
r\node_modules\cliff
requires colors@'0.x.x' but will load
npm WARN unmet dependency
C:\Users\osaka\AppData\Roaming\npm\node_modules\foreve
r\node_modules\colors,
npm WARN unmet dependency which is version 0.6.0-1
npm WARN unmet dependency
C:\Users\osaka\AppData\Roaming\npm\node_modules\foreve
r\node_modules\winston requires colors@'0.6.x' but will load
npm WARN unmet dependency
C:\Users\osaka\AppData\Roaming\npm\node_modules\foreve
r\node_modules\colors,
npm WARN unmet dependency which is version 0.6.0-1
npm WARN unmet dependency
C:\Users\osaka\AppData\Roaming\npm\node_modules\foreve
r\node_modules\cliff\node_modules\winston requires
colors@'0.x.x' but will load
npm WARN unmet dependency
C:\Users\osaka\AppData\Roaming\npm\node_modules\foreve
r\node_modules\colors,
npm WARN unmet dependency which is version 0.6.0-1
npm WARN unmet dependency
C:\Users\osaka\AppData\Roaming\npm\node_modules\foreve
r\node_modules\flatiron\node_modules\broadway\node_modules\winston
requires colo
rs@'0.x.x' but will load
npm WARN unmet dependency
C:\Users\osaka\AppData\Roaming\npm\node_modules\foreve
r\node_modules\colors,
npm WARN unmet dependency which is version 0.6.0-1
npm WARN unmet dependency C:\Users\osaka\AppData\Roaming\npm\node_modules\foreve
r\node_modules\flatiron\node_modules\prompt\node_modules\winston requires colors
@'0.x.x' but will load
npm WARN unmet dependency
C:\Users\osaka\AppData\Roaming\npm\node_modules\foreve
r\node_modules\colors,
npm WARN unmet dependency which is version 0.6.0-1
npm WARN unmet dependency
C:\Users\osaka\AppData\Roaming\npm\node_modules\foreve
r\node_modules\forever-monitor\node_modules\broadway\node_modules\winston
requir
es colors@'0.x.x' but will load
npm WARN unmet dependency
C:\Users\osaka\AppData\Roaming\npm\node_modules\foreve
r\node_modules\colors,
npm WARN unmet dependency which is version 0.6.0-1
java@0.6.0
C:\Users\osaka\AppData\Roaming\npm\node_modules\java
├── async@0.9.0
├── find-java-home@0.1.2 (which@1.0.9)
├── nan@2.0.9
├── glob@5.0.5 (path-is-absolute@1.0.0,
inherits@2.0.1, once@1.3.2, inflight@
1.0.4, minimatch@2.0.10)
└── lodash@3.7.0
メモ2.javaモジュールを動かしたらエラーが出た
半年ぶりにnode.jsでjavaモジュールを動かしところ、“Module._extensions[extension](this,
filename)”のエラーメッセージが出て、困っていた。
でも、この現象はよくあるらしい。
C:\node\chat\ng>node jv.js ngword2.csvあさイチ.txt
module.js:355
Module._extensions[extension](this, filename);
^
Error: The specified module could not be
found.
C:\node\node_modules\java\build\Release\nodejavabridge_bindings.node
at Error (native)
at Module.load
(module.js:355:32)
at Function.Module._load
(module.js:310:12)
at Module.require
(module.js:365:17)
at require
(module.js:384:17)
at Object.<anonymous>
(C:\node\node_modules\java\lib\nodeJavaBridge.
js:10:16)
at Module._compile
(module.js:460:26)
at
Object.Module._extensions..js (module.js:478:10)
at Module.load
(module.js:355:32)
at Function.Module._load
(module.js:310:12)
”Error: Module version mismatch. Expected
11, got 1”
http://stackoverflow.com/questions/20099334/error-module-version-mismatch-expected-11-got-1
上記のサイトに従い、npm updateを行ったところ、正常な動作となった。
(記 大坂 哲司)