Railo JARs on JBoss (or Tomcat) - Tips and Tricks

As a follow up to a previous related post, I wanted to share a couple potentially helpful tricks that I've since learned. Everything I document here has been tested with both Railo 3.0.2.004 (current stable) and Railo 3.1.0.012 (current beta), both of which can be downloaded from here, on JBoss Application Server (AS) 4.2.3.GA.

The purpose (as I see it) of a Railo JARs installation is to provide an alternative to using a full-blown Railo WAR for each of your Railo CFML applications. This allows you to define your Railo CFML servlet "globally" in JBoss/Tomcat and then use virtual hosts for multiple CFML apps. Each CFML app is then leveraging the same Railo instance, one copy of the jars and one Railo server admin (but still multiple Web contexts with unique Railo Web Admin for each Web site/context).

Also keep in mind that JBoss AS leverages Tomcat as its Web server, so just about everything here should directly translate. Here are the locations of key configuration files and directories in both JBoss 4.2 and Apache Tomcat 6:

{JBOSS_HOME}/lib/ {JBOSS_HOME}/server/default/lib/
or
{TOMCAT_HOME}/lib/

{JBOSS_HOME}/server/default/deploy/jboss-web.deployer/conf/web.xml
or
{TOMCAT_HOME}/conf/web.xml

{JBOSS_HOME}/server/default/deploy/jboss-web.deployer/server.xml
or
{TOMCAT_HOME}/conf/server.xml

Quick Review of Railo JARs Install on JBoss/Tomcat

