2010-12-15

Deploying Web Apps in Apache Tomcat via the "jFastCGI" Java Servlet

    When deploying web apps built in Web Edition of REAL Studio, you can either build a basic web server into your app, or you can place you app "behind" a separate web server using the FastCGI protocol as a conduit between them. FastCGI is just a protocol, some rules of the road, with many implementations in various web servers.

[A] Apache Tomcat
These brief steps here for Tomcat installation are described more fully in my blog post:

(1) Download version 7.  
That first "Core" zip will do.

(2) Unzip.

(3) On Mac OS X (and maybe Linux) fix file permissions.
I'm not sure about v7, but on previous Tomcats I always ran into permissions problems.
On a Mac I drag and drop the unzipped folder to free "BatChmod" app.
I turn on all "Options" checkboxes except "Clear xattrs". Click Apply button.

(4) Move the unzipped folder to the top of your home folder. 
I'm paranoid about problems with very long pathnames due to too many nested folders.

(5) Launch Tomcat.
(5a) In the Apache Tomcat folder, find the "bin" folder. 
(5b) Launch the Terminal program. (Command Prompt window in Windows)
(5c) Drag the "startup.sh" file to the Terminal, and press Return. (Use the .bat for Windows)
See several lines confirm startup.

Launch a browser, point it to:
You should see a Tomcat-generated page.

[B] Port-forwarding

For Windows, skip to step 4.

For Mac & Linux, forward port 80 calls to Tomcat's default of 8080.
For more info, read my blog post: 

(1) Open another Terminal window.

(2) Paste this:
sudo ipfw add 100 fwd 127.0.0.1,8080 tcp from any to any 80 in
and press Return.

(3) Enter your password in Terminal as prompted.

(4) Test by pointing a web browser to:
You should see the Tomcat-generated page.

Tip: Always hit your browser's Refresh/Reload button/command to force a fresh loading of the web page. Some web browsers, especially Safari, display a cached copy of web pages rather than asking for a fresh one. That caching behavior can really confuse your testing!

(5) Shutdown Tomcat.
(5a) Drag the "shutdown.sh" file to the same Terminal window where you started Tomcat.
(5b) Press Return.

[C] jFastCGI Servlet

(1) Download 2.0 of jFastCGI.

(2) Unzip.
You'll get a folder with 2 .jar files and a .pdf manual.

(3) In the Tomcat folder, navigate to "webapps" folder. 
(3a) Delete or move everything inside "webapps".
(3b) Create a folder named "ROOT" inside the "webapps" folder.
(3c) Create a new Welcome page, for testing. For example, save the following HTML5 source code to a file named "index.html" stored in that "ROOT" folder:

<!doctype html>
<html>
 <head>
   <meta charset="UTF-8">
   <title>Welcome</title>
 </head>
 <body>
   <p>Per Basil's example.</p>
 </body>
</html>


(4) Install servlet.
(4a) Create a "WEB-INF" folder inside the "ROOT" folder.
(4b) Create a folder named "classes" inside the "WEB-INF" folder, next to that index.html file you just created.
(4c) Move in both .jar files from jFastCGI download: 
• commons-logging-1.1.1.jar
• jFastCGI-2.0.jar
FYI: .jar files are simply zip files plus an optional manifest file, used for storing Java executable and related files.

When done, your files should look like this screenshot.

Ignore the "Joda Time" and the commons-logging.

(5) Deploy Servlet Create an XML file to be used as a "Deployment Descriptor" instructing Tomcat when and how to invoke the jFastCGI servlet.
(5a) Create a new text file. Use UTF-8 character encoding.
(5b) Name the file "web.xml" and store it inside the "WEB-INF" folder used above.
(5c) Paste the following:


<?xml version="1.0" encoding="UTF-8"?> <web-app 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                        http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
       version="3.0"
       metadata-complete="true">

<servlet>
    <servlet-name>FastCGI</servlet-name>
    <servlet-class>net.jr.fastcgi.FastCGIServlet</servlet-class>
    <init-param>
        <param-name>server-address</param-name>
        <param-value>localhost:9000</param-value>
    </init-param> 
</servlet>

<servlet-mapping>
    <servlet-name>FastCGI</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

</web-app>

[D] Run.

(1) Launch Tomcat. 
Tip: In Apple's Terminal, you can press the Up arrow key to repeat previous command line. Press again for previous before that. Press Return to execute.

(2) Build a simple web app in REAL Studio.
(2a) Build as "Static FastCGI" using port 9000. This assumes you have no other apps listening on port 9000.
(2b) My app: Create a TextField named "nowField" with an adjacent button whose Action event handler is:
 dim now as new Date
 nowField.Text = now.SQLDateTime

(3) Launch web app
(3a) In a new Terminal window, type out the entire path to your built app, and press Return. For example:
/Users/basilbourque/Desktop/real_now/real_now.fcgi
Tip: I moved my built app "real_now" to my Desktop folder for convenience. 
(3b) You can verify the web app is running by finding its name in the "Activity Monitor" program on your Mac, or equivalent in other platforms. You may need to select "All Processes" from the popup menu that filters the list.

Later, to stop this process, press Control+C in the same Terminal window. There must be a more graceful way to shutdown a web app, but I'll look into that later.

(4) Test Tomcat by pointing your web browser to:
Hopefully you will see your web app!

Next challenge is to wrap my head around the URL mapping. Currently I am using "/*" in the tag above. The asterisk is a wild card. So that pattern means any and every url goes to my REAL Studio web app. That is not practical. Only some URLs should go to the web app, while others will go to static web files, Java Servlets, etc. I tried using other URL patterns, but could not get it to work correctly.

Lastly, for most real-world deployment, we would want to add SSL/TLS encryption to the web browser interaction. Tomcat certainly supports that. But that chore will wait for another day.

6 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. Just stumbled across your post. With everyone on RealSoftware forums beating their heads against the wall trying to get a fastcgi webapp working in Apache under Windows, I thought this might be worth a try via Tomcat. I already had tomcat running for another purpose so this turned out to be very easy! Just followed the steps as written, except for Windows, needed click on real_now.fcgi.exe to execute it. Now I can see my first RealBasic webapp works! Great post! Thanks Basil. Let us know if you make progress on the mapping and deployment. Happy New Year

    ReplyDelete
  3. Hi Basil,
    Thank you for this post. I have been beating my head against the wall on trying to get RB apps to run under different environments. This was going to be my last ditch effort before I aborted RB for more traditional method. And it works! Now moving on to see how a more complicated app runs. You are the best! Cheers!

    ReplyDelete
  4. This works, but I still get high utilization showing on the VPS with my 5 page app. Basically at the same point, but nice try. I am going to have to abort and revisit this later. Project must go on. Thanks.

    ReplyDelete
  5. like the post and all the info...I really like you share it.

    Church Software

    ReplyDelete
  6. Found this while looking for something else, and I have to say, this is really really cool.

    As a comment to anyone who would be trying to do the above and wants to avoid sending all requests to java: if you're using apache or nginx etc., you could use url rewriting and use an extension such that everything with a .jwp or whatever is handled by the fastcgi, and everything else would be handled using business as usual.

    ReplyDelete