DæmonNews: News and views for the BSD community

Daemon News Ezine BSD News BSD Mall BSD Support Forum BSD Advocacy BSD Updates

Jakarta-Tomcat on FreeBSD 4.4

Adrian Thiele <athiele@abraxis.com>

The Java platform is a great way to display dynamic web content. Java is becoming the most popular way to handle CGI tasks. Yes, I understand you were not impressed with applets since most were slow and not very useful. Servlets and Java Server Pages are the power behind today's web applications and they do run on FreeBSD.

If you're like me, you don't always have the luxury of working on FreeBSD. Often the client uses a Windows based operating system, Linux, or some other form of UNIX. This can create problems. Fortunately, Java is really starting to meet the "write once, run anywhere" promise. In this article I will introduce you to Java Web applications on the FreeBSD platform.

So what exactly are Servlets and Java Server Pages? Servlets are small Java programs and are a better way to handle CGI tasks such as dynamic content and database interaction. Servlets run inside the Java Virtual Machine, which handles threads for each new request instead of the per instance model of traditional CGI programs. Servlets are able to take full advantage of the Java language, eliminating buffer overrun problems as well as providing clean database interfaces through JDBC. Java Server Pages and Servlets also do not require a Java capable browser. All processing is done on the server.

Java Server Pages are Sun's answer to Active Server Pages. JSP's use embedded code, translated on the server, to help display dynamic content and leverage the power of Java beans. Tomcat preprocesses JSP's, and creates Servlets.

So, what is Tomcat? Tomcat is The Apache Group's reference implementation of a Servlet engine. It can handle both Servlets and JSPs. Tomcat can be run in stand-alone mode or with a HTTP server, such as Apache. For this article, I'm only going to concentrate on Servlets with Tomcat in stand-alone mode. In the future, we'll cover more functionality.

To run Tomcat you need to install a JVM. I really like Kaffe from Transvirtual, but it requires a little tweaking to work properly with the latest servlet spec. The official version of Sun's JDK on FreeBSD is version 1.1.8. To keep up to date, I recommend using a more recent version of Java. The FreeBSD Foundation has secured a license to distribute a native build of the J2SDK. It was supposed to be available with the release of 4.5. Hopefully it will be soon. Until then you have to roll your own. According to the EyesBeyond web site, the patches should allow it to build on NetBSD. I have not tried it. If you have trouble building the native FreeBSD version, or you simply don't want to, you can run the GNU/Linux version under emulation. I have done this on FreeBSD and NetBSD. I assume it will also work under OpenBSD.

First download the the J2SDK source code. It's available from Sun at http://java.sun.com. For this article I am using j2sdk-1_3_1-src.tar.gz. Don't even try to build it without Greg Lewis' patches, available at http://www.eyesbeyond.com/freebsddom/java/jdk13.html. Get the latest patch, level 6. You also need a Java 1.3 compiler to bootstrap the process. Go to http://www.blackdown.org and get the latest GNU/Linux version, I'm using j2sdk-1.3.1-FCS-linux-i386.tar.bz2. To prepare FreeBSD you need to add Linux binary compatibility. The easiest way to do this is to insert disk 1 of the FreeBSD CDs and from the command prompt type:

	/stand/sysinstall
This will launch the installation/configuration program. Select Configure "Do a post installation configuration" then choose "StartUp" and select Linux Compatibility. The install program will install the Linux package and write to the /etc/rc.conf file for you. You also need to add the Open Motif 2.1.30. It is available on the CD set or in the ports collection. In addition, make sure you have, GNU m4 1.4, zip 2.3, gmake 3.79.1 and gtar 1.13.22 installed. You must have these installed or it will not build. For some reason, the regular tar extracts the files incorrectly. Gmake is required to build the J2SDK.

To increase the performance, I also recommend installing a just-in-time compiler. There are several available. I'm using OpenJIT from http://www.OpenJIT.org. The file name is OpenJIT-1.1.6.tar.gz. The JITs in the ports collection are setup to work with FreeBSD's JDK 1.1.8. It's best to build a new one.

