Monday, February 2, 2009

Open BlueDragon + Railo + ColdFusion on Tomcat

As a corollary to Sean's post about running Railo, OpenBD, and ColdFusion on JRun, I thought I'd outline my preferred development environment these days, which is to run all the necessary CFML engines on Apache Tomcat. Note that this approach will work equally well on Jetty, JBoss, GlassFish, or more or less any servlet container or JEE server you choose.

Great minds think alike because coincidentally enough, Dave Shuck also has just published two blog posts (part 1, part 2) about setting up a similar environment. I figure I'll throw mine out there as well because the more information available the better.

So why not use JRun? Well, aside from the fact that JRun is getting very long in the tooth at this point, personally (and you'll probably hear me say this in a couple of conference presentations this year), I think the ColdFusion model stands Java on its head a bit, particularly when you do a standalone install of ColdFusion. Yes, it makes it easy to install and configure ColdFusion, but in my opinion it also shields people from how Java web applications actually work, so I've become a big fan of treating ColdFusion like what it is: a Java web application.

This to me makes far more sense than letting ColdFusion and JRun dictate your Java environment. And I think you'll see in this blog post that "installing" CFML engines on Tomcat is actually easier than installing ColdFusion. The only even remotely tricky part is installing Tomcat (and in most cases it isn't tricky at all), so let's tackle that first.

As an aside, if you just want to try Open BlueDragon and don't want to bother with the Tomcat installation, just download the Ready2Run Jetty + OpenBD distribution, start Jetty, and you're done!

Installing Tomcat

I'm assuming you already have Java installed, and I recommend Java 1.6 updater 10 or later (updater 11 is the latest) since previous versions had a bug that makes CFC instantiation horrendously slow. So, if the following looks complicated, it's really only because I'm outlining how to get the Java settings correct if you need to worry about it. Chances you won't need to do most of these steps, and once Tomcat's running the CFML piece of this puzzle is dead simple.

First, download Tomcat. As of this blog post the latest version is 6.0.18, and you'll want the "Core" binary distribution. After the download completes, unzip the file you downloaded. Now comes the tricky install process. Oh wait, I forgot--there is no install process! All you have to do is start Tomcat after you unzip it. If you have your Java environment set up correctly Tomcat should find Java fine and fire right up.

To start Tomcat, open a terminal (or DOS window if you must ...) and navigate to your Tomcat directory, then the bin directory. For example if you unzipped Tomcat to /home/yourname/apache-tomcat-6.0.18, you would navigate to /home/yourname/apache-tomcat-6.0.18/bin. (Note that all of this runs perfectly well on Windows, and though I would never recommend using Windows for anything, you do not have to use Linux to get any of this to work.)

Once you're in the bin directory, run the startup.sh script (./startup.sh) and you'll see some output similar to this:

Using CATALINA_BASE:   /home/mwoodward/apache-tomcat-6.0.18

Using CATALINA_HOME:   /home/mwoodward/apache-tomcat-6.0.18

Using CATALINA_TMPDIR: /home/mwoodward/apache-tomcat-6.0.18/temp

Using JRE_HOME:       /usr/share/java/jdk1.6.0_11

