我已经编写了一个小程序来启动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);
}
请让我知道这一点。我在节目中错过了什么?
感谢。
答案 0 :(得分:2)
看起来你的程序正在做你告诉它的事情。
前几行确实应该启动Hive服务器。之后的行,从服务器进程的标准输出读取,并将每个字符回显到Java进程的控制台。只要Hive服务器的输出流存在,您的Java进程就会处于循环中(进行阻塞I / O调用)。
也就是说,只要Hive服务器正在运行,您的Java进程将处于循环中,回显输出。
这是你想要的吗?如果是这样,那么它显然不会能退出。如果没有,则根本没有理由从服务器的输入流中读取,并且Java程序在启动服务器进程后可以退出。或者,如果您想监听输出和在Java进程中执行其他操作,则需要use multiple threads才能同时执行两项操作。
答案 1 :(得分:1)
据我所知,您正在启动服务器,即启动但不会很快终止的应用程序。它仍然在运行。这意味着此应用程序(服务器)的STDOUT未关闭(除非您要杀死服务器)。
方法shellIn.read()
正在阻止。它从输入流中读取下一个字节,并在读取字节或关闭流时返回。
因此,在您的情况下,流永远不会关闭,因此您的程序卡住了:它正在等待输入(并且可能正在读取它)。
要解决此问题,您需要单独的线程:在java或OS中。您可以从单独的java线程或撰写命令行运行服务器以在后台运行服务器(例如使用尾随&)。