Installing the Linux J2SDK

There is no real trick to installing the Linux Java 2 package. For this installation I'm going to use /usr/j2sdk1.3.1. Copy the file j2sdk-1.3.1-FCS-linux-i386.tar.bz2 to /usr. If you are not familiar with bzip2, it's just another form of compression utility like gzip. Use the command:

	bunzip2 j2sdk-1.3.1-FCS-linux-i386.tar.bz2
	tar -xvf- j2sdk-1.3.1-FCS-linux-i386.tar
Now just add /usr/j2sdk1.3.1/bin to your path. If you are using Bash shell and want to test the installation, type:
	export PATH=$PATH:/usr/j2sdk1.3.1/bin .
Try to run java with:
	java -version

You will probably get an "expr error" before the output. This is normal. This is also why we are building a native port.

Setting Up The Build Environment

Create a build directory. I use /usr/bsdjava. Place the j2sdk-1_3_1-src.tar.gz and bsd-jdk131-patch-6.tar.gz file in the directory.

Extract the source with:

	gtar -xvzf j2sdk1_3_1-src.tar.gz
Then the patch with:
	gtar -xvzf bsd-jdk131-patch-6.tar.gz 
It is very important you use gtar to extract the source files. If you do not, the files will not extract to the proper locations and it will not build.

Before applying the patch, you need to create some additional directories. From the /usr/bsdjava directory. Execute:

	chmod -R u+w *
	mkdir -p hotspot1.3.1/build/bsd
	mkdir -p hotspot1.3.1/build/bsd/makefiles
	mkdir -p hotspot1.3.1/build/bsd/package
	mkdir -p hotspot1.3.1/src/os/bsd/launcher
	mkdir -p hotspot1.3.1/src/os/bsd/vm
	mkdir -p hotspot1.3.1/src/os_cpu/bsd_i486/vm
	mkdir -p j2sdk1.3.1/ext/plugin/oji-plugin/include/bsd/jdk12
	mkdir -p j2sdk1.3.1/ext/plugin/oji-plugin/include/solaris/navig5/private
	mkdir -p j2sdk1.3.1/src/bsd/doc/man
Apply the patch from /usr/bsd/java with:
	patch < jdk1.3.1.patches
Set the following variables, for the Bash Shell:
	export ALT_BOOTDIR= /usr/j2sdk1.3.1
	export ALT_MOTIF_DIR= /usr/X11R6
	export OPENWINHOME= /usr/X11R6
	export BUILD_CLASSIC= yes
	export JAVA_COMPILER=NONE
If you have previously set the environmental variables CLASSPATH or JAVA_HOME, unset them before building.

Building

The most stable build uses green threads. I have not had good luck with the native threads. To start the build:

	cd /usr/bsdjava/j2sdk1.3.1/make
	gmake
It's going to take a minute to compile. On my 900 megahertz system with 256MB of RAM, it takes about fifteen minutes.

After that completes, execute:

	gmake images
to get a final build image. This only takes about five minutes. You may notice the HotSpot directory. This is Sun's optimized compiler. It falls in the "not ready for prime time" category. I had no success building it.

Installing

In the /usr/bsdjava/j2sdk1.3.1/build/bsd-i386 directory you'll find several subdirectories. The jdk-image-i386 directory contains our final product. Go ahead copy the jdk-image-i386 directory to /usr, giving you a /usr/jdk-image-i386 directory. Before we delete the Linux version,test the BSD version by running some of the demos. Change directory to /usr/jdk-image-i386/demo/jfc/SwingSet2.

Execute:

	/usr/jdk-image-i386/bin/java -jar SwingSet2.jar
If it runs okay go ahead and delete the GNU/Linux install with:
	rm -r /usr/j2sdk1.3.1 . 
Then move the jdk-image-i386 to j2sdk1.3.1 with:
	mv /usr/jdk-image-i386 /usr/j2sdk1.3.1
