调用shell命令后,我的Java程序挂起

时间:2012-05-03 10:38:12

标签: java shell

我已经编写了一个小程序来启动Hive Server。启动Hive Server的命令在shell文件中。当我调用shell文件启动Hive Server时,它倾向于启动它并获得挂起。程序中有问题吗?

代码:

            try
        {
            String cmd = "/home/hadoop/sqoop-1.3.0-cdh3u1/bin/StartServer.sh"; // this is the command to execute in the Unix shell

            // create a process for the shell
            ProcessBuilder pb = new ProcessBuilder("bash", "-c", cmd);
            pb.redirectErrorStream(true); // use this to capture messages sent to stderr
            Process shell = pb.start();
            InputStream shellIn = shell.getInputStream(); // this captures the output from the command
            // wait for the shell to finish and get the return code
            // at this point you can process the output issued by the command

            // for instance, this reads the output and writes it to System.out:
            int c;
            while ((c = shellIn.read()) != -1) 
            {
                System.out.write(c);
            }

            // close the stream
            shellIn.close();
        }
        catch(Exception e)
        {
            e.printStackTrace();
            e.printStackTrace(pw);
            pw.flush();
            System.exit(1);
        }

请让我知道这一点。我在节目中错过了什么?

感谢。

2 个答案:

答案 0 :(得分:2)

看起来你的程序正在做你告诉它的事情。

前几行确实应该启动Hive服务器。之后的行,从服务器进程的标准输出读取,并将每个字符回显到Java进程的控制台。只要Hive服务器的输出流存在,您的Java进程就会处于循环中(进行阻塞I / O调用)。

也就是说,只要Hive服务器正在运行,您的Java进程将处于循环中,回显输出。

这是你想要的吗?如果是这样,那么它显然不会退出。如果没有,则根本没有理由从服务器的输入流中读取,并且Java程序在启动服务器进程后可以退出。或者,如果您想监听输出在Java进程中执行其他操作,则需要use multiple threads才能同时执行两项操作。

答案 1 :(得分:1)

据我所知,您正在启动服务器,即启动但不会很快终止的应用程序。它仍然在运行。这意味着此应用程序(服务器)的STDOUT未关闭(除非您要杀死服务器)。

方法shellIn.read()正在阻止。它从输入流中读取下一个字节,并在读取字节或关闭流时返回。

因此,在您的情况下,流永远不会关闭,因此您的程序卡住了:它正在等待输入(并且可能正在读取它)。

要解决此问题,您需要单独的线程:在java或OS中。您可以从单独的java线程或撰写命令行运行服务器以在后台运行服务器(例如使用尾随&)。