A.jar、B.jar という名前の単純な Java アプリケーションをいくつか作成しました。
ここで、ユーザーがボタン A を押して A.jar を実行し、ボタン B を押して B.jar を実行できるように、GUI Java プログラムを作成したいと考えています。
また、実行時のプロセスの詳細を GUI プログラムに出力したいと考えています。
なにか提案を?
A.jar、B.jar という名前の単純な Java アプリケーションをいくつか作成しました。
ここで、ユーザーがボタン A を押して A.jar を実行し、ボタン B を押して B.jar を実行できるように、GUI Java プログラムを作成したいと考えています。
また、実行時のプロセスの詳細を GUI プログラムに出力したいと考えています。
なにか提案を?
私の理解が正しければ、Java GUI アプリケーション内とは別のプロセスで jar を実行したいようです。
これを行うには、次を使用できます。
// Run a java app in a separate system process
Process proc = Runtime.getRuntime().exec("java -jar A.jar");
// Then retreive the process output
InputStream in = proc.getInputStream();
InputStream err = proc.getErrorStream();
プロセスの出力をバッファリングすることは常に良い習慣です。
.jar は実行できません。クラスをインスタンス化するか、任意の静的メソッドを呼び出します。
編集: JAR の作成中に Main-Class エントリを追加します。
>p.mf (p.mf の内容)
メインクラス: pk.Test
>Test.java
package pk;
public class Test{
public static void main(String []args){
System.out.println("Hello from Test");
}
}
Process クラスとそのメソッドを使用し、
public class Exec
{
public static void main(String []args) throws Exception
{
Process ps=Runtime.getRuntime().exec(new String[]{"java","-jar","A.jar"});
ps.waitFor();
java.io.InputStream is=ps.getInputStream();
byte b[]=new byte[is.available()];
is.read(b,0,b.length);
System.out.println(new String(b));
}
}
お役に立てれば:
public class JarExecutor {
private BufferedReader error;
private BufferedReader op;
private int exitVal;
public void executeJar(String jarFilePath, List<String> args) throws JarExecutorException {
// Create run arguments for the
final List<String> actualArgs = new ArrayList<String>();
actualArgs.add(0, "java");
actualArgs.add(1, "-jar");
actualArgs.add(2, jarFilePath);
actualArgs.addAll(args);
try {
final Runtime re = Runtime.getRuntime();
//final Process command = re.exec(cmdString, args.toArray(new String[0]));
final Process command = re.exec(actualArgs.toArray(new String[0]));
this.error = new BufferedReader(new InputStreamReader(command.getErrorStream()));
this.op = new BufferedReader(new InputStreamReader(command.getInputStream()));
// Wait for the application to Finish
command.waitFor();
this.exitVal = command.exitValue();
if (this.exitVal != 0) {
throw new IOException("Failed to execure jar, " + this.getExecutionLog());
}
} catch (final IOException | InterruptedException e) {
throw new JarExecutorException(e);
}
}
public String getExecutionLog() {
String error = "";
String line;
try {
while((line = this.error.readLine()) != null) {
error = error + "\n" + line;
}
} catch (final IOException e) {
}
String output = "";
try {
while((line = this.op.readLine()) != null) {
output = output + "\n" + line;
}
} catch (final IOException e) {
}
try {
this.error.close();
this.op.close();
} catch (final IOException e) {
}
return "exitVal: " + this.exitVal + ", error: " + error + ", output: " + output;
}
}
jar がクラスパスにあり、そのメイン クラスがわかっている場合は、メイン クラスを呼び出すだけです。例として DITA-OT を使用します。
import org.dita.dost.invoker.CommandLineInvoker;
....
CommandLineInvoker.main('-f', 'html5', '-i', 'samples/sequence.ditamap', '-o', 'test')
これにより、下位のjarがメモリ空間とクラスパスをjarと共有し、干渉の可能性がすべて生じることに注意してください。そのようなものを汚染したくない場合は、上記のように他のオプションがあります-つまり:
Runtime.getRuntime.exec(...)
(jar を完全に分離しますが、通常の「アプリケーションを見つける」、「文字列を正しくエスケープする」、「プラットフォーム固有の WTF」、および「OMG システム スレッド」の実行中のシステム コマンドの落とし穴があります。Java 1.6 の場合は、次の操作も実行できます。
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
public class CompilerExample {
public static void main(String[] args) {
String fileToCompile = "/Users/rupas/VolatileExample.java";
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
int compilationResult = compiler.run(null, null, null, fileToCompile);
if (compilationResult == 0) {
System.out.println("Compilation is successful");
} else {
System.out.println("Compilation Failed");
}
}
}