Railo on Tomcat on Windows x64 - Part III

Now that we've got Tomcat, Railo and Apache httpd up and running, lets connect Tomcat and Apache.

For this we will need a mod_jk connector. The binary can be found here.

There is no x64 connector as there is no x64 official release of Apache httpd, so we will be using the x32 connector. In my case I downloaded mod_jk-1.2.28-httpd-2.2.3.so from the win32 folder. Download this file and put it in C:\Apache2\modules. Now rename it to mod_jk.so

Create a file in c:\Apache2\conf\extra called workers.properties and put this into the file

view plain print about
1# Define 1 real worker using ajp13
2 worker.list=worker1
3 # Set properties for worker1 (ajp13)
4 worker.worker1.type=ajp13
5 worker.worker1.host=localhost
6 worker.worker1.port=8009

Now lets download Railo and lets set it up. We want to get the custom one, the jars, in my case "railo-3.1.2.001-jars.zip (34 MB)". Create a Railo folder in the Tomcat folder, in my case "C:\Program Files (x86)\Apache Software Foundation\Tomcat 6.0".

Now open up the railo zip file and put the jar files from the railo-3.1.2.001-jars into the railo folder we just created.

Now edit the catalina.properties file that was in Tomcat conf folder, in my case "C:\Program Files (x86)\Apache Software Foundation\Tomcat 6.0\conf". Find the line that says "common.loader=${catalina.home}/lib,${catalina.home}/lib/*.jar" and edit it to say "common.loader=${catalina.home}/lib,${catalina.home}/lib/*.jar,${catalina.home}/railo/*.jar"

Now open tomcat-users.xml and change the encoding to utf-8. At the top where it says "<?xml version='1.0' encoding='cp1252'?>" and change it to "<?xml version='1.0' encoding='utf-8'?>" This is needed due to some weird Tomcat bug on windows.

Now lets open web.xml in the Tomcat's conf directory. Just before the "Built In Servlet Mappings" add the following:

view plain print about
1<servlet>
2 <servlet-name>RailoCFMLServlet</servlet-name>
3 <description>CFML runtime Engine</description>
4 <servlet-class>railo.loader.servlet.CFMLServlet</servlet-class>
5 <init-param>
6<param-name>configuration</param-name>
7<param-value>/WEB-INF/railo</param-value>
8<description>Configuration directory</description>
9</init-param>
10 <!-- init-param>
11<param-name>railo-server-root</param-name>
12<param-value>.</param-value>
13<description>directory where railo root directory is stored</description>
14</init-param -->

15 <load-on-startup>1</load-on-startup>
16</servlet>
17<servlet>
18 <servlet-name>RailoAMFServlet</servlet-name>
19 <description>AMF Servlet for flash remoting</description>
20 <servlet-class>railo.loader.servlet.AMFServlet</servlet-class>
21 <load-on-startup>1</load-on-startup>
22</servlet>
23<servlet>
24 <servlet-name>RailoFileServlet</servlet-name>
25 <description>File Servlet for simple files</description>
26 <servlet-class>railo.loader.servlet.FileServlet</servlet-class>
27 <load-on-startup>2</load-on-startup>
28</servlet>

Now at the end of the servlet mapping section, add the following

