等待一系列脚本中的单个Shell脚本在继续之前运行完成(Java,MySQL,JUnit)

时间:2012-04-13 13:35:06

标签: java mysql shell junit

我正在开发一个包含Process和Runtime的Java程序,用于运行多个shell脚本以进行自动化测试。除了其中一个脚本之外的所有脚本运行正常,这会导致跟随它的脚本调用出现问题。例如:

process = runtime.exec("A.sh");
process = runtime.exec("B.sh");
process = runtime.exec("C.sh");

A.sh运行良好,只需几秒钟即可运行。但是,运行起来需要几分钟的时间,我认为这会导致运行C.sh的问题,因为它们都与同一个MySQL表进行交互,重叠导致通信链路失败。

如果没有不必要的信息,我的问题是,如何确保运行shell脚本已经运行完成/终止,然后再转到下一个exec()调用? < / p>

我尝试了什么:

process.waitFor()

这不起作用,我认为它不会等到脚本完全完成

process.wait(long time_period)

这不起作用,因为它导致当前线程等待,导致剩余的shell脚本调用被跳过,下一个测试用例提前开始。

我调用的shell脚本导致问题是而不是一个简单的脚本,但我自己并没有写它,也不了解它在幕后的作用。我所知道的唯一相关信息是它直接连接到有问题的MySQL数据库,而我的程序使用java.sql。*来(我相信)远程连接(尽管它是远程机器上的本地数据库)。

编辑:

在提出建议之后,我查看了Apache Commons Exec并尝试了一种新策略,但未成功。

ExecuteWatchdog watchdog = new ExecuteWatchdog(300000); //For five minutes
CommandLine cmdline = CommandLine.parse("./directory/shell.sh");
DefaultExecutor executor = setExitValue(0);
executor.setWatchdog(watchdog);
int exitVal = executor.execute(cmdLine);
//A line to log the exit val in another file

我的日志没有暗示shell脚本实际上是运行的,因为记录的语句“shell.sh begin”和“test 2 starts”之间的时间基本上是同一时刻,这意味着~2分钟的过程shell.sh运行永远不会发生。我哪里出错了?

1 个答案:

答案 0 :(得分:2)

我使用Apache Commons Exec。具有同步和异步执行支持。可以设置执行超时。

他们的教程页面中的第一段:

  

此时我们可以放心地假设你想开始一些   您的Java应用程序中的子进程并且您花了一些时间   在这里做得恰到好处。你看看Commons Exec并想“哇 -   调用Runtime.exec()很容易,Apache人员正在浪费他们的   我的时间用大量的代码“。好吧,我们学到了很多东西   我的情况不止一次)使用普通的Runtime.exec()可以是一个   痛苦的经历。因此,请您深入研究   commons-exec并以简单的方式看看艰苦的课程......

高级用法示例(缺少某些代码,如BusinessException和“StreamUtil.closeQuietly”,但可以轻松替换):

    ExecuteWatchdog watchdog = new ExecuteWatchdog(EXECUTION_TIMEOUT_IN_MS);
    DefaultExecutor executor = new DefaultExecutor();

    executor.setWatchdog(watchdog);
    executor.setExitValue(0);

    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    ByteArrayOutputStream errorStream = new ByteArrayOutputStream();

    executor.setStreamHandler(new PumpStreamHandler(outputStream, errorStream));

    try {
        log.info(commandLine.toString());

        int exitCode = executor.execute(commandLine, (Map<?, ?>) null);

        if (exitCode != 0)
            throw new BusinessException("Process exited with non-zero exit code.");

        return outputStream.toString();
    } catch (ExecuteException e) {
        String errorStreamStr = null;

        if (errorStream.size() != 0)
            errorStreamStr = errorStream.toString();

        StringBuilder errorMessageBuilder = new StringBuilder();

        errorMessageBuilder.append("main.error").append(":\n").append(
                e.getMessage()).append("\n\n");

        if (errorStreamStr != null) {
            errorMessageBuilder.append("additional.error").append(":\n").append(errorStreamStr).append("\n\n");
        }

        errorMessageBuilder.append("command.line").append(":\n").append(commandLine.toString());

        if (log.isDebugEnabled())
            log.debug(errorMessageBuilder.toString());

        throw new BusinessException(errorMessageBuilder.toString());
    } catch (IOException e) {
        throw new IllegalStateException(e);
    } finally {
        StreamUtil.closeQuietly(outputStream, errorStream);
    }