首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >调用外部程序异步运行的Java程序?

调用外部程序异步运行的Java程序?
EN

Stack Overflow用户
提问于 2013-11-07 11:53:58
回答 2查看 2.1K关注 0票数 3

全,

我最初有一个名为SQLLoader (Oracles数据上传工具)的shell脚本。

问题是SQLLoader接受一个纯文本密码作为输入,所以我决定构建一个SQLLoader应用程序,在内部调用SQLLoader,将一个解密密码传递到命令字符串中。

例如:

sqlldr用户/pass@DBServer控件=../sqlloader.ctl log=sqlloader.log data=mydata.csv

因此,在我的java包装器中,它变成了shell脚本中的

代码语言:javascript
运行
复制
java -jar sqlloader.jar sqlloader.ctl mydata.csv

然而,当SQLLoader抱怨没有加载文件时,出现了一个新的问题。经过一些抓取之后,发现shell脚本中的后续命令似乎正在执行,而我的java应用程序仍在运行。因此它的行为是异步的。

下一个命令是移动输入文件sqlloader正在使用,然后才能有机会使用它。因此,我在20秒内放置了一个睡眠命令,以便给我的java应用程序运行时间。

代码语言:javascript
运行
复制
java -jar sqlloader.jar sqlloader.ctl mydata.csv
echo $?
sleep 20
if [ $? -ne 0 ]
    then
        echo "SQLLoader failed during execution, please check the log : " 
        mv mydata.csv

else
    echo "SQLLoader successfully processed file : "
    mv mydata.csv
fi

有人知道为什么unix会这样做吗,Java会以不同的用户/线程的形式执行我的SQLLoader吗?

这是我的java代码:

代码语言:javascript
运行
复制
    Runtime Rt;
Process Prc;
    Prc = Rt.exec("sqlldr user/decryptedpass@DBServer control=../sqlloader.ctl log=sqlloader.log data=mydata.csv);
system.exit(0);

我检查了Runtime类是否是异步的,但是找不到任何东西

http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html

有什么理论或建议吗?

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-11-10 03:17:37

是。如果再次查看Runtime.exec,它确实指定它将在指定的环境中启动一个新进程(例如,独立于当前的“环境”或异步地使用它)。您应该使用ProcessBuilder创建一个流程,然后在调用System.exit之前先完成该进程,这当然不是强制性的。就像这样

代码语言:javascript
运行
复制
public static void main(String[] args) {
    // String command = "/usr/bin/sleep 5";
    List<String> command = new ArrayList<String>();
    command.add("c:/cygwin/bin/sleep");
    command.add("5");
    ProcessBuilder pb = new ProcessBuilder(command);
    BufferedReader is = null;
    try {
        System.out.println("Starting command " + command);
        Process p = pb.start();

        int ret = p.waitFor();
        is = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line;
        while ((line = is.readLine()) != null) {
            System.out.println(line);
        }
        if (ret == 0) {
            System.out.println("Command has completed.");
            System.exit(ret);
        } else {
            System.out.println("Command completed with return code " + ret);
            System.exit(ret);
        }
    } catch (Exception e) {
        System.out.println("Caught Exception " + e.getMessage()
                + " running command " + command);
        e.printStackTrace();
    } finally {
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
            }
        }
    }
    System.out.println("COMMAND FAILED");
    System.exit(1);
}
票数 3
EN

Stack Overflow用户

发布于 2013-11-07 12:05:18

您需要等待进程完成,还应该从正在启动的进程中读取所有输出(stdout、 stderr)。

如果在exec()之后调用exit(),Java将立即执行- exit。

下面是一篇解释Runtime.exec缺陷的文章:http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=4 (也考虑其他页面)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19835244

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档