view plain print about
1<servlet-mapping>
2 <servlet-name>RailoCFMLServlet</servlet-name>
3 <url-pattern>*.cfm</url-pattern>
4</servlet-mapping>
5<servlet-mapping>
6 <servlet-name>RailoCFMLServlet</servlet-name>
7 <url-pattern>*.cfml</url-pattern>
8</servlet-mapping>
9<servlet-mapping>
10 <servlet-name>RailoCFMLServlet</servlet-name>
11 <url-pattern>*.cfc</url-pattern>
12</servlet-mapping>
13<servlet-mapping>
14 <servlet-name>RailoAMFServlet</servlet-name>
15 <url-pattern>/flashservices/gateway/*</url-pattern>
16</servlet-mapping>
17<servlet-mapping>
18 <!-- could be RailoFileServlet -->
19 <servlet-name>default</servlet-name>
20 <url-pattern>/</url-pattern>
21</servlet-mapping>

Now open up server.xml and at the end of the file inside the Engine tag, we'll add a new host definition.

view plain print about
1<Host name="railotest" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
2 <Context path="" docBase="c:/websites/railotest" />
3</Host>

Now lets go back to our httpd-vhosts.conf Apache file. We need to add the following (I do this outside of any virtualhost definitions.

view plain print about
1# Load mod_jk module
2LoadModule jk_module modules/mod_jk.so
3# Where to find workers.properties
4JkWorkersFile conf/extra/workers.properties
5# Where to put jk shared memory
6JkShmFile logs/mod_jk.shm
7# Where to put jk logs
8JkLogFile logs/mod_jk.log
9# Set the jk log level [debug/error/info]
10JkLogLevel info
11# Select the timestamp log format
12JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "

We also need to add the following to the VirtualHost definition

view plain print about
1# Send requests for cfm files to worker named worker1
2    JkMount /*.cfm     worker1

The full virtualhost definition should look like

view plain print about
1<VirtualHost *:80>
2    DocumentRoot "C:/websites/railotest"
3    ServerName railotest
4    ErrorLog "logs/railotest.com-error.log"
5    CustomLog "logs/railotest-access.log" common
6    # Send requests for cfm files to worker named worker1
7    JkMount /*.cfm     worker1
8</VirtualHost>

Now if we restart Tomcat and Apache we should be able to hit http://railotest in our browser and see the debugging info. We will also see a WEB-INF folder created inside c:\websites\railotest.

Now lets put in an alias for the railo-context so that we can get to the admin. Inside the virtual host add

view plain print about
1Alias /railo-context C:\websites\railotest\WEB-INF\railo\context

Now restart Apache and we should be able to get to the Web Administrator for this host by going to http://railotest/railo-context/admin.cfm

Railo on Tomcat on Windows x64 - Part II

In the previous two parts we installed Tomcat. Now lets set up Apache httpd server.

I suggest downloading Apache from Apache Lounge. The nice thing about Apache Lounge's builds is that they include mod_rewrite and mod_ssl.

The latest version at the time of this writing is 2.2.14. Download httpd-2.2.14-win32-x86-ssl.zip and open it in your favorite archiver (mine is WinRar).

I recommend taking the Apache2 folder inside the zip file and placing it on c:\. After you've done this you should have a c:\Apache2 folder with many files and subfolders in it.

Open c:\Apache2\conf\httpd.conf file in your favorite text editor. I recommend Textpad.

I usually change a few things from the defaults. Your configuration may differ.

Change

view plain print about
1ServerAdmin admin@example.com
to your email address.

Uncomment the following modules:

view plain print about
1#LoadModule proxy_module modules/mod_proxy.so
2#LoadModule proxy_http_module modules/mod_proxy_http.so
3#LoadModule rewrite_module modules/mod_rewrite.so
by removing the # sign in front of the line.

Find the line that says

view plain print about
1<Directory "c:/Apache2/htdocs">

After closing directory tag lets add one allowing access to our web root. I usually set up a folder or a new drive for it. Lets say we set up a webroot of "c:\websites". Create a folder websites on c: and then inside it create another folder called railotest. We will use this to set up our test site.

After the closing tag, add a new one allowing access to our web root.

view plain print about
1<Directory "c:/websites">
2 Options Indexes FollowSymLinks
3 AllowOverride None
4 Order allow,deny
5 Allow from all
6</Directory>

This will allow Apache to serve from anywhere inside c:\websites. Alternatively, you can set up a new directory entry for every site that you create, but I find that this makes things easier without significantly impacting security.

Find the line that says

view plain print about
1DirectoryIndex index.html

and add index.cfm to that list

view plain print about
1DirectoryIndex index.html index.cfm

Uncomment the line that says

view plain print about
1#Include conf/extra/httpd-vhosts.conf
by removing the # sign.

Now open up httpd-vhosts.conf file that is located in "C:\Apache2\conf\extra".

There are two sample virtual hosts defined. Lets comment them both out. Alternatively you can just delete them.

view plain print about
1<VirtualHost *:80>
2 ServerAdmin webmaster@dummy-host.example.com
3 DocumentRoot "c:/Apache2/docs/dummy-host.example.com"
4 ServerName dummy-host.example.com
5 ServerAlias www.dummy-host.example.com
6 ErrorLog "logs/dummy-host.example.com-error.log"
7 CustomLog "logs/dummy-host.example.com-access.log" common
8</VirtualHost>
9
10<VirtualHost *:80>
11 ServerAdmin webmaster@dummy-host2.example.com
12 DocumentRoot "c:/Apache2/docs/dummy-host2.example.com"
13 ServerName dummy-host2.example.com
14 ErrorLog "logs/dummy-host2.example.com-error.log"
15 CustomLog "logs/dummy-host2.example.com-access.log" common
16</VirtualHost>
should look like this:

view plain print about
1#<VirtualHost *:80>
2# ServerAdmin webmaster@dummy-host.example.com
3# DocumentRoot "c:/Apache2/docs/dummy-host.example.com"
4# ServerName dummy-host.example.com
5# ServerAlias www.dummy-host.example.com
6# ErrorLog "logs/dummy-host.example.com-error.log"
7# CustomLog "logs/dummy-host.example.com-access.log" common
8#</VirtualHost>
9#
10#<VirtualHost *:80>
11# ServerAdmin webmaster@dummy-host2.example.com
12# DocumentRoot "c:/Apache2/docs/dummy-host2.example.com"
13# ServerName dummy-host2.example.com
14# ErrorLog "logs/dummy-host2.example.com-error.log"
15# CustomLog "logs/dummy-host2.example.com-access.log" common
16#</VirtualHost>

Now lets add a new entry for our test server

view plain print about
1<VirtualHost *:80>
2 DocumentRoot "C:/websites/railotest"
3 ServerName railotest
4 ErrorLog "logs/railotest.com-error.log"
5 CustomLog "logs/railotest-access.log" common
6</VirtualHost>

Now save the files and lets try running apache and see if it worked. Open up command prompt (Start -> Run -> cmd.exe)

view plain print about
1Microsoft Windows [Version 5.2.3790]
2(C) Copyright 1985-2003 Microsoft Corp.
3
4C:\Documents and Settings\Administrator>
cd \apache2\bin
5
6C:\Apache2\bin>httpd
7httpd: Could not reliably determine the server's fully qualified domain name, using xxx.xxx.xxx.xxx for ServerName
We can ignore that warning since we don't care about the default configuration.

Now we will need to define a host called railotest using windows hosts file. Open up "C:\windows\system32\drivers\etc\hosts" file in your favorite text editor.

After a bunch of comments, you should see

view plain print about
1127.0.0.1 localhost

Lets add an entry for railotest

view plain print about
1127.0.0.1 railotest

Now this computer knows that railotest points to 127.0.0.1.

Lets put a test cfm file in the webroot for railotest. Create a new file called index.cfm and put it in c:\websites\railotest.

Inside the file lets put some basic cf code

view plain print about
1<cfdump var="#server#">

If you still have apache running and put in http://railotest in your browser you should see the code being output. It is not being interpreted yet because we have not hooked up Apache httpd to Railo. We will do this in Part IV.

For now lets set up apache to run as a service.

First stop the httpd that you ran earlier by entering ctrl-c and do the following.

view plain print about
1C:\Apache2\bin>httpd -k install
2Installing the Apache2.2 service
3The Apache2.2 service is successfully installed.
4Testing httpd.conf....
5Errors reported here must be corrected before the service can be started.
6httpd: Could not reliably determine the server's fully qualified domain name, using xxx.xxx.xxx.xxx for ServerName

The Apache service is now installed. I recommend also adding the "Apache Monitor" app to your startup folder.

Click Start->All Programs and right click on Startup. Now click "Explore All Users". In another explorer window open up C:\Apache2\Bin and right drag ApacheMonitor.exe to the Startup folder. Let go of the right mouse button and select "Create shortcut here".

Double click on the shortcut and the monitor App should appear in your taskbar next to the clock and next to Tomcat's icon.

Double click it to open it and click start. Now you have a working Apache installation that will start as a service.

If you enter http://railotest in your browser, you should see the code we wrote earlier. This will persist across reboots.

In the next part, we'll hook it up to Railo and be able to actually execute this code.

Windows Server 2003 SP2 with Firefox 3.5 - downloads "Cancelled"

It seems that the new versions of Firefox have started to respect the server's security policy.

I would usually use firefox to download things on a server to avoid having to deal with IE's enhanced security.

The solution is to change the Internet zone to medium instead of high. This option, however, is disabled by default if you have "Internet Explorer Enhanced Security" installed. This option can be uninstalled from the control panel "Add/Remove Programs'" Add Remove Windows Components option.

After uninstalling, restart firefox and you should be able to download again.

Getting IIS and Apache to run side by side on Windows 2003

Getting IIS and Apache running side by side is not as easy as telling IIS to listen on one IP and Apache on the other. You will need to tell IIS to not be greedy and stop listening on all IPs. In order to do that, you will need the Windows 2003 SP1 Support Tools' httpcfg.exe utility to set the IP's that IIS listens on.

view plain print about
1httpcfg set iplisten -i xxx.xxx.x.x

You would need to run this command once for each IP that you're using. If using a lot of IP's, I suggest writing a simple batch script.

Once you have done this, and restarted IIS, you can use the IP that you have not included in the IP list above for your Apache server.

NTFRS EventID 13506: The File Replication Service failed a consistency check (QKey != QUADZERO)

We have two Windows 2003 Fileservers replicating several folders about 75K Folders, 95K files, about 6GB total. After a large update, I've noticed that the files stopped replicating. Looking at the event log, I noticed the following event:

view plain print about
1Event ID: 13506
2Source: NtFrs
3The File Replication Service failed a consistency check
4 (QKey != QUADZERO)
5in "QHashInsertLock:" at line 696.
6
7The File Replication Service will restart automatically at a later time. If this problem persists a subsequent entry in this event log describes the recovery procedure.
8 For more information about the automatic restart right click on My Computer and then click on Manage, System Tools, Services, File Replication Service, and Recovery.
9
10For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.

Following this event, came Event ID 13555:

view plain print about
1Event ID: 13555
2Source: NtFrs
3The File Replication Service is in an error state. Files will not replicate to or from one or all of the replica sets on this computer until the following recovery steps are performed:
4
5 Recovery Steps:
6
7 [1] The error state may clear itself if you stop and restart the FRS service. This can be done by performing the following in a command window:
8
9 net stop ntfrs
10 net start ntfrs
11
12If this fails to clear up the problem then proceed as follows.
13
14 [2] For Active Directory Domain Controllers that DO NOT host any DFS alternates or other replica sets with replication enabled:
15
16If there is at least one other Domain Controller in this domain then restore the "system state" of this DC from backup (using ntbackup or other backup-restore utility) and make it non-authoritative.
17
18If there are NO other Domain Controllers in this domain then restore the "system state" of this DC from backup (using ntbackup or other backup-restore utility) and choose the Advanced option which marks the sysvols as primary.
19
20If there are other Domain Controllers in this domain but ALL of them have this event log message then restore one of them as primary (data files from primary will replicate everywhere) and the others as non-authoritative.
21
22
23 [3] For Active Directory Domain Controllers that host DFS alternates or other replica sets with replication enabled:
24
25 (3-a) If the Dfs alternates on this DC do not have any other replication partners then copy the data under that Dfs share to a safe location.
26 (3-b) If this server is the only Active Directory Domain Controller for this domain then, before going to (3-c), make sure this server does not have any inbound or outbound connections to other servers that were formerly Domain Controllers for this domain but are now off the net (and will never be coming back online) or have been fresh installed without being demoted. To delete connections use the Sites and Services snapin and look for
27Sites->
NAME_OF_SITE->Servers->NAME_OF_SERVER->NTDS Settings->CONNECTIONS.
28 (3-c) Restore the "system state" of this DC from backup (using ntbackup or other backup-restore utility) and make it non-authoritative.
29 (3-d) Copy the data from step (3-a) above to the original location after the sysvol share is published.
30
31
32 [4] For other Windows servers:
33
34 (4-a) If any of the DFS alternates or other replica sets hosted by this server do not have any other replication partners then copy the data under its share or replica tree root to a safe location.
35 (4-b) net stop ntfrs
36 (4-c) rd /s /q c:\windows\ntfrs\jet
37 (4-d) net start ntfrs
38 (4-e) Copy the data from step (4-a) above to the original location after the service has initialized (5 minutes is a safe waiting time).
39
40Note: If this error message is in the eventlog of all the members of a particular replica set then perform steps (4-a) and (4-e) above on only one of the members.
41
42For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.

In our case, this is not a domain controller, so 4 applies. However, we can't afford to have any downtime since the servers are hosting production website content. I have done these type of restores in the past, and it takes a while to get the images from SVN (SubVersion), and then it takes many hours to replicate. Doing a little googling, I found this microsoft technote:

http://support.microsoft.com/?id=290762

I decided to pick server1 to be authorative, and performed an authorative restore (D4). In order to do that, I followed the instructions in the section titled "Authorative FRS Restore".

view plain print about
1Authoritative FRS restore
2Use authoritative restores only as a final option, such as in the case of directory collisions.
3
4For example, you may require an authoritative restore if you must recover an FRS replica set where replication has completely stopped and requires a rebuild from scratch.
5
6The following list of requirements must be met when before you perform an authoritative FRS restore:
71.    The FRS service must be disabled on all downstream partners (direct and transitive) for the reinitialized replica sets before you restart the FRS service when the authoritative restore has been configured to occur.
82.    Events 13553 and 13516 have been logged in the FRS event log. These events indicate that the membership to the replica set has been established on the computer that is configured for the authoritative restore.
93.    The computer that is configured for the authoritative restore is configured to be authoritative for all the data that you want to replicate to replica set members. This is not the case if you are performing a join on an empty directory. For more information, click the following article number to view the article in the Microsoft Knowledge Base:
10266679 (http://support.microsoft.com/kb/266679/) Pre-staging the File Replication Service replicated files on SYSVOL and Distributed File System shares for optimal synchronization
114.    All other partners in the replica set must be reinitialized with a nonauthoritative restore.
12To complete an authoritative restore, stop the FRS service, configure the BurFlags registry key, and then restart the FRS service. To do so:
131.    Click Start, and then click Run.
142.    In the Open box, type cmd and then press ENTER.
153.    In the Command box, type net stop ntfrs.
164.    Click Start, and then click Run.
175.    In the Open box, type regedit and then press ENTER.
186.    Locate the following subkey in the registry:
19HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NtFrs\Parameters\Backup/Restore\Process at Startup
207.    In the right pane, double click BurFlags.
218.    In the Edit DWORD Value dialog box, type D4 and then click OK.
229.    Quit Registry Editor, and then switch to the Command box.
2310.    In the Command box, type net start ntfrs.
2411.    Quit the Command box.
25When the FRS service is restarted, the following actions occur:
26"    The value for the BurFlags registry key is set back to 0.
27"    Files in the reinitialized FRS replicated directories remain unchanged and become authoritative on direct replication, and through transitive replication, indirect replication partners.
28"    The FRS database is rebuilt based on current file inventory.

So what I did was turned off the "File Replication Service" on server2, which I decided to make Non-Authorative. I made the registry change on server2, changing

view plain print about
1HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NtFrs\Parameters\Backup/Restore\Process at Startup\BurFlags=D2

Then I stopped the FRS service on server1, which I decided to make authorative. I set the same registry entry to D4

view plain print about
1HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NtFrs\Parameters\Backup/Restore\Process at Startup\BurFlags=D4

After starting the FRS service on Server1, the jet database in C:\Windows\ntfrs\jet\ntfrs.jdb shrank from 500mb down to 1mb and slowly started growing again.