Skip to main content

PHP on Grizzly with JSR223

Posted by survivant on February 3, 2009 at 4:38 PM PST

This time I will show you how to run PHP applications on GrizzlyWebServer using 100% pure java solutions.
I used Caucho Quercus to handle the PHP and GrizzlyWebServer as my WebServer.

The first implementation that I did was really simple. I used the demo that I did for JSPOnGrizzly and replace the servlet
by Quercus. You can see what the code looks like :

public void launch(){
		GrizzlyWebServer ws = new GrizzlyWebServer(80);
		try {
            ServletAdapter sa = new ServletAdapter();
            Servlet servlet = (Servlet)ClassLoaderUtil.load("com.caucho.quercus.servlet.QuercusServlet");
    	      ws.addGrizzlyAdapter(sa, new String[]{});
        } catch (Exception e){
            s_logger.error("Error Launching GrizzlyWebServer",e);

I was expecting that would work within a few seconds, but I got few exceptions when I tried to run the application.

2009-02-02 17:28:03 com.sun.grizzly.http.servlet.ServletAdapter service
GRAVE: service exception:
java.lang.UnsupportedOperationException: Not supported yet.
	at com.sun.grizzly.http.servlet.HttpServletRequestImpl.getRealPath(
	at com.caucho.quercus.servlet.QuercusServletImpl.getPath(
	at com.caucho.quercus.servlet.QuercusServletImpl.service(
	at com.caucho.quercus.servlet.QuercusServlet.service(
	at javax.servlet.http.HttpServlet.service(
	at com.sun.grizzly.http.servlet.FilterChainImpl.doFilter(
	at com.sun.grizzly.http.servlet.FilterChainImpl.invokeFilterChain(
	at com.sun.grizzly.http.servlet.ServletAdapter.service(
	at com.sun.grizzly.tcp.http11.GrizzlyAdapter.service(
	at com.sun.grizzly.http.DefaultProcessorTask.invokeAdapter(
	at com.sun.grizzly.http.DefaultProcessorTask.doProcess(
	at com.sun.grizzly.http.DefaultProcessorTask.process(
	at com.sun.grizzly.http.DefaultProtocolFilter.execute(
	at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(
	at com.sun.grizzly.DefaultProtocolChain.execute(
	at com.sun.grizzly.DefaultProtocolChain.execute(
	at com.sun.grizzly.http.HttpProtocolChain.execute(
	at com.sun.grizzly.ProtocolChainContextTask.doCall(
	at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
	at Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$ Source)
	at Source)

Grizzly doesn't completely implement HttpServletRequest (yet). The easy way doesn't always work the first time.
BUT there is still a way to do PHP with GrizzlyWebServer. An alternative is to use Quercus's JSR223 implementation.

We will have to replace QuercusServlet by my Servlet that uses Quercus libraries.

Servlet servlet = (Servlet)ClassLoaderUtil.load("ca.sebastiendionne.grizzly.servlet.QuercusHttpServlet");


package ca.sebastiendionne.grizzly.servlet;

import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;

import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class QuercusHttpServlet extends HttpServlet {
	private static final long serialVersionUID = -1649882114668014299L;
	private static final Logger s_logger = LoggerFactory.getLogger(QuercusHttpServlet.class);
	private static ScriptEngineManager scriptManager = new ScriptEngineManager();
	private static ScriptEngine phpEngine = scriptManager.getEngineByExtension("php");
	protected void doPut (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		ScriptContext context = phpEngine.getContext();

		try {
			context.setWriter(new StringWriter());
			//put the parameters and attributes into the engine
			Enumeration attributes = req.getAttributeNames();
			while (attributes.hasMoreElements()) {
				String key = (String) attributes.nextElement();
				// put the parameters and attributes into the engine
				phpEngine.put(key, req.getAttribute(key));
			Map<String, Object> params = req.getParameterMap();
			for (Iterator iterator = params.keySet().iterator(); iterator.hasNext();) {
				String key = (String);
				// put the parameters and attributes into the engine
				phpEngine.put(key, params.get(key));
			// need a better way to find the requested file
			String uri = req.getRequestURI();
				uri = uri.substring(1);
			phpEngine.eval(new FileReader(uri), context);
			StringWriter writer = (StringWriter) context.getWriter();
		} catch (Exception e) {
			s_logger.error("Error Evaluating PHP",e);
	protected void doGet (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		doPut(req, res);


We need a php page to test our application.


// Show all information, defaults to INFO_ALL


The output won't be the same as the native php. Here the output from Quercus implementation.

PHP Version => 5.2.0
System => Windows XP 5.1 x86
Build Date => 20070628T2777
Configure Command => n/a
Server API => CGI
Virtual Directory Support => disabled
Configuration File (php.ini) Path => WEB-INF/php.ini
PHP API => 20031224
PHP Extension => 20041030
Debug Build => no
Thread Safety => enabled
Registered PHP Streams => php, file, http, https
Variable => Value

You can download the source code for this project here.

Related Topics >>


new String[]{} is ugly, I do prefer new String[0]. However this great blog makes me want to write PHP webapps just to try this, what a performance !

OK I've fixed the Unsupported exception :-)