Running PHP Apps on GlassFish

For the upcoming semester, I want to run a learning management system into which I can integrate an experimental feature for evaluating student programs. It needs to be open source so that I can modify it. I was first going to go with Sakai, which is based on Java, but just about everyone else is going to Moodle, and there are reasons for that.

The problem is, Moodle is written in PHP, and I am not a LAMP guy. I run Java, PostgreSQL, OpenSolaris, and GlassFish. (Thanks Sun for donating the server!) What's a JPOG guy going to do?

In this blog, I show three ways of running a PHP application on GlassFish. These all work with GlassFish and Moodle.

Quercus

Quercus is an implementation of PHP in Java. An interpreted version is free and open source, and a faster version can be licensed by those who feel the need for speed (which I do not). The Quercus folks will tell you that this is a more secure and scalable way of running PHP applications, which seems entirely plausible, provided, of course, that they did a good job with the PHP implementation.

I had my doubts, but Moodle is listed as a supported application and indeed, it worked like a charm.

Installation couldn't be simpler.

Download Moodle and Quercus:

wget http://download.moodle.org/download.php/direct/stable19/moodle-weekly-19.tgz
wget http://caucho.com/download/quercus-4.0.2.war

Unzip somewhere, superimposing the Quercus and Moodle trees, so that the Moodle tree wins out with index.php.

cd /somewhere
mkdir moodle
cd moodle
unzip ~/quercus-4.0.2.war 
tar xvfz ~/moodle-1.9.7.tgz 
mv moodle/* .
rmdir moodle

Do the other things you need to do for Moodle: create a moodledata directory somewhere and make a moodle database with PostgreSQL (or, if you prefer, MySQL).

Deploy, using directory deployment. That way, you can keep making changes to the Moodle PHP files, which is the modus operandi when adding themes or plugins.

asadmin deploy /somewhere/moodle

(This is with GlassFish v3.)

Now point your browser to http://server:8080/moodle and run the Moodle setup process.

There are ominous warnings about missing xml-rpc and ssl libraries, but they haven't caused me any problems yet. Overall, this is very impressive and the simplest way of getting going for a non-PHP person.

PHP/Java Bridge

The PHP/Java Bridge connects a JVM and a native PHP implementation. I tried this on Ubuntu Linux where I needed to install php5-common, php5-cli, php5-cgi, and php-pear. (Don't install php5—it shleps with it all of Apache, and the point of all this is not to install Apache.)

The installation procedure is similar. Download the latest PHP/Java Bridge binary from here. Download Moodle. Extract them into the same directory. Then you need to edit WEB/web-inf.xml and change the php_include_java parameter from the default On to Off, like this:

<init-param>
   <param-name>php_include_java</param-name>
   <param-value>Off</param-value>
</init-param>

(Thanks to Peter from the project mailing list for this tip!)

Again, run

asadmin deploy /somewhere/moodle

and point your browser to http://server:8080/moodle.

The advantage of using the bridge is that you are using genuine PHP, so there isn't any potential incompatibility issue. (The Quercus people will tell you that this is also a disadvantage—PHP is more prone to attacks than Java, and it is not all that fast.)

It is worth noting that both with Quercus and the PHP/Java Bridge, you can make Java calls from PHP code, which can come in handy if you want to extend the capabilities of your PHP program without the indignity of having to code in PHP.

jFastCGI

jFastCGI is another mechanism for making a servlet container serve PHP pages. I am guessing that it has a bit less overhead than the PHP/Java Bridge. It didn't work out of the box for me on Linux, but one of the developers, Barry van Someren, sent me a patch that worked. Here is how you can build it yourself.

Check out the latest code from SourceForge and build it. Curiously, the Ant script assumes that you have the servlet library on the global class path:

cd ~
svn co https://jfastcgi.svn.sourceforge.net/svnroot/jfastcgi/trunk jfastcgi 
export CLASSPATH=.:/path/to/glassfishv3/glassfish/modules/javax.servlet.jar
cd jfastcgi/ant
ant

Now unzip Moodle somewhere and turn it into a web application like this:

mkdir -p /somewhere/moodle/WEB-INF/lib
cp ../dist/jFastCGI.jar /somewhere/moodle/WEB-INF/lib
cp ../lib/*.jar /somewhere/moodle/WEB-INF/lib

Make a file /somewhere/moodle/WEB-INF/web.xml with the contents

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <servlet>
     <servlet-name>FastCGI</servlet-name>
     <servlet-class>net.jr.fastcgi.FastCGIServlet</servlet-class>
     <init-param>
        <param-name>server-address</param-name>
        <param-value>localhost:6667</param-value>
     </init-param>
  </servlet>
  <servlet-mapping>
     <servlet-name>FastCGI</servlet-name> 
      <url-pattern>*.php</url-pattern>
  </servlet-mapping>
</web-app>

Run

php-cgi -b6667

(The docs recommend port 6666, but for some reason, that is taken on my machine.)

Deploy the directory to GlassFish, and it works.

Summary

I am a Java guy and build my applications with JSF and JPA. But there is no denying that there is a lot of PHP code out there that does useful stuff. If you need to host a PHP app with your Java apps, you don't have to drink the LAMP Kool-Aid. There are multiple ways of making this work with GlassFish, which gave me the courage to go with one of them and use the others as a fallback.