Tomcat Configuration Trickery

Posted 1195 days ago

Say you're working on a handful of different web application projects using one installation of Tomcat; it's very likely that you need different resources, settings, and runtime parameters per project - and as a consequence of such it's very likely that your tomcat configuration is a mess! Well no more, I say! What if you could have a distinct set of configurations for each project you're working on?

Fortunately Tomcat makes this extremely easy. There are two primary locations that Tomcat works with, identified by and . is the location you installed Tomcat into -- in my setup, that's /opt/tomcat. is where it will look for configuration files and other "dynamic portions" (according to tomcat's documentation) of the server.

What we're going to do is create one per project (or one for just the projects you think require their own, anyway), and then configure tomcat to use the new TOMCAT_BASE.

The first thing to do is create a local tomcat directory structure in your project directory -- my project looks something like this:

  MyProject/
    docs/
    etc/
    src/
      java/
      test/
    tomcat/
      conf/
      logs/
      tmp/
      webapps/
      work/
MyProject/tomcat is going to be your .

You need to copy two files from /conf to /conf:

  • web.xml - Contains the default settings for all web apps deployed into .
  • server.xml - Contains the server configuration. For my web projects, i usually use server-minimal.xml file instead of the default server.xml, as it only loads the minimum amount of services needed to run a web application (which is usually sufficient for my hobby projects).

Once you have that done, your is ready for use. If you're launching Tomcat from the command line, you'll want to set the environment variable CATALINA_BASE to point to your TOMCAT_BASE directory (MyProject/tomcat). If you're launching Tomcat from XCode, you'll want to open your custom executable's properties, and add the following argument:

  -Dcatalina.base=../tomcat
Note: XCode appends arguments in order, so you'll want to put it somewhere before the argument that specifies the Bootstrap class to launch.

All that's left to do is start deploying your project's webapp to /webapps rather than /webapps, and you're good to go. Your project's instance of Tomcat will log to MyProject/tomcat/logs, use MyProject/tomcat/work for its working directory, and MyProject/tomcat/tmp for tmp space.

Why would you want to do this, you ask? Well first and foremost, cuz it's cool. Second, perhaps you have projects that really should be tested and run in isolation. Third, maybe you don't have the luxury of having multiple machines that you can run webservers on, and you need to test a multi-server setup - or test communications between applications on separate app-servers. For me, it's a configuration-location thing - it lets you keep project-specific server configurations in your project, where they belong.

Debugging Servlets in XCode

Posted 1195 days ago

So I've been struggling for a while with finding a way to debug web applications in XCode. The answer wasn't immediately obvious. I'm sure it would have been if I happened to have Apple's WebObjects, but I don't; just XCode. Well today I figured out how to do it -- you run Tomcat directly from within XCode!

Now before we get started, I want to point out that I realize there are pros and cons to doing this -- I'm going to save those for the end.

My setup

Here's the software I have installed to work with:

  • OS X 10.4 Tiger
  • XCode 2
  • Java 1.5.0 (also "Tiger")
  • Tomcat 5.5.9 (installed in /opt/tomcat)
I'm 99% certain this procedure will work using OS X 10.3, XCode 1.5, Java 1.4.2, and Tomcat 5.0.x as well, but I haven't tried it. If you try it, and it works, please let me know -- if your mileage varies and you want me to post instructions for that as well, please email me :).

Step 1: Creating a new project

If you already have a project you want to try this with - just skip to step 2.

If you don't already have an XCode project, now's the time to make it. I used the "Java: Ant Based Application Jar" project template in XCode. This creates a new project with an ant build script, and src and lib directories. Making yourself a nifty servlet that looks something like this:

import java.io.*;

import javax.servlet.http.*;
import javax.servlet.*;

public class javaplay extends HttpServlet {
  public void doGet ( HttpServletRequest req, 
                      HttpServletResponse res )
    throws ServletException, IOException
  {
    PrintWriter out = res.getWriter();
	
    out.println("Hello, world!");
    out.close();
  }
}

is a great beginning. You'll also want to make yourself a WEB-INF/web.xml file, like so:

<web-app>
  <servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>javaplay</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>
</web-app>

And then modify your build script a little bit a make the WAR. Mine is embarrasing, so I'm not going to show it to you. There's two steps though:

  1. Make a new target that creates a WAR and depends on "compile"
  2. Change the default target of your build script to call your new target.

Ok great, one last final step, grab your servlet-api and jsp-api jars and copy them into your projects "lib" directory. The build script needs these in lib to resolve against at compile time. Now go ahead and build your project to make sure it goes smoothly and generates the WAR as expected.

Had a problem, did you? That's okay... I'll wait till your done.

( ... jeopardy theme ... )

Step 2: Tying in Tomcat

This part's also very easy -- you're going to create a new executable target that starts Tomcat. My setup has Tomcat 5.5.9 installed into /opt/tomcat.

Right-click (ctrl-click) "Executables" under Groups & Files and select "New Custom Executable". Name it something meaningful, such as "Tomcat", and set the executable path to: /usr/bin/java. When you press "Finish" you'll get the "Executable Tomcat Info" dialog up. Go to the Arguments tab, and add the following set of arguments, in order:

  -classpath /opt/tomcat/bin/bootstrap.jar:/opt/tomcat/bin/commons-logging-api.jar
  -Dcatalina.home=/opt/tomcat
  -Xmx128m
  -Xms64m
  -Xincgc
  -Djava.awt.headless=true
  org.apache.catalina.startup.Bootstrap -debug start

Set your new target to be the active target, and run your project. You'll notice that your console output is Jakarta Tomcat starting up! Not too shabby, eh?

Step 3: There is no step 3

That's it. Just deploy your webapp to tomcat, start it up under XCode, and you're good to go. Give it a try, set a break point in your servlet code and hit the page through a web browser.

Conclusion

One thing I did to make my life easier in this setup is to make my default ant target automatically deploy the WAR file to my tomcat directory. That way when I hit "Build & Debug", it builds, deploys, and launches tomcat in my debugger.

Well I hope you found this helpful. I know I keep having to go back to using IntelliJ IDEA for my servlet based projects up until now I haven't been able to figure this out. I'm still looking into getting the XCode debugger to hook up to a remote Tomcat session, and I'll be posting info about that soon (I hope). If anyone out there has info on doing that, please get in touch with me.

About

My name is Tim Fanelli, I am a software engineer in Northern NY. I spend most of my time working, and when I can, I try to post interesting things here.

Cigar Dossiers