As long as you see something similar everything's likely fine. If you see errors, the most likely culprit is that Tomcat can't find Java. You can either set a JAVA_HOME environment variable, or you can explicitly tell Tomcat where to find Java by adding the JAVA_HOME location to the catalina.sh script in the bin directory. Open catalina.sh in your favorite text editor, and after the big block of comments at the top of the file (denoted with # signs), add the following line:

JAVA_HOME=/path/to/your/jdk

Note that this should be the path to your JDK's home directory, not to a directory such as lib, etc. inside the directory. In my case I have Java in /usr/share/java/jdk1.6.0_11 so that's the value I use for JAVA_HOME. Save catalina.sh and run startup.sh again and everything should work now.

Check to make sure Tomcat is running by browing to http://localhost:8080 You should a page confirming that Tomcat is configured correctly.



Tomcat_screenshot


Installing Open BlueDragon

Once Tomcat is running, since Open BlueDragon is a standard Java WAR (web application archive) file, "installing" OpenBD on Tomcat really just means copying a file to Tomcat's webapps directory so the WAR file is deployed. A WAR file is actually the same format as a JAR file (which is essentially a ZIP file ...), but it has an XML file that tells servlet containers how to deploy the application.

Here are the installation steps for OpenBD:



  1. Download the Open BlueDragon WAR ("J2EE Standard WAR") file from http://openbluedragon.org/download.cfm


  2. Copy the WAR file (which unless you change it is called openbd.war) to /path/to/tomcat/webapps


  3. Wait a few seconds for Tomcat to auto-deploy the WAR file, and browse to http://localhost:8080/openbd to see a test page:


 



Openbd_screenshot


That's it! You now have Open BlueDragon running on Tomcat. Tomcat will deploy the WAR into a context path with the same name as the WAR file, which in this case is openbd, hence the URL http://localhost:8080/openbd If you want to deploy another instance with a different context path name, just change the name of the WAR file as you copy it (e.g. cp opendb.war /path/to/tomcat/webapps/mynewcontextpath.war) and you'll have another instance with a different context path.

As for where to put your CFML files, just put them in /path/to/tomcat/webapps/openbd (or whatever you called your context path), and of course all URLs for this instance will include the context path in them. I won't be covering how to run Tomcat on port 80 or hook things into Apache in this blog post, but I'll cover that in a future post.

Installing Railo

To install Railo you follow the exact same steps as above with Open BlueDragon:



  1. Download the Railo WAR from http://railo.ch/en/index.cfm?treeID=224 -- you want the WAR file under "Railo Custom" at the bottom of the page


  2. Copy the WAR file to /path/to/tomcat/webapps. In this case since the file name includes the version number, I did a cp railo-3.0.2.001.war /path/to/tomcat/webapps/railo.war, which will make the context path "railo"


  3. Wait a few seconds for Tomcat to auto-deploy the WAR file, and browse to http://localhost:8080/railo to see a test page:



 


Railo_screenshot

As with OpenBD above, just put your CFML files in /path/to/tomcat/webapps/railo to run them on Railo in the railo context path.

Installing ColdFusion

ColdFusion is a bit of a different beast since Adobe doesn't distribute a standard WAR file, but luckily you easily can generate one by running the installer. The steps below are when you run the installer on Linux but the same principles apply on other operating systems. Let's generate a WAR file for ColdFusion.



  1. If you don't have it handy, download the developer edition of ColdFusion from http://www.adobe.com/support/coldfusion/downloads.html


  2. Run the installer (note on Linux you need to run the installer as root)


  3. Accept the license agreement (which is really fun to page through on the console installer--I think if you hit enter 28 times that will get you to the "Do you accept?" prompt ;-)


  4. Select Developer Edition (or use a serial number if you prefer)


  5. KEY STEP: Choose an installation type of "J2EE Configuration (WAR file)"


  6. Select the stuff you don't want to include in the installation. I typically uncheck all four choices (docs, LiveCycle, search services, and start on init) when I generate a WAR


  7. Choose the installation directory or accept the default


  8. Enter the admin password


  9. Choose to enabled or disable RDS. I find it's handy to have RDS on development instances so you can use the Eclipse tools to interact with the datasources.


  10. Enter the RDS password


  11. Confirm the installation selections and continue


  12. Wait a minute or so for the WAR to be generated



At the end of this process you have a CF 8 WAR file sitting in your install directory (which by default on Linux is /opt/coldfusion8). Now the installation is more or less as above with OpenBD and Railo since we have a standard WAR file we can deploy on Tomcat:



  1. Copy the cfusion.war file into /path/to/tomcat/webapps As indicated above, this will mean your context path will be "cfusion" unless you rename the WAR file while copying it.


  2. Wait a few seconds for Tomcat to auto-deploy the WAR file


  3. Browse to http://localhost:8080/cfusion to complete the installation process for the WAR.




Cf8_screenshot

Note that you only have to go through the 12-step program above to generate the WAR once, unless you want to change the installation options. So when you need another instance of ColdFusion on Tomcat, just copy the WAR file over again and give it a different name (and hence a different context path) from any other instances.

If this matters to you, please be aware that for some reason ColdFusion isn't officially supported on Tomcat. Why is a bit of a mystery since Tomcat is the servlet container used in JBoss, and in my experience ColdFusion runs just fine on Tomcat. I only bring it up if you're in an environment where official support matters.

Why Do This?

You now have Tomcat running and can easily develop and test on Open BlueDragon, Railo, or Adobe ColdFusion. To me that's reason enough to use a development setup such as this. Also based on my experience helping people get this type of environment set up, it really does start to open up people's eyes to what's really going on under the hood with ColdFusion. Yes, if you do the multi-instance installation of ColdFusion you do get some server management features you don't get otherwise, but based on how I'm using ColdFusion these days, I simply don't need those features, particularly on development.

What I do need, on the other hand, is the ability to develop on both ColdFusion 8 and (increasingly) Open BlueDragon, so rather than trying to shoehorn OpenBD into the ColdFusion/JRun environment, I prefer to use a standard Java servlet container such as Tomcat and put all the CFML engines and instances I need on Tomcat.

Next Steps

You're probably already wondering how to get things to run "for real," meaning eliminating the port number and context path for your users. This can be done several different ways, so I'll cover some options in future blog posts. In the mean time, check out Dave's blog posts (links above) for some info on setting things up with Apache and mod_jk, which is one way to go. You can also change the port Tomcat runs on, or proxy from Apache out to Tomcat for CFML sites, so there's no shortage of ways to set up more or less any configuration you want.


Comments



Yes, the lack of "official support" for Tomcat is odd since JBoss 4.0.3, 4.0.5 and 4.2 are all officially supported!


I've never had much luck getting Tomcat to work with a webroot outside of its install tree - could you post instructions for that?


I guess my ideal setup would be to use Apache vhosts to select which engine handles the code but to have each project have its own webroot that all three engines can see, e.g.,


dev-cf.project.com -> CF8 and {workspace}/project/wwwroot


dev-railo.project.com -> Railo and {workspace}/project/wwwroot


dev-openbd.project.com -> OpenBD and {workspace}/project/wwwroot





Great Post and looking forward for your future post on this topic.





@Sean--concerning the webroot outside the Tomcat area, do you mean having your CFML files in a directory elsewhere on your hard drive? Like /home/user/mywebs as opposed to being in the Tomcat webapps directory?





It seems like I heard that Adobe wasn't going to support JRun any more, am I remembering wrong?





@Jake--they announced some time ago that they will not be developing new features for JRun.


http://tinyurl.com/d4tmu2


The last official update was in 2007.


ColdFusion/JRun FAQ is here:


http://tinyurl.com/d575v7


Personally it seems to me they'd do better forgetting about JRun and shipping ColdFusion as a standard EAR/WAR distribution, but I understand that they have an investment in the JRun + CF combo so that probably won't happen, at least for a while.





@sean Part of what Matt is talking about here having a more standard JEE configuration. Having a war access resources outside of itself seems to go against the spirit of what Matt is talking about accomplishing. You can configure tomcat itself to look for war files anywhere on the system by adding a context element to server.xml (Confluence standalone does this very nicely refer to it as a good example). Maybe later I'll post my ANT file for people if they want to use it to deploy to the different war's (which is how I have my dev setup). I have a builder attached to each Eclipse project which deploys the code to all configured war files.





@Adam--yep, that's part of it too. I'm becoming a massive fan of just dropping a WAR with everything in it on a production server when I need to deploy an app, not to mention it keeps my development environment dang tidy.





I understand the value of a packaged WAR but for development at least, it's nice to have a single webroot for a project with all your CFML engines pointing to the same place.


I believe you can configure Tomcat to serve specific directories for specific hostnames and then you could use a symlink from webapps/something to the actual webroot?





Great timing, a few week's ago I tried to do the same but with Apache in the mix. I think I'll take another look.


Looking forward to that next post. Could you comment here to alert us when it's up maybe?


Thanks.





@sean I still don't like the approach personally but hey we all have our quarks. Anyone interested in doing it this way is probably looking for is allowLinking. You would specify this in a context element in the server.xml (due to windows security issues this is disabled by default). More info:


http://tomcat.apache.org/tomcat-5.5-doc/config/context.html





@Adam @Matt Based on your comments then, you advocate holding all files for a web application under the context root in Tomcat (ie /usr/tomcat/webapps/projectX)?


Maybe I'm missing something but doesn't that force all requests to go to the app server, instead of just the CF-related requests. That seems to be counter-productive to me in that we want Apache to serve graphics, css, html and other "non-CF" stuff because that's what it's good at.


I'd like to move to having all my CF engines active under Tomcat (and in fact as of right now have CFMX7, CF8, OpenBD, and Railo3 deployed to Tomcat on my Mac). My issue is that I keep projects sorted by client under my home directory as in /Users/userName/Sites/ClientName/ProjectName so that multiple projects for a specific client stay together. Then I can create Apache vhosts to point to the correct folder for that project


I really want to find out how to replicate the proxy behavior that the JRun connector gave us that only sent .cfm, .cfc etc to the app server while letting Apache do what it excels at.


Looking foward to your next posts. Hopefully it'll come later this week so that I can play with some of this configuration while I'm on the RIAdventure cruise next week!





Counterproductive because ... ? You can set things up a bunch of different ways, but I think the notion of "use Apache for static content because it will be faster" is antiquated at this point (and it's a notion I held until I read more about the various Tomcat connectors). Using the native Tomcat HTTP connector is actually going to perform better than using the AJP connector, which would hand CFML processing off to Tomcat while Apache would handle everything else.


So what I'm saying is unless you really *need* Apache (and you may ...) you can use the HTTP connector built into Tomcat and get far better performance for both dynamic and static content, and the setup is a lot more straight-forward.


On my VPS right now I'm using Apache and just proxying out to Tomcat + OpenBD for all my CFML content. I did it this way because I already had Apache configured, and I do have a couple of sites running on here that are straight HTML, but I'm going to convert these over because proxying is actually the least performant option. As fast as things run even using proxying I can't wait to see how fast things run on Tomcat with the native HTTP connector. :-)





Apache is no better at fielding requests than the Tomcat HTTP connector (like Matt was saying). What apache excels at, over tomcat's HTTP handling, is configuration (and this is based off older experiences this too may have changed). Unless you have a configuration that can not be done easily in Tomcat I'd just use Tomcat (or jetty for that matter). Even if I do need an http server I use lighttpd or ngineX over apache these days. The only reason apache is installed on my personal server is for SVN (which last time I checked the connector was still in early works for lighttpd).


At work it is a different story we have a dedicated logical partition (actually multiple clustered HTTP servers) that handle some of our static content and proxy to a cluster of CF servers. Again though we do this not for performance but because we use siteminder and it has to connect to either IIS or Apache (or a derivative). Since we have that http server we figured why not put all of the reusable static content on a shared partition and host it straight off there, while anything that is app specific remains packaged in the war.





@Matt - How do you deal with URL rewriting without Apache?





One interesting point I'd like to discuss regarding proxying requests in this type of setup. I run an NginX / HAProxy combo as my proxy layer. Much smoother then apache for static content and the likes.. But I find that when proxying a request for "/" to "/cfusion" or what have you, theres an anomoly w/ the cookies wherein each cookie seems to be tied to not only a domain, but also a context root. Have you had an experience with this happening?





@Adrian--depends on how much URL rewriting you need. You can easily set up hosts on Tomcat just as you do on Apache to have Tomcat respond to normal URLs without the port and context path and point those to a specific web app.


You can also do more full-blown URL rewriting on Tomcat, either directly or through an add-on. I haven't tried it myself but Tomcat does include a URLRewriteFilter that lets you put rewrite rules in place.


I'll know a lot more once I cut the Apache cord and run pure Tomcat. ;-)





I receive a HTTP Status 404 - /cfusion/


Any ideas?





NM, I had to put in the full url: http://localhost:8080/cfusion/CFIDE/administrator/index.cfm Duh!





Always useful to know this stuff, but would be even more useful if it wasn't anti-windows, as that is after all what most of us use, it is only a small minority of developers who use Linux and even most CF hosts also use windows.





@Russ--not sure how not poking fun at windows makes the information itself more useful. I'm a firm believer in the free software movement so I don't use Windows unless I'm forced to, and just because from some people's perspective "most people use Windows" that doesn't mean I'm required to take my time to cater to Windows users when I myself hardly use it at all. It's not my main area of familiarity. Not to mention the fact that with legions of Windows users out there, someone else can surely take anything I post that's Linux specific (which this isn't!) and modify it for Windows.


And frankly I don't think Linux/Mac users are as small of a minority as you may think they are, and many people are interested in learning about Linux, so I think I'm filling a need there.


Also, I think people need to have a sense of humor about the whole thing. So I hate Windows--so what? All this stuff is Java anyway, so even my Windows-specific post about getting all this stuff running is only about 10% Windows-specific. If people get something out of my posts and also lose a bit of the fear of the unknown when it comes to Linux in the process, all the better as far as I'm concerned.





Matt,


I am sorry you hate windows that much that is causes you to rant like a rabid dog in to a harmless comment, which is simply a statement of fact. Perhaps you need to take a chill pill there and stop getting so angry, it is just an operating system, and it is the one most of the population uses whether you like it or not.





@Russ--first off, I'm not ranting like a rabid dog, so I'm not sure where you're coming from when you make a comment like that. I realize you can't hear my tone when just reading text, but I honestly don't think I'm the one who needs the chill pill here. 99% of my bitching about Windows is intended to be humorous--why are you getting so angry and defenseive about me not liking Windows?


Second, not that this even needs to be said, but it's my blog and if you don't the way I present things, you're certainly free to get your information elsewhere.


Lastly, as I said in my other comment (and frankly it sounds like a lot of this is coming out of you being frustrated about something wholly unrelated to my attitude about Windows ...) I don't use Windows much, and given the fact that I don't like Windows I'm certainly not going to spend my time installing and using Windows to cater to people who do use it. Majority doesn't rule here--I have a choice not to use Windows and I choose not to. Everyone's free to make their own choice.


Again, I'm really not angry. Seriously. So I'm not sure where your vitriol is coming from. If it's just an operating system why do you care so much that I don't like it? Do you expect me to suppress my attitude on my own blog so I don't "offend" Windows users? I just don't get it.





I'm afraid you have lost me now Matt, I am not angry or defensive, nor have I said anything angry or defensive. The only anger I can see here is yours i'm afraid. I personally don't care whether you like windows or not, it certainly desn't affect my life in any way. All I said was it would be better if it was not so anti-windows, which is simply my opinion, i'm afraid I cannot fathom why this has sent you off in such a rage.





Can someone post a WAR for Adobe's CF so that we don't have to go through the install process...





@Baz--that would be against the terms of the CF license I believe. It's really not *that* bad and once you have the WAR file created, you can re-use it so you don't have to create it every time.





@Matt What pain in the license :) My Ubuntu desktop is so nice and clean, I'm hesitant to have some installer litter it...





I'm sure it wouldn't be a big deal. anyone can download the trial/developer edition and generate a war file, so you are not giving anything away as it would still be a trial/developer ediiton without a license.





I know in the past it has been an issue--I know at least a couple of people who asked Adobe if they could provide the CF runtime with sample apps and the answer was an unequivocal no. Maybe that's changed.





Hi. I appreciate your article on setting up openbd but I am having an issue that likely has a simple fix. Being a newbie I simply cannot figure it out and was hoping you could help. I would like to put my site in a sub-directory of my "/etc/tomcat/webapps/openbd" directory. But as soon as I change my tomcat host from "/opt/tomcat/webapps/openbd/" to "/opt/tomcat/webapps/openbd/mysite/", it no longer works. I get a "HTTP Status 404" error. ANY help with thiw would be HUGELY appreciated.





Has anyone figured out to configure railo and coldfusion to use the same webroot on a windows machine?


I can specify a webroot in the railo administrator but i can't tell how to do this for coldfusion. If you are interested in details, take a look here: http://serverfault.com/questions/47109/coldfusion-8-does-not-accept-document-...





this may be a dumb? but you recommended using the java 1.6 update 10, on osx, it runs the java update through the os updater and i noticed that it is not version 1.6. I am currently on 10.5.8 and its running:


java version "1.5.0_19"


Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_19-b02-304)


Java HotSpot(TM) Client VM (build 1.5.0_19-137, mixed mode, sharing)


will this cause an issue or is there a way around this to update it to the latest version? I am hesitant to affect anything that can screw up my machine.


Thank you Matt





@Chris--I haven't heard of any problems with Java 1.6 on the Mac, but of course you can simply point Tomcat to Java 6 if you don't want to make it the default before Apple officially ordains it as the default. (As an aside, Apple handles Java very strangely IMO.)


So, if you've done all the OS X updates as far as I know you'd have Java 6. So you can point Tomcat directly to that and you should be in good shape. Note that the latest nightly of OpenBD REQUIRES Java 6, as will (presumably) versions moving forward, so you'll at least need to point Tomcat to Java 6 in order to be able to run OpenBD.


Let me know if you need more details.





@Matt from what I have found out, you can either switch the java preference in the java utilities app or going through ADC to get the coming updater: http://adcdownload.apple.com/Java/java_for_mac_os_x_10.5_update_5_developer_p...


I changed my pref and when I use java version in terminal I am now showing "java version "1.6.0_13"





@Eric--sorry, was going back through old emails and couldn't remember if I ever addressed your question.


Some common problems that might cause what you're seeing are A) you're not restarting Tomcat after you make a configuration chnage; B) you don't have your site files and your WEB-INF files in the same place; or C) your config file syntax isn't correct.


If you're still having trouble feel free to email me and I'll help if I can.



No comments: