私は単純なJavaプログラムに取り組んでいます。別のJavaプログラムをコンパイルして実行します。Runtime.exec()関数を使用してコンパイルおよび実行しています。コンパイルに問題はありませんが、実行時に2番目のプログラムがキーボードから読み取るための入力を必要とする場合、マスタープロセスからそれを与えることができません。getOutputStream()関数を使用しましたが、役に立ちませんでした。私のコードを提供します。
public class sam {
public static void main(String[] args) throws Exception {
try {
Process p = Runtime.getRuntime().exec("javac sam2.Java");
Process p2 = Runtime.getRuntime().exec("Java sam2");
BufferedReader in = new BufferedReader(
new InputStreamReader(p2.getInputStream()));
OutputStream out = p.getOutputStream();
String line = null;
line = in.readLine();
System.out.println(line);
input=input+"\n";
out.write(input.getBytes());
p.wait(10000);
out.flush();
}catch (IOException e) {
e.printStackTrace();
}
}
}
これは私のマスタープログラム(sam.Java)です。
以下はsam2.Javaのコードです
public class sam2 {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str;
System.out.println("Enter the number..\n");
str = br.readLine();
System.out.println(Integer.parseInt(str));
}
}
2番目のプログラムに印刷ステートメントしか含まれていない場合、問題はありません。しかし、他から何かを読まなければならないときに問題が発生します。
少し奇妙ですが、2つ目のプログラムをフォークせずに実行できます。その中のmainメソッドを呼び出すだけです。したがって、ランタイムセクションを忘れて、次のようにします。
sam2.main(new String[0]);
もちろん、この方法では、コンパイル時にsam2をコンパイルする必要があります
各プロセスの実行と終了を許可する必要があります。この目的でProcess#waitFor
を使用できます。同様に、プロセスからの出力を同時に消費する必要があります。 waitFor
はブロックするため、Thread
を使用して入力を読み取る必要があります(必要に応じて、プロセスに出力を書き込みます)。
Java /クラスファイルの場所によっては、プロセスの実行を開始できる開始フォルダを指定する必要がある場合もあります。
これのほとんどはProcessBuilder
を使用すると大幅に簡単になります
import Java.io.File;
import Java.io.IOException;
import Java.io.InputStream;
public class CompileAndRun {
public static void main(String[] args) {
new CompileAndRun();
}
public CompileAndRun() {
try {
int result = compile("compileandrun/HelloWorld.Java");
System.out.println("javac returned " + result);
result = run("compileandrun.HelloWorld");
} catch (IOException | InterruptedException ex) {
ex.printStackTrace();
}
}
public int run(String clazz) throws IOException, InterruptedException {
ProcessBuilder pb = new ProcessBuilder("Java", clazz);
pb.redirectError();
pb.directory(new File("src"));
Process p = pb.start();
InputStreamConsumer consumer = new InputStreamConsumer(p.getInputStream());
consumer.start();
int result = p.waitFor();
consumer.join();
System.out.println(consumer.getOutput());
return result;
}
public int compile(String file) throws IOException, InterruptedException {
ProcessBuilder pb = new ProcessBuilder("javac", file);
pb.redirectError();
pb.directory(new File("src"));
Process p = pb.start();
InputStreamConsumer consumer = new InputStreamConsumer(p.getInputStream());
consumer.start();
int result = p.waitFor();
consumer.join();
System.out.println(consumer.getOutput());
return result;
}
public class InputStreamConsumer extends Thread {
private InputStream is;
private IOException exp;
private StringBuilder output;
public InputStreamConsumer(InputStream is) {
this.is = is;
}
@Override
public void run() {
int in = -1;
output = new StringBuilder(64);
try {
while ((in = is.read()) != -1) {
output.append((char) in);
}
} catch (IOException ex) {
ex.printStackTrace();
exp = ex;
}
}
public StringBuilder getOutput() {
return output;
}
public IOException getException() {
return exp;
}
}
}
ここで明らかに、プロセスの戻り結果を確認する必要があります。プロセスと対話するためのより良いメカニズムを生成する可能性がありますが、それが基本的な考え方です...
2番目のクラスのmainメソッドを呼び出すだけです。メインメソッドは他の静的メソッドと同じです。
メインクラスファイルを呼び出すだけです。たとえば、Javaクラスファイル名がxyz.Java
、Java SwingアプリケーションをクリックしてJButton
で同じように呼び出して実行できます。コードは
private void Btn_createdatabaseActionPerformed(Java.awt.event.ActionEvent evt) {
xyz.main(new String[0]);
}
それでおしまい...
これは私のために働いたものです:
try {
single.main(new String[0]);
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
}