JServ for me represents the best-value servlet engine on the market today. "Why?" I hear you ask. Well, that's easy. It's free, of course. To this day, the fact that I can download the Apache Web server and JServ for Linux and have the beginnings of an excellent enterprise server for nothing surprises me. And why anybody would use any Web server/servlet engine combination other than Apache/JServ escapes me. "What about the lack of support?" the voices cry out. Is that a real reason? I'm not convinced, but I've heard lots of remarks on the "difficulty" of setting up JServ with Apache on Linux. This article provides a step-by-step guide on getting JServ up and running.
We'll start by looking at how to install JServ and how to test the setup of the installation. Then I'll explain some of the more advanced configurations that can be applied to the product. This article won't be a comprehensive investigation into JServ - that would take a book - but I'll cover the more popular configurations that developers use.
Installation and Configuration
Before you start, I can't stress strongly enough how much a logical and clear directory structure on your Linux installation helps. Many times I've tried to fix an installation of JServ and have wasted 20 minutes finding where it was installed in the first place. Having Apache installed under /usr/local and JServ installed under /var/etc makes no sense, does it?
Let's start nice and agree on where we're going to install our applications. For me it'll be /usr/local; for you it could be somewhere else, as long as it's consistent.
To run JServ you need the Apache Web server and, of course, JServ itself. JServ and Apache are both available for download from the http://www.apache.org/ and http://java.apache.org/ sites. Keep these sites bookmarked as they provide an excellent reference point for help when things aren't going too well. When you're choosing which files to download, you'll have to decide between the source distributions or the binary distributions.
I personally like to have a lot of control over what goes on in my system, so I generally choose the source distribution. It means more work in configuring and compiling each application, but I find I learn far more about an application than I would from installing the binaries. For this reason, within this article I'll discuss installation of the source distributions for both Apache and JServ.
You need to install Java on your system and you can download a Linux port of Java from Sun's site, http://java.sun.com/, or you can get a port from www.blackdown.org. I find the guys at Blackdown have slightly better documentation for installing Java on your Linux system as they deal with Linux exclusively.
You'll also need the jsdk.jar (the Java Servlet Development Kit), which can also be downloaded from Sun's Java site. Remember to place this JAR file in a logical place on your file system. I like to set up a specific directory just for Jar files - say, for example, /home/jarfiles/.
Once you've downloaded the necessary archive files - for example, apache_1.3.12.tar.gz and ApacheJServ-1.1.2.tar.gz - they need to be untarred into a temporary directory for configuring and compiling.
Remember, these archives represent the source of the applications, not the applications themselves, so why have them cluttering up the applications directory? I'm going to untar them in /usr/src. It's close enough that I won't have to do too much moving around while installing, but far enough away that I can happily delete it after installing the application without losing any files required to run it. You may want to keep the source, of course; it'll come in handy if you want to compile other modules into your Apache Web server at a later point.
tar -xvzf apache_1.3.12.tar.gz
tar -xvzf ApacheJServ-1.1.2.tar.gz
After untarring both files we now have the directories /usr/src/ apache_1.3.12/ and /usr/src/ApacheJServ-1.1.2/ packed full of the source files necessary for building the applications.
Hurray! We're now ready to start building the two applications.
We'll build Apache first; this needs to be done if you've never had Apache compiled on your system before. So we go into the Apache directory.
We're now going to run the Apache configuration script. We''ll do this with a minimum of parameters, just passing in the path we wish Apache to be installed in. When we compile it, we use the --prefix= option to specify this path. As stated previously, I want my applications installed in /usr/local:
And that should be that. Apache is preliminarily built.
Now we need to go into the JServ directory to carry out a similar operation. Let's get into the correct directory:
We have to run the configure script in this directory, and for this we need to pass in more parameters. These parameters will tell JServ where various resources have been placed on your system.
We need to know where the Apache source has been placed if we're going to build the Web server:
JServ also needs to know where the JDK (Java) has been installed. The JDK_HOME and JAVA_HOME environment variables will be looked for and used as default if this isn't specified. If these variables don't exist, the PATH environment variable will be looked for:
If the servlet classes in the form of the jsdk.jar aren't in your CLASSPATH environment variable, we'll need to specify where these classes are:
We also need to tell the configuration where to install JServ when we build it:
Now we run the configure script with these parameters:
./configure --prefix=/usr/local/jserv --with-apache-src=/usr/local/apache_1.3.12 \
This should successfully configure JServ for us.
We now need to compile and install JServ by running the "make" command. This compiles all the source code binaries, but it doesn't install the application. To install we need to run the "make install" command. This takes the binaries created by "make" and installs them in the directory we specified with the --prefix option in the configuration script. We can run both of these commands together:
make; make install
Congratulations! You now - hopefully - have JServ installed. If you have any errors, read the output from the "make" and the "make install" commands carefully to see if it identifies the problem. If it doesn't, check carefully that the parameters you passed into the configure script were correct. If you installed successfully, you'll see some instructions printed to the screen; follow them as closely as possible. The next step is a slightly more in-depth explanation of these instructions.
We now need to compile and install Apache just as we have for JServ. We do this in the same way; we run "make" and "make install," but this time we do it from the apache directory:
Once again, "make install" should install the application in the directory specified in the --prefix option in the Apache configuration script.
make; make install
Hopefully, Apache will now be installed in the /usr/local/apache directory. However, did your make fail? If it did, try the following:
Is the mod_jserv.c file there? If not copy it from /usr/local/ ApacheJServ-1.1.2/src/c/mod_jserv.c into /usr/local/apache_1.3.12/ src/modules/ jserv/mod_jserv.c
Go to the /usr/src/apache_1.3.12/src/ directory and edit the "Configuration" file. Add the following line to it:
Save this file, and from the /usr/src/apache_1.3.12/src/ directory run:
This should ensure that the JServ module is compiled and installed when we try to "make; make install" again. Now go back to the Apache source directory:
Run "make" and "make install" again".
make; make install
You should see the glorious sight of a message telling you that you have successfully installed Apache.
The next thing is to add a line to the Apache configuration file "httpd.conf". Go to the directory you specified as your Apache installation directory (that was when you ran "./configure" in the Apache directory; remember the --prefix value?):
Now go into the conf/ directory:
Edit the httpd.conf file in this directory, adding the following line:
Save this file and go back up to the installation directory:
Now check that the mod_jserv module has been added to Apache:
Look for mod_jserv.c in the list this returns; if it's there, hurray! If not, check the steps you've already done, paying particular attention to variables being passed into the configuration scripts.
Now try to run the Apache server:
Hopefully you'll get a nice little message "httpd started".
Now stop the server:
Edit the file /usr/local/jserv/etc/jserv.conf, and look for the following text:
Change this to:
deny from all
allow from 127.0.0.1
deny from all
allow from all
This change allows us to check the system status from a browser running from a different IP address than the Web server.
Start the Web server once again.
Once you've completed the steps above, check the system status. The easiest way to do this is to surf to the JServ test Servlet, the HelloWorld.class Servlet:
If you can't surf to this page, check the "zone.properties" configuration file in the /usr/local/jserv/etc/ directory, and make sure that it has a repository pointing to where the HelloWorld.class file is sitting. This will most probably be in /usr/local/jserv/servlets/.
To view how your JServ is set up in a friendlier fashion than viewing the configuration files directly, you can surf to:
From here you'll see a list of configured hosts and mapped servlet engines that are currently running. If you've kept to most of the default values in jserv.conf, the configured host will be "localhost" and the mapped servlet engine will be "ajpv11://localhost:8007". Follow the link from the mapped servlet engine through to the next page and you should be met with links to the "current status" and the "root". Follow each of these links and you should be met with the friendlier-formatted details that you've placed in the configuration files.
At this point you have JServ installed. By making small changes to this setup, you can now run your own servlets. The small changes involve the "zone.properties" file in the /usr/local/jserv/etc/ directory.
In this file there are lines similar to:
This line tells the servlet engine to look in the /usr/ local/jserv/servlets/ directory for class files to execute. If you want to execute your servlets, you need to add the directory in which you've placed your servlets to this file. For example, if I wanted to run servlets from /home/myclasses/, I'd add the line:
And there we have it. You have successfully installed and configured JServ and are able to run your own servlets. Congratulations!
Mount Points and Zones
I'd like to discuss mount points and zones for a bit. These are key areas you should know about if you want to carry out some advanced configuration of JServ.
What is a mount point? It's a virtual file space on the Web server that servlets can be called from. Still not clear? Well, let's go through it with some examples.
You already have a couple of mount points set up in your installation of JServ. If you look in the "jserv.conf", which is in the directory /usr/local/jserv/etc/, you'll see the directives:
ApJServMount /servlets /root
These directives are creating two mount points, both pointing to "/root". So what does this mean? Simply that two virtual file spaces have been created:
ApJServMount /servlet /root
Okay, so what does this do for me? Remember when you ran the test servlet HelloWorld? You surfed to:
and the IsItWorking Servlet was executed. You can go to:
and you should see the same page that you saw from the previous URL.
How does this work? Well, if you look at the "jserv.conf" file once again, you'll see that the two mount points, "/servlets" and "/servlet," are both mapped to "/root." This "/root" is what is called a zone.
Just as a mount point is where a servlet is called from, a zone is where a servlet resides. The mount point has no concept of where to get a servlet from on its own. It requires a zone to hold the information pertaining to where the servlet is sitting on your system.
When we looked at the "zone.properties" file earlier, we were looking at the configuration file for the "/root" zone. This contains all the information needed for a servlet to execute - specifically, where the class files are on the system. The directive that controls this is the "repositories" directive I discussed above - a list of paths to the class files required for execution.
So we have our mount point and we have our zone, and through the zone we know where to find our servlets. We now need to link the two.
Linking Mount Points and Zones
To do this we have to look at the "jserv.properties" file that's also in the /usr/local/jserv/etc/ directory. This file contains a fair amount of information, but the part we're interested in here is the zone parameters.
Go through the file until you see the directive below:
This directive lists the available zones to be mapped onto mount points in the "jserv.conf" file. At the moment we only have the "root" zone mapped; if you added any more, you'd just create a comma-delimited list of zones. For example:
We now need to tell the servlet engine where to find the configuration files for these zones. You'll see the following line:
This tells the servlet engine where and in what file a zone's configuration is kept. The syntax is:
As you can see here, the file name doesn't need to be the same as the zone name. I like to keep them the same as it makes it easier for someone else who might need to investigate your system.
Now we have the "/servlets" and "/servlet" mount points set up; both point to the "root" zone. This zone is named and the path to the properties file containing the information for this zone has been specified in "jserv.properties".
Now the servlet engine knows which servlets can be executed from which mount points and, through each zone, where to find the class files to carry out the execution of these servlets.
Adding Mount Points and Zones
A time may come when you want to add your own mount points and zones. After the discussion above, I don't think you'll have problems, but let's take a step-by-step look at it.
The first thing you need to do is add the mount point and zone to "jserv.conf", so add the line:
ApJServMount /murray /muz
Tada! You've now created a mount point and pointed it to a zone that doesn't exist at the moment. So you have to create it. Open up "jserv.properties" and go to the list of zones. Add your zone to the list of those available:
Now let's point this zone to the correct configuration file for it. Add the following line to "jserv.properties":
We now have our mount point set up: it knows which zone it's connecting to, and it knows where to find the configuration file for that zone. Now we have to create this configuration file.
Make a copy of "zone.properties", renaming it "muz.properties". Remove all the "repositories=" directives from this file - we're not going to use any of the paths that the "root" zone is using. Let's say, for example, I had a servlet "MurraysExample.class" sitting in a jar file. I have created "application.jar", which in turn is sitting in my JAR files directory, /home/jarfiles. Now we create the repository directive for this class:
Note that as the class file is in a JAR, I have to specifically name the JAR. If it had been in the directory, I could have put:
And that's that. You have successfully added a new mount point and zone. You can now (if the class file actually existed) surf to the following URL to execute the servlet:
Actions Based on File Extensions
With JServ we can tell the Web server to pass any files with a certain extension through the servlet engine before passing it on to the browser that initially requested the page. We do this by using the "ApJServAction" directive, the syntax of which follows:
ApJServAction <file extension> <Servlet mount point/Servlet within that mount point>
If we want to activate the servlet "pageServlet" that resides in the "root" zone each time we come to a page with the file extension ".serve", we check which zone the servlet is in, "root", and then check which mount point this zone is mapped to, "/Servlets", as follows:
ApJServAction .serve /Servlets/pageServlet
So every time we come to a .serve page, we activate the "pageServlet" servlet in the "root" zone from the "/Servlets" mount point.
Passing Parameters to Servlets
We may wish to pass a parameter into a servlet or group of servlets, which is achieved by using the default arguments directive in the relevant zone file. The syntax is:
servlets.default.initArgs=<variable name>=<variable value>
This is the default init arguments directive. Say we need to pass in the name of the directory where we have application-specific initialization files. Our directive could be:
We can now install and configure JServ, we can add different mount points and zones to extend the functionality of our JServ installation, we can even send files with certain extensions through the servlet engine before the Web server serves the page.
What's left to do? The first thing I'd mention is that this article doesn't cover security. Each area discussed here - Apache, JServ, JServ zones - has security considerations, all basically dealing with who can access what on a particular server.
Some smaller aspects you may want to look at are the different logging parameters that can be configured. I personally have had no problem with the default settings in "jserv.properties" so I won't try to convince you to do something I haven't done.
Don't be afraid to play with JServ. It's not your enemy, it's your friend. Go through the configuration files and read the documentation on the Apache Web site. Most of it is very clear and useful. But the best way to learn is to change the settings and go through the configuration files with an attitude of "What will happen if I do this?"
I won't say Hack JServ, but please don't be afraid to at least fiddle.
Murray Wilson, a software developer with n-ary (consulting) ltd, is one of only a few developers who began their careers with Java. He has spent the last 18 months on a number of high-profile e-commerce projects, where he quickly learned that coding Java was only half the job. He can be contacted at: [email protected]