繁体   English   中英

在 Java 程序中执行另一个 jar

[英]Execute another jar in a Java program

我写了几个简单的java应用程序,分别命名为A.jar、B.jar。

现在我想编写一个 GUI java 程序,以便用户可以按下按钮 A 执行 A.jar 和按钮 B 执行 B.jar。

我还想在我的 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 时添加主类条目。

>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 来工作,以防程序作为独立运行:

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

如果 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 的插件。 插件是一对 jars - 接口和实现 - 被压缩在一起。 ClassLoader 都共享所有的接口,而每个 ClassLoader 只知道自己的实现。 堆栈有点复杂,但它通过了所有测试并且运行良好。
  • 使用Runtime.getRuntime.exec(...) (它完全隔离了 jar,但具有正常的“查找应用程序”、“正确转义字符串”、“特定于平台的 WTF”和“OMG 系统线程”陷阱运行系统命令。

首先,我们创建一个 FirstFileOutput 类,该类具有一个 main 方法,该方法将一行输出到稳定输出和一行到稳定错误。 对于所有第一个过程,我们将再次创建一个 RuntimeExecCheck 类,该类将在启动过程中运行我们的 FirstFileOutput 类,然后 RuntimeExecCheck 类将从 FirstFileOutput 和输出中读取稳定的输出和稳定的错误。

package check;

public class FirstFileOutput{

    public static void main(String[] args) {
        System.out.println("This is output to stable output");
        System.err.println("This is output to stable error");
    }
}



package check;

import java.io.InputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class RuntimeExecCheck {

    public static void main(String[] args) {
        try {
            Runtime runTime = Runtime.getRuntime();
            Process process = runTime.exec("java -classpath C:\\projects\\workspace\\check\\bin check.FirstFileOutput");
            InputStream inputStream = process.getInputStream();
            InputStreamReader isr = new InputStreamReader(inputStream);
            InputStream errorStream = process.getErrorStream();
            InputStreamReader esr = new InputStreamReader(errorStream);

            int n1;
            char[] c1 = new char[1024];
            StringBuffer stableOutput = new StringBuffer();
            while ((n1 = isr.read(c1)) > 0) {
                stableOutput.append(c1, 0, n1);
            }
            System.out.println("Stable Output: " + stableOutput.toString());

            int n2;
            char[] c2 = new char[1024];
            StringBuffer stableError = new StringBuffer();
            while ((n2 = esr.read(c2)) > 0) {
                stableError.append(c2, 0, n2);
            }
            System.out.println("Stable Error: " + stableError.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

如果您是 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");
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM