導入
node.jsのマルチプロセスモジュールChild Processで新たなプロセスを作成する時、主にspawn
、exec
、fork
というメソッドを使用する。
しかしexec
はプロセス間の通信は基本できないとされている。そしてfork
はnode.jsのみ使用できるので、javaの子プロセスを立ち上がり、しかも通信するにはspawn
しか使えない。
Round 1 : node.jsとclassファイルが同じフォルダにある
その場合、ことは極めて簡単に済ませられる。
- 1 まずはjava一個作る
test.java
class test {
public static void main(String argv[]){
//まずinitialパラメータを受信する
for ( int i = 0; i < argv.length; i++ ){
System.out.println("argv[" + i + "] = " + argv[i] );
}
//繰り返して入力を待ち、処理する
while(true){
System.out.println("input sth.");
Scanner input = new Scanner(System.in);
String s = input.next();
if (s.equals("break")){
break;
}
System.out.println("s = "+s);
}
}
}
- 2 そしてjavaをコンパイルし、テストしてみる
windows使っているんだ!文句あっか!?(笑)
C:\test\your_java_test>javac test.java
C:\test\your_java_test>java test Hello World
argv[0] = Hello
argv[1] = World
input sth.
test\n
s = test
input sth.
hello\n
s = hello
・・・
- 3 同じフォルダの中に、親プロセスにあたるjsを作る
test_java.js
var child = require('child_process');
//pipeを使って、プロセス間通信を行う
//引数'test'はclass名、no
var java = child.spawn( 'java', ['test','Hello','World'],{stdio:[ 'pipe',null,null, 'pipe' ]});
//受信するたびに、内容を返す
java.stdout.on('data', function(data){
//toString()を使わないと、バイナリのバッファー内容が返される
console.log("[java]"+data.toString());
});
//2秒間一回、親プロセスから子プロセスへ送信
setInterval(function () {
//送信内容は必ず"\n"で終わらせる
java.stdin.write("Hello\n");
},2000);
- 4 そのjsを回してみる
C:\test\your_java_test>node test_java.js
[java]argv[0] = Hello
argv[1] = World
[java]
input sth.
[java]s = Hello
input sth.
[java]s = Hello
input sth.
・・・
Round2 : 別のフォルダからjavaを呼び出す
- 1 先ほど作成したjsを一個上のフォルダにコピーしてpathを修正して、動かしてみると
events.js:72
throw er; // Unhandled 'error' event
^
Error: spawn ENOENT
at errnoException (child_process.js:1000:11)
at Process.ChildProcess._handle.onexit (child_process.js:791:34)
nodeかjavaかどちらが怒ったぜ。
- 2 トラブルシューティングしてみる
C:\test>java ./your_java_test test
Error:java error cannot find main class
と、やっぱりjvmが怒ったみたいだね…
いろいろ調べてみると、-classpath
入れるといいらしい。
C:\test>java -classpath ./your_java_test test
input sth.
aaa\n
s = aaa
では、jsの中身も改造してみよう
test_java2.js
//to test how to run java in different dir
var child = require('child_process');
var path = __dirname+'/'+'test_java';
console.log(path)
var java = child.spawn( 'java', ['-classpath',path,'test','Hello','World'],{stdio:[ 'pipe',null,null, 'pipe' ]});
// $ java -classpath [yourpath] [classname]
java.stdout.on('data', function(data){
console.log("[java]"+data.toString());
} );
setInterval(function () {
java.stdin.write("Hello\n");//must end by "\n"
},2000);
動かしてみると、
C:\test>node test_java.js
C:\test/your_java_test
[java]argv[0] = Hello
argv[1] = World
[java]
input sth.
[java]s = Hello
input sth.
・・・
と、問題解決。