Javaプログラムで別のjarを実行する


113

私はA.jar、B.jarという名前のいくつかの単純なJavaアプリケーションを作成しました。

ここで、ユーザーがボタンAを押してA.jarを実行し、ボタンBを押してB.jarを実行できるように、GUI Javaプログラムを作成します。

また、実行時プロセスの詳細をGUIプログラムに出力したいと思います。

なにか提案を?


31
なぜこれが否決されたのかわかりません。彼の仮定が間違っている理由を彼に説明しますが、質問には反対票を投じないでください。
ウィリアム・ブレンデル、

-1基本的なJava用語が正しく使用されておらず、質問は非常にあいまいであり、2番目の推測のために多く残します。質問をより詳細に言い換えるか、Javaクラスパスとその他の基本事項について最初に読んでください。
topchef 2009

21
@grigory:ほら、すぐに反対票を投じるのではなく、そもそもそれをあなたが尋ねるべきだったのです。詳細情報を要求することさえせずに反対票を投じることは、何の役にも立ちません...
ウィリアム・ブレンデル

4
@ウィリアム、あなたがしたより数秒遅れてボタンを押して申し訳ありません。私はその後のコメントで投票権を留保します。問題を理解または提示するための基本的な準備や努力なしに質問が表示されるのはイライラします。私にとって、投票はレストランのヒントのようです。サービスの品質に応じて、標準より12%多いか少ないかを決定します。ここで同意しないことに同意しましょう。
topchef 2009

1
@topchef私はこれに11年遅れていますが、「基本的な準備なしで質問が表示されるのを見るのはイライラします...」とあなたは言います。次に、それを修正するのに役立ちます。反対票を投じた理由を説明てください。そうでなければ、あなたはまったく問題を助けていません。
tylerr147

回答:


63

私が正しく理解している場合は、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();

プロセスの出力をバッファリングすることは常に良い習慣です。


21
このソリューションはポータブルですか?
パセリエ

3
ありがとう。「dir」パラメーターを含む3つのパラメーターでexec()funcを試してみましたが、機能しません。1つだけで、3つのファイル.jarを同じ場所に配置するだけです
Duc Tran

RuntimeそのJavaアプリケーションのオブジェクトを取得する方法を知っていますか?
stommestack 2014年

ProcessBuilderを使用して、よりポータブルなバージョンを使用できますか?
Anand Rockzz 2014

プログラム「java」を実行できません:CreateProcess error = 2、システムは指定されたファイルを見つけることができません。このエラーを取得しています。
紳士

27

.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));
    }
}

1
私は、jarへのアクセスが与えられたら、それをクラスパスに追加して、そこからクラスをロードする方法を考えています。
ジェリコ2009

1
注:PATHにJava binがあるためにのみ機能します。これは、デフォルトのWindowsインストールには
当てはまり

@AVD:A.jarファイルはどこに保存する必要がありますか?
ローガン、2014年

1
@logan-プログラムをロードするディレクトリ。
adatapost 2014年

このアプローチは、新しいJVMプロセスを作成するのですか、それとも既存のプロセスを使用するのですか?
RahulDeep Attri

17

お役に立てれば:

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;
}
}

0

jarがクラスパスにあり、そのMainクラスがわかっている場合は、メインクラスを呼び出すだけです。例としてDITA-OTを使用する:

import org.dita.dost.invoker.CommandLineInvoker;
....
CommandLineInvoker.main('-f', 'html5', '-i', 'samples/sequence.ditamap', '-o', 'test')

これにより、下位のjarがjarとメモリ空間およびクラスパスを共有し、干渉の可能性があるすべての可能性があることに注意してください。汚染されたくない場合は、上記のように他のオプションがあります。

  • jarを含む新しいClassLoaderを作成します。これはより安全です。エイリアンjarを利用することになるという知識を持ったものを構築する場合、少なくとも新しいjarの知識をコアクラスローダーに分離できます。これは、私たちのショップでプラグインシステムのために行っていることです。メインアプリケーションは、ClassLoaderファクトリ、APIのコピーを備えた小さなシェルであり、実際のアプリケーションがClassLoaderを構築する最初のプラグインであることを認識しています。プラグインは、インターフェースと実装の2つのjarファイルで、圧縮されています。ClassLoaderはすべてすべてのインターフェースを共有しますが、各ClassLoaderは自身の実装に関する知識しか持っていません。スタックは少し複雑ですが、すべてのテストに合格し、美しく動作します。
  • use Runtime.getRuntime.exec(...)(これはjarを完全に分離しますが、実行中のシステムコマンドの通常の「アプリケーションを見つける」、「文字列を正しくエスケープする」、「プラットフォーム固有のWTF」、および「OMGシステムスレッド」の落とし穴があります。

0

以下は、プログラムがスタンドアロンとして実行される場合に備えて、jarをバッチファイルで開始することで機能します。

public static void startExtJarProgram(){
        String extJar = Paths.get("C:\\absolute\\path\\to\\batchfile.bat").toString();
        ProcessBuilder processBuilder = new ProcessBuilder(extJar);
        processBuilder.redirectError(new File(Paths.get("C:\\path\\to\\JavaProcessOutput\\extJar_out_put.txt").toString()));
        processBuilder.redirectInput();
        try {
           final Process process = processBuilder.start();
            try {
                final int exitStatus = process.waitFor();
                if(exitStatus==0){
                    System.out.println("External Jar Started Successfully.");
                    System.exit(0); //or whatever suits 
                }else{
                    System.out.println("There was an error starting external Jar. Perhaps path issues. Use exit code "+exitStatus+" for details.");
                    System.out.println("Check also C:\\path\\to\\JavaProcessOutput\\extJar_out_put.txt file for additional details.");
                    System.exit(1);//whatever
                }
            } catch (InterruptedException ex) {
                System.out.println("InterruptedException: "+ex.getMessage());
            }
        } catch (IOException ex) {
            System.out.println("IOException. Faild to start process. Reason: "+ex.getMessage());
        }
        System.out.println("Process Terminated.");
        System.exit(0);
    }

次に、batchfile.batで次のように言うことができます。

@echo off
start /min C:\path\to\jarprogram.jar

-3

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");
        }
    }
}

4
これがOPの質問に答えるとは思わない
スリハルシャチラカパティ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.