I am setting up PHP on my Tomcatserver using the PECL-servlet (PHP/PECL-version 5.2.5). The server now sucessfully handles real PHP-files, but i am having a problem with requests for nonexistent pages.
A request for such a page, f.ex: http://www.mydomain.com/nonexistentfile.php, causes the servlet to raise a java.io.IOException, which is never catched. Tomcat is therefore terminated.
How can i fix this? Can i catch exceptions from the servlet? Is there a way to only map existing files to the servlet?
Thanks for the reply, its seems to be working now. I did your suggested re-map in web.xml, mapping the php-files to my first self-made servlet, which basically wrapps around the phpservlet and handles raised exceptions. Is this a good way solving the problem?
It seems a little strange to me that tomcat isn't able to handle such exceptions on its own. I can see the point in terminating the server to protect it from executing in corrupt states, but it should be possible to enable custom exception-handling...
Here is my localhost.2009-12-09.log after invoking phpservlet directly with non-existent page:
(tomcat displays the 4 first lines of the stacktrace int its default errorpage before terminating)
09.des.2009 13:35:50 org.apache.catalina.core.ApplicationContext log INFO: ContextListener: contextInitialized() 09.des.2009 13:35:50 org.apache.catalina.core.ApplicationContext log INFO: SessionListener: contextInitialized() 09.des.2009 13:35:50 org.apache.catalina.core.ApplicationContext log INFO: ContextListener: attributeAdded('org.apache.catalina.Registry', 'org.apache.tomcat.util.modeler.Registry@1010058') 09.des.2009 13:35:50 org.apache.catalina.core.ApplicationContext log INFO: ContextListener: attributeAdded('org.apache.catalina.MBeanServer', 'com.sun.jmx.mbeanserver.JmxMBeanServer@bdab91') 09.des.2009 13:35:54 org.apache.catalina.core.StandardWrapperValve invoke SEVERE: Servlet.service() for servlet php threw exception java.io.IOException: at net.php.servlet.send(Native Method) at net.php.servlet.service(servlet.java:190) at net.php.servlet.service(servlet.java:214) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447) at java.lang.Thread.run(Unknown Source)
You normally declare it as <error-page>
in web.xml
.
But since you literally said, "which is never catched. Tomcat is therefore terminated", I have my doubts about the setup. Do you really not see Tomcat's default error page with a stacktrace inside? Don't you see anything in the appserver logs? How did you know about the IOException
?
At least, you could try to map a Filter
on the url-pattern
of *.php
which contains basically the following lines:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException {
try {
chain.doFilter(request, response);
} catch (IOException e) {
// Handle it.
}
}
But seeing how you described the problem, I rather think that the PHP servlet or the webcontainer failed to display the error page, because the response is already committed, but in this case you should have seen a fairly self-explaining IllegalStateException: Response already committed
error in the appserver logs.