Calling perl script from Java servlet
I'm trying to call a perl script from a java servlet on tomcat 7. I开发者_运维知识库 have set up the context.xml and the web.xml so I can run a .pl file by going to http://localhost:8080/test/cgi-bin/test.pl and I can also run perl from directly within java like so:
String[] cmdArr = new String[]{"perl", "-e", "print \"Content-type: text/html\n\n\";$now = localtime();print \"<h1>It is $now</h1>\";"};
if (cmdArr != null) {
Process p = null;
Runtime rt = Runtime.getRuntime();
try {
p = rt.exec(cmdArr); // throws IOException
returnValue = p.waitFor(); // throws InterruptedException
}
catch (IOException xIo) {
throw new RuntimeException("Error executing command.",xIo);
}
catch (InterruptedException xInterrupted) {
throw new RuntimeException("Command execution interrupted.",xInterrupted);
}
InputStreamReader isr = new InputStreamReader(p.getInputStream());
BufferedReader stdout = null;
stdout = new BufferedReader(isr);
String line = null;
try {
while ((line = stdout.readLine()) != null) {
System.out.println(line);
}
}
catch (IOException xIo) {
throw new RuntimeException("Error reading process output", xIo);
}
}
and this works fine, but if I try and refer to a .pl script that is in my /WEB-INF/cgi folder by replacing the:
String[] cmdArr = new String[]{"perl", "-e", "print \"Content-type: text/html\n\n\";$now = localtime();print \"<h1>It is $now</h1>\";"};
with something like:
String cmdArr = "/WEB-INF/cgi/test.pl";
or
String cmdArr = "/cgi-bin/test.pl";
I keep getting this error:
java.io.IOException: Cannot run program "/WEB-INF/cgi/test.pl": error=2, No such file or directory
I'm guessing im going wrong with the file path somewhere? Any help would be really appreciated!
UPDATE:
after @hobbs comment I changed to: String[] cmdArr = new String[]{"perl", "/WEB-INF/cgi/test.pl"};
but if I add the following before the .waitFor():
BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()));
String line;
while ( (line = br.readLine()) != null){
System.out.println(line);
}
I get the print:
Can't open perl script "/WEB-INF/cgi/test.pl": No such file or directory
I guess this is back to the original problem?
Somewhat confusingly, when an exec syscall returns "No such file or directory" on a script, what it usually means is that the interpreter on the shebang line couldn't be found. e.g. if /WEB-INF/cgi-test.pl starts with #!/usr/bin/perl
then it could be that /usr/bin/perl doesn't exist. Or if the file has Windows line-endings, it could lead to the kernel looking for an interpreter named "/usr/bin/perl\x0a"
, which can't be found.
Since you've established that you can run things using a command array that starts with "perl"
, how about:
String cmdArr = new String[]{"perl", "/WEB-INF/cgi/test.pl"};
?
Your issue has to do with the context of which your servlet is being ran. You need to get the context, then navigate to your file. See here to find how to get servlet context: How to get the Servlet Context from ServletRequest in Servlet 2.5?
You will achieve your servlet context in a manner such as this:
ServletContext context = config.getServletContext();
Then just use that context like so:
String cmdArr = new String[]{"perl", context.getRealPath("/") + "WEB-INF/cgi/test.pl"};
精彩评论