You have a Glassfish server.
You are a Drupal developer.
You want to run Drupal in Glassfish. More importantly, you want to have it use clean urls because without that capability, all of your urls look like this: /index.php?foo/bar/baz. Which sucks, of course.
Let's set aside for the moment the desirability of running PHP in a Java application container for the moment1, and jump right to the meat of this geeky post. Here's how I got some of the clean url functionality you'd normally get from Apache's mod_rewrite, or using either mod_rewrite or Lua in lighttpd.
I'm assuming you've already got Glassfish installed, so from there:
- Get a copy of Quercus, Caucho's Java implementation of PHP 5. I downloaded the version 3.2.1 .war file.
- Unzip the .war:2
jar -xvf quercus-3.2.1.war
- Get a copy of Url Rewrite Filter. I used version 3.2.0 (beta), but 2.6 should work also.
> cd quercus-3.2.1 > wget http://urlrewritefilter.googlecode.com/files/urlrewritefilter-3.2.0-src.zip > unzip urlrewritefilter-3.2.0-src.zip
- Get Drupal. I used the latest 6.x version.:
> cd ../ > wget http://ftp.drupal.org/files/projects/drupal-6.10.tar.gz > tar zxvf drupal-6.10.tar.gz Copy Drupal files to the quercus docroot > cp -r drupal-6.10/* quercus-3.2.1/
-
Configure Url Rewrite Filter. This is where it gets a little sketchy. Drupal comes prepackaged with a
.htaccessfile, which sets up the mod_rewrite rules for Apache:
# Rewrite current-style URLs of the form 'index.php?q=x'. RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
Unfortunately, Url Rewrite Filter doesn't support the REQUEST_FILENAME directive (yet). So I've put in some hacks to at least get clean urls working. I don't pretend that this is production-ready, but it gets it working for basic testing. If anyone has input, I'd welcome it. Anyway, in the WEB-INF/web.xml file, the following directives need to be added:
<filter> <filter-name>UrlRewriteFilter</filter-name> <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class> </filter> <filter-mapping> <filter-name>UrlRewriteFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
This should go before the<servlet></servlet>section.Next, create
WEB-INF/urlrewrite.xml:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 2.6//EN" "http://tuckey.org/res/dtds/urlrewrite2.6.dtd"> <urlrewrite> <rule> <note> Prevent rewriting of specific files. Definitely not the best way to do this. </note> <from>^/(.*)(css|js|png|jpg|gif)$</from> <to>/$1$2</to> </rule> <rule> <note> Prevent rewriting of files in the files directory </note> <from>^/(.*)/files/(.*)$</from> <to>/$1/files/$2</to> </rule> <rule> <note> Do the Drupaly stuff </note> <from>^/(.*)$</from> <to>/index.php?q=$1</to> </rule> </urlrewrite>
- Re-zip your directory back into a .war file to deploy onto the app server:
>jar -cvf quercus-3.2.1.war quercus-3.2.1/*
- Deploy to Glassfish through the admin console, or from the auto-deploy directory. Note that you should set your context-root to / to run Drupal at the root of the app server.
- Oh yeah, you'll probably want to connect to a database too, right? In the admin panel, go to Resources > JDBC > Connection Pools and create a new Connection Pool. Let's call it
mysqlpool.Set Datasource Classname to
com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource.Plug in the following Additional Parameters for your Drupal DB:
password user databaseName portNumber serverName
That should be about it.
2: I expect that most Drupal developers aren't using IDEs like Eclipse or NetBeans, so I'm just using command-line tools here.



Comments
This rewrite is inadequate. I've been getting incredibly frustrated finding a way to make clean URLs work with Drupal on Quercus for this reason.
Specifically URLs like:
http://localhost:8080/batch?op=start&id=4
http://localhost:8080/admin_menu/flush-cache?destination=admin
fail miserably. There has to be a better way to emulate mod_rewrite in a servlet container. I just can't find it for the life of me. I tried updating the regex for the latter case to:
<rule>
<note>
Do the Drupal stuff
</note>
<from>^/(.*)|(.*)(\?(.*))$</from>
<to>/index.php?q=$1&$4</to>
</rule>
This looks too ugly to be very right though. I'm no reg-expert.
I'm almost to the point of getting a separate hosting account just to use Apache for this and proxy calls to my Java host. That not only sounds terribly annoying, but probably won't help with .htaccess rules like:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
as these require access to the file system.
Has anyone found a better way?
Yeah, I've found after playing with Quercus a bit more that it's not quite ready for production, perhaps maybe for very specific use cases.
For example, it doesn't support LDAP and some classess in SPL, which make it unusable for my applications.
I've also found it to be not quite as fast as the lighttpd+APC combo we run in production. At this point, I'd probably only use it for things that were heavily integrated with java code.
I am posting this quite late.. But still it may be of use to someone .
Well i was trying to deploy my drupal site on glassfish and faced with the clean url problem. This post really helped me. But as Todd, in the above post, has mentioned we need to mention these conditions
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
So this is wat i have done
- Removed the previous 2 rules
- Replaced the 3rd rule with
Do the Drupaly stuff
^/(.*)/files/(.*)$
^/(.*)(css|js|png|jpg|gif)$
^/(.*)$
/index.php?q=$1
It works great !!
Eww... Sorry for the above post.. The tags just disappeared...
Replace the 3rd rule with:
<rule>
<note>
Do the Drupaly stuff
</note>
<condition type="request-uri" operator="notequal">^/(.*)/files/(.*)$</condition>
<condition type="request-uri" operator="notequal">^/(.*)(css|js|png|jpg|gif)$</condition>
<from>^/(.*)$</from>
<to>/index.php?q=$1</to>
</rule>
Post new comment