Now the native build is in your path.

Try it out with:

	java -version
You should see the build as "Classic VM (build1.3.1-p6(time stamp), green threads, no jit)".

Just In Time Compiler

In order to speed up execution time, a just in time compiler will translate Java bytecode into machine code on the fly. None of Sun's JITs have been ported yet, but third party products are available.

OpenJIT is available from http://www.openjit.org. It is real easy to install. Use the latest version 1.1.6. Download it to /usr/bsdjava with the other files.

Extract it in /usr/bsdjava directory with:

	gtar -xvzf OpenJIT-1.1.16.tar.gz 
Set JAVA_HOME:
	export JAVA_HOME=/usr/j2sdk1.3.1
Add it to your .profile file as well. If you're using csh set JAVA_HOME with the command:
	setenv JAVA_HOME /usr/j2sdk1.3.1
Add to your .cshrc file.

Change directory to /usr/bsdjava/OpenJIT-1.1.16 and execute:

	./configure
then:
	gmake ; gmake install
One last environment variable to set:
	export JAVA_COMPILER=OpenJIT
Go ahead and add it to your .profile file as well.

Test it to make sure it's installed with:

	java -version
You should see:
	Classic VM (build 1.3.1-p6-root-020221-19:31, green threads, OpenJIT)

Tomcat Installation

Next, download Jakarta-Tomcat from http://jakarta.apache.org. Get the binary to start. Remember this is Java so the binary will work on FreeBSD. Sources are also available if you want to roll your own. I used jakarta-tomcat-4.0.2.tar.gz. If you get a newer version, make sure to check the documentation for changes. Extract the tarball. I put mine under /usr.

	tar -xvzf  jakarta-tomcat-4.0.2.tar.gz
If you want to, you can put the jakarta-tomcat/bin directory in your path and/or startup files.
	export JAVA_HOME=/usr/j2sdk1.3.1
 	export CATALINA_HOME=/usr/jakarta-tomcat-4.0.2
This will help Tomcat find your Java classes it needs to run.

While you have the .profile open, add the CLASSPATH variable so you can compile your servlets. Add this line:

	export CLASSPATH=/usr/jakarta-tomcat-4.0.2/common/lib/servlet.jar
The location of the servlet jar has changed in Tomcat 4. In previous versions the servlet jar was in JAKARTA_TOMCAT_HOME/lib.

Running Tomcat

Test the installation by changing directory to the jakarta-tomcat-4.0.2/bin and type:

	./startup.sh
If you get a bad interpreter error, you need to run
	chmod +x *.sh
(For production machines set executable permissions accordingly.)

Point your browser to:

	 http://localhost:8080
You should see the Tomcat home page with several examples of both Servlets and Java Server Pages. As I mentioned earlier, Servlets and JSPs do not require a Java capable browser.

To stop Tomcat just run:

	/usr/jakarta-tomcat-4.0.2/bin/shutdown.sh

Writing Servlets

A little bit of Java knowledge is required to make your own servlets. There is no shortage of quality Java books and tutorials available. I'm going to do a couple of simple examples that you should be able to follow with little to no Java experience.

The first Servlet, is going to be the traditional type of "Hello World" example, with a twist.

Call the file Hello.java and save it under the /usr/jakarta-tomcat-4.0.2/webapps/examples/WEB-INF/classes.

Remember Java is case sensitive,and the filename and classname must match!

We'll walk through the first example, which can be downloaded here.

	//The import statements are for java classes needed by the Servlet.
	import java.io.*;
	import javax.servlet.*;
	import javax.servlet.http.*;
	
	//The file must have the same name as the class declaration. Extends shows inheritance.
	public class Hello extends HttpServlet {
			
		//The method doGet is overridden from the super class HttpServlet
		public void doGet(HttpServletRequest request, HttpServletResponse response) 
			  throws ServletException, IOException {
	
			//Output type is set to text/html
			response.setContentType("text/html");
	
			//Here we output simple html
			PrintWriter out=response.getWriter();
	
			String daemon = "Daemon News Reader";
	
			out.println("<HTML><BODY>"); 
			out.println("<TITLE>Hello " +daemon+" </TITLE>");
			out.println("<B> Hello " + daemon +"</B>");
			out.println("</BODY></HTML>");
		}
	}
As mentioned before, save the above as Hello.java. To compile our servlet, from the same directory:
	javac Hello.java
If you did not set your CLASSPATH variable, use:
	javac -classpath /usr/jakarta-tomcat-4.0.2/common/lib/servlet.jar Hello.java
If you installed Tomcat somewhere else, make the appropriate adjustment to the -classpath.

Now test the servlet by pointing your browser to:

	http://localhost:8080/examples/servlet/Hello
You should see "Hello DaemonNews Reader"

A quick description of the Tomcat directory structure. The webapps directory is where you store all of your work. If you look at the subdirectories just below webapps, you'll notice that they conform to the same basic structure. WEB-INF holds all of the servlets in the classes directory. If you noticed in the above example it's "examples/servlet/Hello" not "examples/servlets/Hello". This is because you are calling a "servlet" not the servlets directory. Makes a little bit of sense.

Not a real exciting example, but you see how it works. The next example will show a servlet as a CGI replacement. Create the file getname.html, a simple form to ask for the user's name. You can download it here. Place getname.html in the TOMCAT_HOME/webapps/examples directory. If you look at the HTML code you will see it makes a call to HelloName. You can get it here. The main change from Hello is the line

	String daemon = request.getParameter("name");
The getname.html passes the parameter "name" to the servlet. Try it by pointing your browser to:
	http://localhost:8080/examples/getname.html
Now the servlet returns "Hello" and the value passed as "name". HelloName is also capable of being accessed just like the Hello servlet.
	http://localhost:8080/examples/servlet/HelloName
You should see the same "Hello DaemonNewsReader" message.

The last example, HelloDaemon3 combines all the above functionality with the HTML form in one file. Download it here.

HelloDaemon3 checks to see if the "name" parameter is passed, if not, it provides the form inside the servlet. If the name parameter is passed, it displays "Hello" + name.

Access the page with:

	http://localhost:8080/examples/servlet/HelloDaemon3
That's just a quick introduction to Tomcat and Servlets. I didn't even scratch the surface of what is possible with either one. The Java platform is an exciting way to develop applications for the Internet. Best of all, it runs on BSD!

Here are some great resources for information on Tomcat, servlets and Java on FreeBSD.

The Home of Java on FreeBSD
    http://freebsd.org/java

Greg Lewis' site for FreeBSD Java patches
    http://www.eyesbeyond.com/freebsddom/java/jdk13.html

The home of the Jakarta project including the Tomcat servlet engine.
    http://jakarta.apache.org

Jason Hunter's site for all things servlet.
    http://www.servlets.com

O'Reilly publishes the "Java Servlet Programming" book by Jason Hunter and William Crawford.
    http://www.oreilly.com/catalog/jservlet2/

Home of the open source Java virtual machine Kaffe.
    http://www.kaffe.org

Sun Microsystems home for Java.
    http://java.sun.com

The Linux port of Sun's JVM.
    http://www.blackdown.org

Google
Web daemonnews.org

More Articles
  • Interview with Jan Schaumann
  • Interview with Theo de Raadt
  • Book Review: Virtualization with VMware ESX Server
  • Editorial: Not Quite Dead Yet
  • The Design of OpenBGPd
  • Interview with der Mouse
  • Letter to Steve Jobs
  • Interview with Manuel Bouyer on Xen
  • Apple and Open Source
  • BSDCan 2006
  • BSD Certification Survey Results
  • Lab in a Box
  • Ike Notes on BSDCan 2005
  • BSDCan 2005 Photos
  • FreeBSD Developer Summit Pictures

  • Advertisements




    Author maintains all copyrights on this article.
    Images and layout Copyright © 1998-2006 Dæmon News. All Rights Reserved.