I will first give a very brief outline of the steps required to install Railo (jars) on JBoss/Tomcat here. There are, however, some potential problems with this configuration, which I'll outline below, with a solution/workaround for each.

  1. Download and "install" (simply extract to a directory) JBoss or Tomcat.
  2. Download the Railo WAR (from here) and extract (unzip) to a temporary location. Note that I'm suggesting the WAR download and not the "jars" download, because the "jars" download is simply the contents of the WAR's WEB-INF/lib folder; plus, we'll need to copy some XML snippets from the Railo WAR's web.xml file.
  3. Copy the contents of the Railo WAR's WEB-INF/lib folder (a bunch of .jar files) into your JBoss/Tomcat /lib folder.
  4. Copy from your Railo web.xml file to your JBoss/Tomcat web.xml file each servlet block, each servlet-mapping block and the two welcome-file tags (there is already similar XML for each block in the JBoss/Tomcat web.xml file, so it should be obvious where each piece goes).
  5. In your JBoss/Tomcat server.xml file, after the last Host entry, add a new entry like the example below, where the appBase attribute is the Web root of a CFML app (also be sure the host name and/or alias is added to your local hosts file).
  6. Start JBoss/Tomcat and browse to your virtual host on port 8080 (e.g., http://mysite.com:8080/index.cfm). You should see your CFML output.

The following is an example for your JBoss/Tomcat server.xml file. You can also add additional tags and attributes to control log files and much more (see Tomcat docs).

<Host name="mysite.com" appBase="/var/www/mysite">
<Alias>www.mysite.com</Alias>
<Context path="" docBase="" />
</Host>

Potential Problems/Inconveniences

The beauty of the above configuration is that Railo handles a bunch of details automatically, but you may or may not like the results.

First, it just feels a little funny to "blend" all of the Railo jars in a main JBoss deployment /lib folder with a bunch of other JBoss related .jar files. I'll show you how to define a specific directory location, so you can keep your Railo jars in their own directory.

When you first hit a CFML page, Railo will create a lot of files and directories for you. A "railo-server" directory structure is created within your JBoss/Tomcat /lib directory and a WEB-INF directory structure is created in the root of each virtual host directory as well as each top-level directory of each virtual host root. These files and directories provide templates and configuration for server-wide settings (Railo Server Admin) and individual Web context (site/virtual host) settings (Railo Web Admins). This may or may not be an issue, but I don't think I want to have all of this in my Subversion repos, nor do I want to deal with svn:ignore settings. I'll also show you how to specify configuration directory locations for both the server admin and the Web context directories.

Finally, if you choose to use this configuration, but also want to deploy a Railo WAR (or two or more), then you'll run into a "Child name 'CFMLServlet' is not unique" error when you try to start JBoss. I'm hoping to have my "global" Railo jars install handle my smaller CFML apps while also deploying a Railo WAR app or two to experiment with some more enterprisey ideas. I'll show you how to make a few minor naming changes in the JBoss web.xml to allow for all of the above.

Custom /lib directory for Railo JARs

Rather than dumping all the Railo JARs on top of the JBoss JARs you can create a railo-{version}/lib path and let JBoss know where to find it. For example, I've created this directory: {JBOSS_HOME}/server/default/deploy/jboss-web.deployer/railo-3.1.0.012/lib

To let JBoss know to load this class path, add a classpath tag in {JBOSS_HOME}/server/default/conf/jboss-service.xml (just after the existing classpath tag, near the top):

<classpath codebase="deploy/jboss-web.deployer/railo-3.1.0.012/lib" archives="*" />

Custom Railo Server and/or Web Admin Directories

You can control the location of Railo Server Admin and Railo Web Admin directories by making simple changes to the CFMLServlet servlet definition (in web.xml). Take note of the two param-value definitions in the following example.

<servlet>
    <servlet-name>CFMLServlet</servlet-name>
    <description>CFML runtime Engine</description>
    <servlet-class>railo.loader.servlet.CFMLServlet</servlet-class>
    <init-param>
        <param-name>configuration</param-name>
        <param-value>/etc/railo/web-config/{web-context-hash}</param-value>
        <description>Railo Web contexts configuraton directory (where Web admin roots and configuration files will be stored)</description>
    </init-param>
    <init-param>
        <param-name>railo-server-root</param-name>
        <param-value>/etc/railo/server-config</param-value>
        <description>Railo server configuration directory (where server admin root and configuration files will be stored)</description>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

You'll want to prepare for the above example by creating the /etc/railo/web-config and /etc/railo/server-config directories. Then, a /etc/railo/server-config/railo-server directory will be generated, and a hash-named directory for each Railo Web context will be created (by Railo) beneath /etc/railo/web-config.

Global Railo Servlet Plus Railo WAR Apps

If you'd like to use the configuration described above but also drop a Railo WAR in your JBoss deployment directory (say, to test out a brand new beta version:) you'll need to alter the servlet names in your JBoss/Tomcat web.xml file in both the servlet and servlet-mapping blocks. In the following snippet examples, I've simply prepended "GLOBAL" to make the servlet names unique (different than that used in any Railo WARs you deploy as well).

<servlet>
    <servlet-name>GLOBALCFMLServlet</servlet-name>
    <description>CFML runtime Engine</description>
    <servlet-class>railo.loader.servlet.CFMLServlet</servlet-class>
    <init-param>
        <param-name>configuration</param-name>
        <param-value>/etc/railo/web-config/{web-context-hash}</param-value>
        <description>Railo Web contexts configuraton directory (where Web admin roots and configuration files will be stored)</description>
    </init-param>
    <init-param>
        <param-name>railo-server-root</param-name>
        <param-value>/etc/railo/server-config</param-value>
        <description>Railo server configuration directory (where server admin root and configuration files will be stored)</description>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet>
    <servlet-name>GLOBALAMFServlet</servlet-name>
    <description>AMF Servlet for flash remoting</description>
    <servlet-class>railo.loader.servlet.AMFServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet>
    <servlet-name>GLOBALFileServlet</servlet-name>
    <description>File Servlet for simple files</description>
    <servlet-class>railo.loader.servlet.FileServlet</servlet-class>
    <load-on-startup>2</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>GLOBALCFMLServlet</servlet-name>
    <url-pattern>*.cfm</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>GLOBALCFMLServlet</servlet-name>
    <url-pattern>*.cfml</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>GLOBALCFMLServlet</servlet-name>
    <url-pattern>*.cfc</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>GLOBALAMFServlet</servlet-name>
    <url-pattern>/flashservices/gateway/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>GLOBALFileServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

Resources

I did figure a thing or two out on my own, but not without a good deal of direction from key blog posts by Markus Skrabal. After reviewing this post and this post with the help of Google Translate to decipher the German for me, I was on my way. Thanks, Markus!

Finally, a last-minute disclaimer: I'm still pretty much a JEE n00b, so I'm not absolutely certain how much of the above is a good idea or follow best practices, but it does allow me to use one JBoss AS instance to power a bunch of smaller Railo CFML apps (Web contexts) as well as one or more Railo WAR (full-blown JEE) apps, while sharing Railo Server Admins and controlling directory locations as needed.

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
darius's Gravatar Great info, very much appreciated. I'm switching now a few of my boxes from windows/iis/cf7 to ubuntu/apache/jboss/railo and any info helps alot. Running on this config for over 12 years so its a big switch for me :)

Darius
# Posted By darius | 4/2/09 9:16 PM
Jamie Krug's Gravatar @Darius,

Very cool. I'm basically making the same "big switch" :) I was using, just about exclusively, Windows/CF (both IIS and Apache) for roughly 8 years. After leaving my last job (about 4 months ago) I switched my development laptop to Ubuntu and VPS hosting to Linux (CentOS). Now I'm moving a lot of things, including my VPS, to Ubuntu/Apache/JBoss/Railo. It is a big switch, but exciting too!

FYI, here's a useful resource for securing a production-ready JBoss on Ubuntu (I'll probably use this as a reference when configuring my new VPS this week):
http://chiralsoftware.com/linux-system-administrat...

Best,
Jamie
# Posted By Jamie Krug | 4/3/09 9:16 AM
Steve's Gravatar I've followed these instructions and my app is connecting to railo how ever I cannot access the railo admin pages due to the following errors:
07:30:45,400 ERROR [[FileServlet]] Servlet.service() for servlet FileServlet threw exception
java.io.FileNotFoundException: /opt/jboss-test/server/default/deploy/jboss-web.deployer/ROOT.war/WEB-INF/railo/context/admin (Is a directory)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:106)
at railo.commons.io.res.type.file.FileResource.getInputStream(FileResource.java:198)
at railo.commons.io.IOUtil.copy(IOUtil.java:153)
at railo.runtime.engine.CFMLEngineImpl.serviceFile(CFMLEngineImpl.java:273)
at railo.loader.servlet.FileServlet.service(FileServlet.java:32)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.intergral.fusionreactor.filter.FusionReactorFilter.G(Unknown Source)
at com.intergral.fusionreactor.filter.FusionReactorFilter.B(Unknown Source)
at com.intergral.fusionreactor.filter.FusionReactorFilter.doFilter(Unknown Source)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:179)
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:156)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:241)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:580)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)
# Posted By Steve | 6/24/09 2:31 AM
Jamie Krug's Gravatar @Steve: It looks like Tomcat doesn't know what to do with the directory you're browsing to (/railo-context/admin I presume). Try hitting it with the index.cfm explicitly called (/railo-context/admin/index.cfm). Assuming that works, you may just need to add index.cfm to the "welcome-file-list" at the bottom of tomcat/conf/web.xml.
# Posted By Jamie Krug | 6/24/09 9:13 AM
Chris Haubner's Gravatar Good Stuff....I just upgraded to a new version of Railo in production! Definitely would recommend using a separate lib directory to test out different versions with nothign more than a restart :)
# Posted By Chris Haubner | 9/11/09 2:09 PM
Jamie Krug's Gravatar @Chris: Cool! Remember you can also just use the "Update" feature in the Railo Server Admin to upgrade to newer versions/patches -- you can also roll-back patches from there ;-)
# Posted By Jamie Krug | 9/11/09 2:26 PM
Paul G Cormier's Gravatar Jamie, I've successfully used your instructions on my TomCat6/IIS7 install to move /WEB-INF/railo/ out of my virtual host's web root. However, I'm still getting /WEB-INF/flex/ created in my web root when I start TomCat. Do you know the web.xml settings to move that as well? It seems that putting application configuration files in the host's web root is a really bad idea. Any help would be appreciated.

Paul G Cormier
WinCorp Software, Inc.
# Posted By Paul G Cormier | 9/16/09 12:08 AM
Jamie Krug's Gravatar @Paul: I recall tinkering with the behavior you're seeing, and I believe I only got that to stop happening (the WEB-INF/flex/ dirs in Web root) when the Tomcat user did *not* have file write permissions there -- I could be remembering incorrectly too though :) I also haven't gotten around to trying any Flex remoting w/Railo yet, but I think those XML config files may need to live there (under the Web root).

I doubt there's concern for those XML configs being there. It's standard practice for any JEE WAR/EAR app to have a WEB-INF under the root.

I suggest posting your question to the Railo Google Group to get better clarification than I can provide off the top of my head. You may even want to search existing discussions first, as I recall some discussion around this type of stuff.
# Posted By Jamie Krug | 9/16/09 1:50 PM
Jamie Krug's Gravatar @Paul: Also, keep in mind that Tomcat takes care of protecting the WEB-INF folder -- you won't be able to browse directly if you hit a /WEB-INF/ URL on port 8080. So, if you have Apache or IIS in front of Tomcat and don't already have a proxy/connector set to pass everything for the host to Tomcat, then you'll need to address this w/Apache or IIS. In the case of Apache, you'd use a simple mod_rewrite rule to deny traffic to WEB-INF.
# Posted By Jamie Krug | 9/16/09 2:15 PM
Jamie Krug's Gravatar Looks like the Railo team now has a bunch of related goodies documented under:
http://www.getrailo.org/index.cfm/documentation/co...
(note sub-links in left nav too - 3, to date)
# Posted By Jamie Krug | 9/17/09 2:38 PM
Chris Haubner's Gravatar So in regards to the Tomcat creating the WEB-INF\flex folders and files in EVERY folder under a virtual host web root...

You will need to change your appPath to "/" and change the docBase property in the Context to the actual absolute path to your website folder (This was happening on Windows with Railo 3.1 and Tomcat).

In other words:
<Host name="mysite.local" appBase="/">
<Context path="" docBase="C:\myWebSites\mysite.local" />
</Host>   

Again, this was on windows and the specific symptom I was having (In win 7 anyway) was after starting Tomcat, it was dropping a WEB-INF folder in EVERY folder under my web directories, which was annoying to say the least given that I use version control :)

Hope this helps someone...I will get around to posting this on my blog sometime soon as well!!
# Posted By Chris Haubner | 10/25/09 2:33 PM
Chris Haubner's Gravatar Just to be clear on my last comment...this change was in server.xml and will NOT stop it from generating the WEB-INF\flex folder in your site ROOT, but it will stop it from doing it in every folder off of your root too :)
# Posted By Chris Haubner | 10/25/09 2:49 PM
Jamie Krug's Gravatar Hey Chris, thanks for the comments. Yes, I should probably add a couple "update" notes to this post, as I've learned a few other tricks and have my "TRAM(P)" stack running nicely on Ubuntu now (http://tinyurl.com/tramp-vps ;-)

Yes, I have found it important to set your Context docBase to the absolute path of your Web root (same as DocumentRoot in Apache vhost), however, I leave my Host appBase as "webapps" in Tomcat. I believe appBase="/" is stating the root directory on Linux, or the C:\ drive for Win in your example. You may very well have some dirs generated at your C: root, no? :)

So, the Railo jar does indeed generate the WEB-INF dir under each Web app/root under my tomcat/webapps dir, but I delete all the defaults anyway and just leave the ROOT webapp with a test index.html file. I use a Tomcat Host to set a docBase matching each of my Apache vhost's DocumentRoot. This has been working great.

As for generated directories that you don't want under version control, you can just svn ignore all WEB-INF folders if you'd like.

Cheers!
# Posted By Jamie Krug | 10/26/09 12:14 AM
Chris Haubner's Gravatar Hey Jamie,

Yeah good call...it actually was dumping a WEB-INF in the tomcat/conf folder on Windows, and Ubuntu dumped it at the top level folder for my websites...very odd.

So I cleaned that up and changed it to webapps too (keeping with the standard defaults :)

And I thought about the SVN Ignore...I have ignored it in Eclipse ;) and just have not done it in the svn client stuff yet.
# Posted By Chris Haubner | 10/26/09 2:22 AM
Chris Haubner's Gravatar BTW..thanks for the doc link...I pretty much did all the same things you had documented except I have not done the port change for SSH yet...that is a good idea since it is publically accessible (read as "I am going to do that asap" ;). I did however limit who can log into SSH so that I am forced to use a normal user acct and then SUDO into the root account (Which is proper security anyhow so you can track activity properly). From the root account, you can then assume any other user...that way you can limit your SSH access to only 1 (or maybe 2) users.
# Posted By Chris Haubner | 10/26/09 2:35 AM
William Dale's Gravatar When you include ...
<classpath codebase="deploy/jboss-web.deployer/railo-3.1.0.012/lib" archives="*" />
... the railo java libraries the following jboss service are no long accessible form the web:

* Tomcat status (full) (XML)
* JMX Console
* JBoss Web Console

Do you know who to link and still retain the jboss web console>?
# Posted By William Dale | 2/18/10 6:24 PM
Jamie Krug's Gravatar William,

I've always removed all other apps when installing Railo jars "globally" like this. I generally do this with Tomcat, not JBoss, but same idea. I'm not surprised that there could be conflicts with other Web apps when the Railo jars are loaded this way. I doubt it's worth fighting it much. I'd suggest using just Railo with your servlet container instance this way (no other Web apps on the instance), or run Railo as separate WARs for each app.

Actually, with a second glance at your comment, I see that you mentioned these other apps are not accessible -- are they returning 404 errors, or are you getting other errors? If not 404, you can check the logs for error details, but again, I doubt it's worth the fight.
# Posted By Jamie Krug | 2/18/10 10:04 PM
Jack's Gravatar Hey can I copy and paste this texts on my web site? What references might I give? You ought to give this info for others too. =-=
# Posted By Jack | 9/13/11 4:48 AM
Jamie Krug's Gravatar Jack: Sure, you can copy parts of this post--just link back to this page as the original source. Thanks.
# Posted By Jamie Krug | 9/14/11 11:31 AM
BlogCFC was created by Raymond Camden.