This is the third of three posts on installing Railo 3.1 on Windows Server 2008 with IIS7. The previous post can be found here.
Okay, in our last episode, we focused our incredible shrinking brains solely on getting Tomcat and Railo set up and working as a standalone entity. We also did the preliminary work of getting IIS7 set up with whatever domains we plan on giving the ability to execute CFML requests. In this final chapter we are now going to do the dirty work of bridging the two together. As a reminder, here is my view of how the two entities (IIS and Tomcat) will be communicating:

The key to this bridge is "The Connector", a DLL whose job in life is to evaluate incoming http requests and determine if said request should be redirected for processing or not. I use the word redirected, but it isn't a true redirection in the sense of sending the caller to a different URL. Rather, it is more so deferred processing; if the incoming request matches a pre-defined filter list, then that request will be deferred to Tomcat for processing, the resulting html being returned to IIS for delivery to the caller.
Here's an overview of what we're going to accomplish:
- acquire and install the DLL;
- "wire up" the DLL to IIS7;
- tell the DLL what requests to be watching for;
- tell Tomcat what domains it should care about and where it can find those domains' content;
Before we begin, go ahead and make sure Tomcat is shut down. If you need to know how, see step 6 in the previous post.
Get The DLL
1. Download the DLL from http://www.ip97.com/apache.org/tomcat/tomcat-connectors/jk/binaries/win32/jk-1.2.28/isapi_redirect-1.2.28.dll . If that specific file is removed or superceded by a later version, or you find that you need the win64 version, just pare the url back to the appropriate place so you can drill down yourself.
2. Once you have the DLL, create a folder called 'scripts' under your inetpub folder and drop the dll in there.
3. Now we have to create the configuration files (.properties files) that the DLL will use to communicate with Tomcat. When you create these, make sure that a ".txt" extension doesn't get tacked on to the end, k? c. Create C:\Program Files\Tomcat6\conf\uriworkermap.properties and paste the following into it: d. Create C:\Program Files\Tomcat6\conf\workers.properties and paste the following into it Okay boys and girls, now we've got everything in place from The Connector back to Tomcat; it's time for us to connect The Connector to IIS! (note: I am assuming at this point that you are able to navigate to localhost and your other domains already, viewing at least a default html page) Tell IIS It's Okay To Run the DLL 6. Click on the Jakarta virtual directory, then double click on the 'Handler Mappings' icon Repeat Steps 3 through 7 for Remaining Domains Your Other Domains and Tomcat Let's say that IIS is also hosting a domain called MyDomain.Net. For development purposes, you will also be referring to this domain locally as "MyDomain-Test". Your domain's web root is located at C:\inetpub\wwwroot\mydomain.net, and you already have an entry in your hosts file (MyDomain.net MyDomain-Test) to allow you to successfully navigate to MyDomain.net via http://MyDomain-Test. What we need to do is create another <Host> entry in our server.xml file that defines this host AND its known alias. Here is the snippet you should paste in to your server.xml file (values replaced appropriately with your own, of course), just below the localhost entry: <Host name="MyDomain.net" appBase="webapps" (note: make sure you understand the Context tag and the Alias tag in the above snippet. You can have multiple Alias tags, but you must make sure that the alias actually resolves before its of any use here. Either DNS entries are in place, or the Hosts file is being used for local resolution. Context is important because that is what tells Tomcat where to look for the files being requested.)
Save server.xml, restart IIS, restart your web sites, then restart Tomcat. You should now be able to successfully navigate to http://MyDomain.net/index.cfm as well as http://MyDomain-Test/index.cfm! Troubleshooting Hints TIPS AND POINTERS 1: Within IIS, you can specify the order that default documents should be looked for regarding any given site. Just click the site, then the "Default Document" icon If you want index.php to be the default document, simply make sure index.php appears before index.cfm, or leave index.cfm out of the list altogether. That's half of the issue. The other half is the dll that sniffs every single request to determine if it should redirect or not. The snippet I gave you earlier for C:\inetpub\scripts\isapi_redirect-1.2.28.properties included the line " /*=wlb ". This line essentially tells the redirector, "redirect everything to Tomcat". Remove or comment out that line, and then ONLY the requests for files with the specific CFML extensions will be redirected for processing. flex2gateway Basically, any process you want to run that needs Railo to do the work, add an appropriate filter to the DLL's properties file so that it will know to redirect the processing to Tomcat. That's all folks, and quite a lot it is. Any corrections or comments or suggestions or other tips and tricks are welcome!
a. Create C:\inetpub\scripts\isapi_redirect-1.2.28.properties
b. Paste the following into that file:
# The path to the ISAPI Redirector Extension, relative to the website
# This must be in a virtual directory with execute privileges
extension_uri=/jakarta/isapi_redirect-1.2.28.dll
# Full path to the log file for the ISAPI Redirector
log_file= C:\Program Files\Tomcat6\logs\isapi_redirect.log
# Log level (debug, info, warn, error or trace)
log_level=debug
# Full path to the workers.properties file
worker_file= C:\Program Files\Tomcat6\conf\workers.properties
# Full path to the uriworkermap.properties file
worker_mount_file= C:\Program Files\Tomcat6\conf\uriworkermap.properties
#rewrite_rule_file= C:\Program Files\Tomcat6\conf\rewrites.properties
##########################################################
/*=wlb
/*.cfm=wlb
/*.cfc=wlb
/*.cfml=wlb
# This file provides minimal jk configuration properties needed to connect to Tomcat.
# The workers that jk should create and work with
worker.list=wlb,jkstatus
# Defining a worker named ajp13w and of type ajp13
# Note that the name and the type do not have to match.
worker.ajp13w.type=ajp13
worker.ajp13w.host=localhost
worker.ajp13w.port=8009
# Defining a load balancer
worker.wlb.type=lb
worker.wlb.balance_workers=ajp13w
# Define status worker
worker.jkstatus.type=status
####################################
1. In IIS Manager, click the main host, then double click the "Isapi and CGI Registrations" Icon 
2. In the right hand panel, click the 'Add' link, then fill in the path to your dll as well as a name (any name will do). Be sure to check the little box! 
Link Up Your Filter to Your Site
3. Click on your server's default site ("Default Web Site") and double click the ISAPI Filters icon. 
4. In the right hand panel, click the Add link and fill in the name of your filter (the name you gave it in the previous step) and the path to the dll. 
Create a Very Special Virtual Directory in Your Site
5. Right click on your Default Web Site and select 'Add Virtual Directory'. Name it 'Jakarta', and point it to C:\inetpub\scripts


7. In the right hand panel, click on the link named "Edit Feature Permissions", then check the "Execute" box and close. 
8. Restart IIS, restart your default web site (just for good measure), restart Tomcat, drop in a test index.cfm file into your default web root, and see if you can navigate to localhost/index.cfm! It should work at this point.
Now, go back through steps 3 through 7 to get your remaining domains ready to use Railo. Skip step 8 for the time being (at least the part about browsing to an index.cfm), because we have to dive back into Tomcat before those domains will know what to do with a .cfm file.
Tomcat comes pre-configured with localhost, so for that domain we don't have to do anything. But for any other domains you may be wanting to run on this server, we're going to have to tell Tomcat that they exist and a few things about them. Your domains will now be referred to as 'Hosts', and we'll be working inside C:\Program Files\Tomcat6\conf\server.xml to set them up.
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
<Alias>MyDomain-Test</Alias>
<Context path="" docBase="C:\inetpub\wwwroot\mydomain.net"/>
</Host>
Hopefully everything went well, but if not, don't panic. First, check your Tomcat log file to see if it had any issues starting up due to configuration errors (type-os, paths, etc.). You can find the log file at C:\Program Files\Tomcat6\logs\catalina.2009-09-04.log (or whatever today's date is for you). Remember that in this log file, latest entries are appended to the bottom. You can also eliminate some things by verifying that you can browse to your domain in IIS (calling a standard html page, not the cfm page), and in Tomcat by browsing to your domain with a specified port. In our sample above, we could perform this troubleshooting by browsing to http://MyDomain.net/default.htm , and http://MyDomain.net:8081/default.htm . If both of those resolve correctly, then try browsing directly to your .cfm page with http://MyDomain.net:8081/index.cfm. If that parses correctly, we know that Railo is doing its job and that the issue is probably somewhere in the redirection portion of things, meaning we should review our web sites' IIS settings again and the values in the properties files related to our DLL.
Default Files
In my scenario, I have to run both PHP files AND CFM files from the same domain. IIS already knows what to do with PhP files via an ISaPI mapping associating the PHP executable with files of that extension. And, the way the Tomcat connector dll works, it looks at every request to that domain to determine if it should redirect or not. SO then...what if I want the url http://MyDomain.net to default to index.php instead of index.cfm? Two pieces to that puzzle.

I had a conversation with Paul Kukiel regarding an issue he was having getting flex2gateway to resolve without having to specify the port. Now, Paul was using IIS6 in that instance, so this solution doesn't apply, but I found that I myself wasn't able to get flex2gateway to resolve in my scenario either. The solution was simply adding this line to C:\inetpub\scripts\isapi_redirect-1.2.28.properties: " /flex2gateway/*=wlb "
You are not logged in, so your subscription status for this entry is unknown. You can login or register here.
Next...flood of questions: Is this your production environment? I'm interested to find out what the experts think of this particular setup (IIS7 / Tomcat / Connector / Railo). Is this production ready? How will the ISAPI Connector handle load? For that matter...Doug, have you done any load testing on this config?
Sorry for the flood of questions...I am just REALLY interested in how I can put Railo into production, but I'm no guru and typically use wizards to set up servers :)
Many thanks!
"is this your production environment?" - yes, it will be!
"is this production ready?" - I have no idea, but I assumed that I could tweak the Java Runtime Environment settings to make it so! I guess I'll find out soon enough myself! :)
"How will the ISAPI Connecter handle load?" - I honestly do not know the answer to that one, but it's an outstanding question, and no, I haven't done any load testing with this config whatsoever at this point. If anyone does, though, I would love to find out the results!
Anybody else have some input on JD's questions?
1. Step #1 should read "Isapi and CGI Restrictions" not "Isapi and CGI Registrations"
2. It's not indicated anywhere, but the url to the Railo Web Administrator interface is:
http:localhost/railo-context/admin/web.cfm
3. Lastly, something is not right which I hope your more knowlegdeable readers (than me) can address. Following your steps as described results in the /WEB-INF/ being created in my public web root folder?!? (e.g. C:\inetpub\wwwroot\WEB-INF\.. )That can't be right, nor can it be very safe. Did I not complete one of the steps correctly? How do I now move that folder out of my web root?
Paul G Cormier
WinCorp Software, Inc.
Regarding why you have a WEB-INF in your root folder/default web site...in my example, I wanted to be able to execute CFML templates in my root directory, and so went ahead and configured localhost (which typically does default to your web root) in the tomcat server.xml file. Basically, any web site that you configure to work with railo is going to have its own copy of WEB-INF, because that folder is where all of the site specific settings are stored. Thus, since localhost was configured as such, it had ITS own copy, too. If you want CFML templates to execute in your root, then it has to have a WEB-INF.
That being said, it MIGHT be possible to move the WEB-INF to a virtual directory outside of the actual root. Not sure if that addresses security concerns or not, or if it's even possible to do it that way, but it's worth investigating and/or asking on the railo google group list.
Thanks for mentioning how to get to the railo administrator! I can't believe I forgot to mention such an important item! To add to that, it's important to know how to get to the railo Server admin as well. That url is http:[your site]/railo-context/admin/server.cfm (for example, http:localhost/railo-context/admin/server.cfm)
I think I'll do a short post on the difference between server.cfm and web.cfm since I have heard others being confused by the difference in their roles. Link to follow soon!
Doug :0)
since it seems that only the 32 bit version of the redirector dll works, it is vital, after following the above steps, that you then go into your Application Pools section, choose the pool for your site, click the "Advanced Settings" link on the right, and change "Enable 32 Bit Applications" to TRUE. Unless you do this, you will get a persistent 404.3 error that will drive you NUTS (as it did me for a couple of hours today). :)
Calling GetFilterVersion on ISAPI filter "C:\inetpub\scripts\isapi_redirect-1.2.28.dll" failed
Any ideas?
I honestly don't need IIS, I'm looking to implement Railo with either the built in Resin server or Tomcat, and just direct traffic from a load balancer from port 80 to 8080 (or 8600 for Resin). However, I was doing this all on an Amazon EC2 Windows instance and for some reason no matter what firewall rules I added, I couldn't hit the 8080 or 8600 ports (or 80 if reconfigured), but the IIS setup worked on port 80. I'd like to avoid the performance hit of adding IIS on top of Tomcat, but I'm also much more familiar with IIS so it's a catch 22 at this point :)
Thanks in advance.
I got Tomcat serving up CF with Railo on Win2008/IIS7 now, thanks to your help here. This is something I've tried about four times before and could never get it working properly.
I do have one outstanding issue I'm hoping to get some help with: when I hit http://localhost/index.cfm directly (and explicitly), it comes up fine. When I just go to http://localhost/ , however, I get a big fat 404.3 error from IIS. I did add index.cfm to my list of welcome files, so I'm not sure what I need to do beyond that.
Anyone?
i installed everything (with railo installers) and now if i'm hitting http://mysite.com/index.cfm everything works. but if i hit http://mysite.com i get a Unknown-File Message and the browser askes me if i want download the file...
Any idea?
Just removed that tag and everything works fine.
http://www.apache.org/dist/tomcat/tomcat-connectors/jk/binaries/
The link above seems to be broken. Hope that helps!
Great article by the way - thanks!
# Log level (debug, info, warn, error or trace)
log_level=debug
# Log level (debug, info, warn, error or trace)
log_level=error
If you leave it at debug, the later version of the connector (e.g. 1.2.30) will fill the file with debug, and it will actually seriously slow your app.
Hoep that helps someone!
Thanks again!
Thank you
Great setup tutorial.
Very easy to follow...Although, I don't know where I am going wrong...
I have set everything up as you are suggesting in this two part tutorial.
When I test along the way as you suggest, everything is working perfectly... until...
When I go to localhost:8081/index.cfm (a page I created to output time and hostname)... it works perfectly!
Then when I try going to localhost/index.cfm (which is to the same page) the output doesn't, well, output. I just see the text "#now()# - #cgi.http_host#".
The only difference I have to you is the DLL "isapi_redirect-1.2.28". Mine is "isapi_redirect-1.2.30", so I made the obvious necessary adjustments along the way.
My environment is Windows Server 2008 64bit Standard with SP2 and all updates installed.
Have you got any ideas?
Please help.
Thanks for the tutorial... I'm ALMOST there... however, I'm getting a 500 ERROR:
HTTP Error 500.0 - Internal Server Error
The page cannot be displayed because an internal server error has occurred.
Module:
IsapiFilterModule
Notification:
AuthenticateRequest
Handler:
StaticFile
Error Code:
0x80070001
Requested URL:
http://localhost:80/index.cfm
Physical Path:
C:\inetpub\wwwroot\index.cfm
Logon Method:
Anonymous
Logon User:
Anonymous
Anyone have any ideas?
However, I'm experiencing the opposite of what the others were ... when I go to "localhost", it's all good. However, when I access "index.cfm" directly, I get a 404.3 - Not Found:
HTTP Error 404.3 - Not Found
The page you are requesting cannot be served because of the extension configuration. If the page is a script, add a handler. If the file should be downloaded, add a MIME map.


