LoginSignup
12
15

More than 5 years have passed since last update.

Node.jsでjavaを呼びだす時のトラブル及び対策

Last updated at Posted at 2016-01-28

導入

node.jsのマルチプロセスモジュールChild Processで新たなプロセスを作成する時、主にspawnexecforkというメソッドを使用する。
しかし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.

・・・

と、問題解決。

12
15
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
15