【问题标题】:Executing another java program from our java program [duplicate]从我们的java程序执行另一个java程序[重复]
【发布时间】:2011-10-14 15:43:17
【问题描述】:

可能重复:
Execute a Java program from our Java program

我想从我们的 java 程序中执行另一个 java 程序。当我运行一个名为“First.java”的java程序时,它应该提示用户输入任何类名(.java文件名)的名称,然后它应该读取该输入(.java文件)并且应该能够编译并运行该程序。谁能给我一个示例代码?

【问题讨论】:

  • 您需要更具体一点,您可以发布两个 Java 程序的部分或全部吗?然后告诉我们你想在哪里调用其他 Java 程序
  • execute 是什么意思?您是否希望程序像从命令行启动一样在自己的 JVM 中启动?您是否只想从自己的程序中执行部分代码?您想让程序在当前程序的 JVM 中作为单独的进程运行吗?
  • @JohnB 是的,我希望程序像从命令行启动一样启动。

标签: java


【解决方案1】:

这个问题并不清楚,但我会假设 其他 Java 程序是一个命令行程序。

如果是这种情况,您将使用Runtime.exec()

如果您想查看该程序的输出,这并不是那么简单。 以下是您如何将Runtime.exec() 与任何外部程序一起使用,而不仅仅是 Java 程序。

首先你需要一种非阻塞的方式来读取Standard.outStandard.err

private class ProcessResultReader extends Thread
{
    final InputStream is;
    final String type;
    final StringBuilder sb;

    ProcessResultReader(@Nonnull final InputStream is, @Nonnull String type)
    {
        this.is = is;
        this.type = type;
        this.sb = new StringBuilder();
    }

    public void run()
    {
        try
        {
            final InputStreamReader isr = new InputStreamReader(is);
            final BufferedReader br = new BufferedReader(isr);
            String line = null;
            while ((line = br.readLine()) != null)
            {
                this.sb.append(line).append("\n");
            }
        }
        catch (final IOException ioe)
        {
            System.err.println(ioe.getMessage());
            throw new RuntimeException(ioe);
        }
    }

    @Override
    public String toString()
    {
        return this.sb.toString();
    }
}

然后你需要将这个类绑定到各自的InputStreamOutputStreamobjects。

    try
    {
        final Process p = Runtime.getRuntime().exec(String.format("cmd /c %s", query));
        final ProcessResultReader stderr = new ProcessResultReader(p.getErrorStream(), "STDERR");
        final ProcessResultReader stdout = new ProcessResultReader(p.getInputStream(), "STDOUT");
        stderr.start();
        stdout.start();
        final int exitValue = p.waitFor();
        if (exitValue == 0)
        {
            System.out.print(stdout.toString());
        }
        else
        {
            System.err.print(stderr.toString());
        }
    }
    catch (final IOException e)
    {
        throw new RuntimeException(e);
    }
    catch (final InterruptedException e)
    {
        throw new RuntimeException(e);
    }

这几乎是我在需要 Runtime.exec() Java 中的任何内容时使用的样板。

更高级的方法是使用FutureTaskCallable 或至少Runnable,而不是直接扩展Thread,这不是最佳做法。

注意:

@Nonnull 注释在 JSR305 库中。如果您正在使用 Maven,而您不是在使用 Maven,只需将此依赖项添加到您的 pom.xml

<dependency>
  <groupId>com.google.code.findbugs</groupId>
  <artifactId>jsr305</artifactId>
  <version>1.3.9</version>
</dependency>

【讨论】:

    【解决方案2】:
    • 调用其他程序的main 方法(或其他程序中的任何入口点)

    • 或使用ProcessBuilder

    【讨论】:

    • +1 第二个程序是Java程序,发帖人的描述显示SecondProgramClass.main(...)没有理由不能被程序调用。
    • 调用其他程序的main方法很可能效率更高,因为这样就不需要创建新进程,这相对昂贵。我想这两个应用程序之间可能存在冲突问题,例如它们是否具有相同名称的类。
    【解决方案3】:

    如果其他java程序是可执行程序,你可以使用这样的代码:

        try 
        { 
        Runtime.getRuntime().exec("C:\\my.exe"); 
        }
    catch(IOException ex) 
        { } 
    

    【讨论】:

    • 我更喜欢ProcessBuilder 而不是Runtime.exec,因为它的API 更容易使用
    • -1 对一个问得不好的问题的回答很差(无论是在过程中还是在执行中)。孩子们,不要在家里尝试这个(如果你这样做了,请付出更多的努力来编写它)!
    • 这是关于这个问题的最过时(和不正确)的答案!不要遵循这个答案!在下面查看当前的惯用方法!
    猜你喜欢
    • 1970-01-01
    • 2013-02-19
    • 1970-01-01
    • 1970-01-01
    • 2012-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多