简体   繁体   English

Mac OSX上的Java进程似乎在通过Web服务器调用时“挂起”,但可以从命令行调用

[英]Java process on Mac OSX seems to “hang” when invoked via webserver, but OK from the commandline

I have a very strange situation where a Java process seems to hang when called via Apache/PHP, but OK when invoked from the command line. 我有一个非常奇怪的情况,当通过Apache / PHP调用时,Java进程似乎挂起,但是从命令行调用时可以正常。 I spent hours debugging this, no avail. 我花了几个小时调试这个,没有用。 Any and all thoughts welcome! 欢迎任何和所有的想法!

Situation: I have a .class file (without the original Java code) that reads an input file, processes the read information, and writes a report on stdout. 情况:我有一个.class文件(没有原始Java代码),它读取输入文件,处理读取信息,并在stdout上写入报告。 The Java code doesn't read stdin, and only writes stdout. Java代码不读取stdin,只写stdout。 I wrapped this in a tiny Perl script that basically just execs "java -cp /path/to/classfile MyJavaProgram /path/to/inputfile/to/process". 我把它包装在一个很小的Perl脚本中,基本上只执行“java -cp / path / to / classfile MyJavaProgram / path / to / inputfile / to / process”。 That way I can invoke it from the command line for testing, this works like a charm. 这样我就可以从命令行调用它进行测试,这就像一个魅力。 Next, I try to invoke this from PHP using popen(), and there Java just hangs. 接下来,我尝试使用popen()从PHP调用它,并且Java只是挂起。 I see the Perl process in the ps list, and Java; 我在ps列表中看到了Perl进程和Java; but the Java process waits forever. 但Java进程永远等待。 Once I kill it, the webserver page continues loading (but of course without the expected output that the Java process would generate). 一旦我杀了它,webserver页面就会继续加载(但当然没有Java进程会产生的预期输出)。

What I tried so far: 到目前为止我尝试了什么:

  • Wrapping the Java process in a shell script, same behaviour. 在shell脚本中包装Java进程,行为相同。 Java just hangs. Java只是挂起。
  • Running it from PHP with popen() without a wrapper, same behaviour. 使用popen()从PHP运行它而不使用包装器,行为相同。
  • Starting it from PHP with system() or passthru(), same behaviour. 从PHP开始使用system()或passthru(),行为相同。
  • In the Perl wrapper, reopening STDIN for /dev/null (so that reading stdin immediately returns EOF), same behaviour. 在Perl包装器中,为/ dev / null重新打开STDIN(以便读取stdin立即返回EOF),行为相同。
  • In the Perl wrapper, reopening STDERR for /dev/null, same behaviour. 在Perl包装器中,为/ dev / null重新打开STDERR,行为相同。
  • In the Perl wrapper, reopening STDOUT for /dev/null. 在Perl包装器中,为/ dev / null重新打开STDOUT。 Here I would expect no output (as it gets discarded) but still the Java process just hangs. 在这里,我希望没有输出(因为它被丢弃),但Java进程仍然挂起。
  • In the Perl wrapper, reopening all 3 streams for /dev/null. 在Perl包装器中,为/ dev / null重新打开所有3个流。 Java still hangs. Java仍然悬而未决。
  • Replacing the Java invocation in the Perl wrapper with a simple "ls -l /bin". 用简单的“ls -l / bin”替换Perl包装器中的Java调用。 This works as expected; 这按预期工作; the web page gets populated with the "ls" listing. 网页上填充了“ls”列表。 So the problem isn't in PHP or Perl. 所以问题不在PHP或Perl中。
  • Starting the Java process with a "/bin/sh -c 'java .....'". 使用“/ bin / sh -c'java .....'”启动Java进程。 Same behaviour, Java hangs. 相同的行为,Java挂起。
  • In the Perl wrapper, I dump the environment variables too, to check them. 在Perl包装器中,我也转储环境变量,以检查它们。 Environment seems OK. 环境似乎没问题。
  • When the Java process is running, I look up the Perl wrapper invocation in the ps list, and copy/paste it to the command line. 当Java进程运行时,我在ps列表中查找Perl包装器调用,并将其复制/粘贴到命令行。 Works like a charm. 奇迹般有效。
  • Similarly, when the Java process is hanging, I look up the invocation in the ps list, and copy/paste it to the command line. 类似地,当Java进程挂起时,我在ps列表中查找调用,并将其复制/粘贴到命令行。 Works like a charm. 奇迹般有效。
  • I also verified that the the input file is readable when invoked from the web server. 我还验证了从Web服务器调用时输入文件是否可读。 All above tests with the command line were run using the same user ID as the Apache user. 使用与Apache用户相同的用户ID运行命令行的所有上述测试。

Unfortunately I can't replace the Java code with something that's under my control. 不幸的是,我不能用我控制的东西替换Java代码。 I only have the .class file to work with. 我只有.class文件可以使用。 What I haven't tried yet is to run this under Linux, so this still might be an OSX specific issue (which would surprise me). 我还没有尝试过在Linux下运行它,所以这仍然可能是OSX特定的问题(这会让我感到惊讶)。

What the hell is going on here? 这到底是怎么回事? Any and all "wild" ideas appreciated.. thanks! 任何和所有“狂野”的想法都赞赏...谢谢!

Check ALL environment from apache AND from cmd line, including the paths, UIDs etc. 从apache和cmd行检查所有环境,包括路径,UID等。

Also check what the java process does when hanging (use truss/tusc/strace -f java xxxxxxxxxxx 2>/tmp/trace.$$ ) when wrapping it from both places (apache and cmdline), then compare the results. 还要检查挂起时java进程执行的操作(使用truss / tusc / strace -f java xxxxxxxxxxx 2> / tmp / trace。$$)从两个位置(apache和cmdline)包装它,然后比较结果。

Also, when wrapping from perl, set autoflush to 1 for stdin, stdout, stderr before exec-ing java. 另外,当从perl包装时,在执行java之前将stofout,stdout,stderr的autoflush设置为1。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM