Showing posts with label Quercus. Show all posts
Showing posts with label Quercus. Show all posts

12 May 2013

Quercus on Google App Engine - 2.0


Quercus on Google App Engine - 2.0


The following article originally appeared on JavaAdvent 2012.

It's been a 3.5 years ago to this day since I last wrote about running Quercus on Google App Engine (GAE). The article detailed a crazy experiment to get a PHP application, Wordpress, running on GAE. I still remember it being a painful experience because of number of changes I had to make to Wordpress to get it working. It was all due to the GAE Java environment being so drastically different from what Java developers were used to. It was heavily sandboxed and had no SQL support. You couldn't launch new Threads. You couldn't write to the file system. But those were the tradeoffs you had to live with if you wanted to deploy your application to the all-wonderful Cloud.
Fast-forward to 2012 and GAE has come a long way. GAE now allows you to spawn new Threads (currently in beta). You still cannot write to the file system, but for all it's worth there is a new GAE Files API that gives you file-like concepts. And you can run your very own MySQL instances on Google's infrastructure (albeit Google's customized version of MySQL).
What hasn't changed over the years is that you're still expected to hit major roadblocks as you migrate your existing web applications over to GAE. And you'll have to make heavy modifications to your application to 1) make it work and 2) be performant on GAE.
So this is where Quercus comes into the picture. At Caucho, we spent a lot of time getting Quercus to work seamlessly with GAE. Our goal was to abstract the GAE details away so that developers don't have to worry about the fact that the application is running on GAE. Things just work transparently behind the scenes for PHP applications. For example,
  • PHP file_*() functions work just like they do before (including writing to files!)
  • PHP mysql_*() functions and PDO work just like they do before

What this means is that we can run existing PHP applications on GAE without any modifications! Say hello to "Wordpress on Google App Engine” 2.0! But first, let's start with some formalities.

I. Introduction to Quercus

Quercus is Caucho's 100% Java implementation of the PHP language runtime and libraries. Currently, Quercus supports PHP 5.3 language features and contains a multitude of libraries developed in-house including but not limited to apc, bcmath, curl, date, dom, filter, gettext, json, mail, mbstring, mcrypt, pdf, pdo, postgres, reflection, regexp, spl, zip, and zlib.
Quercus can run as a servlet or on the command line. For our case, we're interested in running it as a servlet:
  1. Download Resin Java Application Server and it'll come with Quercus enabled by default and ready to go.
  2. Uncompress the archive and start up Resin with:
        ./bin/resin.sh console
  3. Then create a webapps/ROOT/test.php file with the following contents:
    <?php
    
      phpinfo();
    
    ?>
  4. Browse to http://localhost:8080/test.php and you should see the following:
Congrats! You have PHP running natively on a Java server.

II. Running Quercus on Tomcat

Okay, so you want to use Tomcat instead of Resin? No worries.
  1. Copy lib/resin.jar from the Resin download above to Tomcat's webapps/ROOT/WEB-INF/lib directory.
  2. Add QuercusServlet to Tomcat's webapps/ROOT/WEB-INF/web.xml file:
    <web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
      <servlet>
        <servlet-name>Quercus Servlet</servlet-name>
        <servlet-class>com.caucho.quercus.servlet.GoogleQuercusServlet</servlet-class>
        <init-param>
          <param-name>ini-file</param-name>
          <param-value>WEB-INF/php.ini</param-value>
        </init-param>
      </servlet>
    
      <servlet-mapping>
        <servlet-name>Quercus Servlet</servlet-name>
        <url-pattern>*.php</url-pattern>
      </servlet-mapping>
    
      <welcome-file-list>
        <welcome-file>index.php</welcome-file>
      </welcome-file-list>
    </web-app>