|
Connecting Apache to Tomcat
Since Apache is the world's most popular webserver, and Tomcat is the world's least expensive java application server, I would assume that a lot of people would be trying to use them together, especially since the Jakarta web site tells you that Tomcat's built-in web server is not really meant for deployment. Unfortunately, the process of actually getting these two products to work together has given me no end of grief, and the pages the Apache/Jakarta folks have put together explaining this process never have worked for me. Perhaps it's because they change the entire connector scheme for every new version of their products. Argh. Anyway, here's a description of how I got Apache and Tomcat to work together. I'm sure this description won't be any more universal than the other pages you've found on this, but since none of those helped me make it work, I at least hope this page fills a void. My ConfigurationWhat I actually got to work: First Successful Try: Apache HTTP server 1.3.26 mod_ssl 2.8.10 Tomcat 4.0.4 App Server SuSE Linux 8.1 kernel 2.4.19 mod_jk 1.2.5 connector Second Succesful Try: Apache HTTP server 1.3.26 mod_ssl 2.8.10 Tomcat 5.0.16 App Server SuSE Linux 8.1 kernel 2.4.21 mod_jk2 connector (bundled with Tomcat 5.0.16) Apache Portable Runtime (apr) 0.9.4 I read some places that the jk2 connector wasn't meant for Apace 1.3.x, but I got it to work. I looked into migrating to Apache 2, but it didn't look doable. The majority of users (and mail-list/howto/help) posts I've found suggest that unless you love pain, don't bother going to Apache 2 yet (Dec03). Also, how https support is handled in Apache 2 is not clear to me. Mod_ssl still seems to be geared toward 1.3.x. Sadly, I think you're in for pain regardless of which way you go if you're set on using Apache and Tomcat, but hopefully I can help. The Steps1) First, get the source and/or rpms. This isn't an Apache or Tomcat install howto, so I'll assume you have both of those working fine by themselves, and your problem is just connecting them transparently, so that Apache is dispatching all JSP requests to Tomcat withouth the client being aware of the dual-headed server. 2) I would recommend getting source for the Tomcat version that matches your installation, even if you installed Tomcat with binaries. You probably could just get the connector source, but that's not what I did for my second configuration, so that's not how I'm writing this howto. Again, in my case, that was Tomcat 4.0.4 first, and then 5.0.16. First Configuration (Tomcat 4.0.4 / mod_jk)3) For this, I did use the separate source distribution for Tomcat JK connectors: jakarta-tomcat-connectors-jk-1.2.5-src cd /usr/src/jakarta-tomcat-connectors-jk-1.2.5-src/
4) Use the configure scripts to configure your build: ./buildconf.sh
It should be noted that the docs recommend adding this to your configure flags: --enable-EAPI
This parameter is needed when using Apache-1.3 and mod_ssl, otherwise you will get the error message: "this module might crash under EAPI!" when loading libjk.so in httpd. I didn't do it, and don't quite remember why not, since I am using Apache 1.3 and mod_ssl. But, I never saw any problems ... just thought I'd let you know. 5) Then, build the Apache connector module: make
Make sure /usr/lib/apache is actually where you have the mod*.so files for your httpd installation. 6) Next, you have to alter the Apache httpd.conf file for loading the new module. I have to assume the process of module loading into Apache isn't a new subject. Otherwise, consult the Apache httpd docs on Modules. Here are excerpts from my httpd.conf file: #LoadModule jk_module /usr/lib/apache/mod_jk.so #AddModule mod_jk.c Then, in my VirtualHost section for the secure website, I include a file where I keep all the JSP specific settings I want. You could of course keep them right in httpd.conf, but it makes more sense to me to keep these settings in the $CATALINA_HOME/conf folder where the other tomcat configuration files are. Include /opt/jakarta/tomcat/conf/tomcat_jk_ssl.conf
And finally, in the main section (http, not https) of httpd.conf, I have this include directive: Include /opt/jakarta/tomcat/conf/tomcat_jk.conf
Obviously, my Tomcat installation ($CATALINA_HOME) is /opt/jakarta/tomcat 7) Now, setup the tomcat_jk.conf files. Here you give directives to Apache on which tomcat webapp directories get which permissions, and what Tomcat applications (contexts) you wish to "map" or "alias" to the normal Apache HTTP URL space. Here is a look at my http file. The tomcat_jk_ssl.conf file is exactly the same, just pointing to those webapps which you prefer to only publish on your secure (https://my.domain.name.com) site. For obvious reasons, I'm not showing you exactly what my file looks like. # simple configuration for apache (for AJP connector, modul mod_jk.so) JkWorkersFile /opt/jakarta/tomcat/conf/workers.propertiesI won't explain all these settings. You can use the Apache/Tomcat docs for descriptions. Basically, the workers.properties file is where you specify the connection parameters for how Apache's httpd is to communication with the Tomcat server. The alias directives are needed so that the httpd doesn't tell you "File Not Found" when a client asks it for a file not under its not document base (e.g. /var/www/htdocs). There is no need to keep your Tomcat webapps under the same file root as the Apache normal HTML docs. For those context names (e.g. "/print" or "/examples" in my case) that are aliased, httpd will simple forward the request to Tomcat. Finally, the JkMount directive mount specific filenames (or wildcard filenames) to Apache. So both the context (ala a folder name) and the JSP filename are specified to Apache via this file. You can also use this file to specify restrictions on directory access just like you normally would for any folders served by Apache. For secure webapp folders, you might add lines like these to the AuthType Basic AuthName "Apache/Tomcat secure realm" AuthUserFile /etc/httpd/passwd/passwords8) Then, you have to activate the Tomcat side of the JK connector in the tomcat server.xml file: <!-- Define an AJP 1.3 Connector on port 8009 --> <Connector className="org.apache.ajp.tomcat4.Ajp13Connector" port="8009" minProcessors="25" maxProcessors="75" enableLookups="false" disableLookups="true" tcpNoDelay="true" acceptCount="10" debug="0" connectionTimeout="-1"/> This will make Tomcat listen on port 8009 for forwarded request from Apache httpd. 9) Finally, you have to make the settings match in the workers.properties file I mentioned earlier. I won't show you the whole file. Your Tomcat distro should give you a default version of the file. These are the lines I played with: worker.ajp13.port=8009
If Tomcat is on a different host than Apache, substitute that hostname for 'localhost' above. Mine were on the same server, so localhost did it for me. If the two are on different servers separated by a firewall, you may have more problems. Do some searching on the socket_keepalive property. I think that may help you: # worker ajp13 ask operating system to send KEEP-ALIVE signal on the connection worker.ajp13.socket_keepalive=1 10) Then, you should be ready to restart everything, and give it a shot! Second Configuration (Tomcat 5.0.16 / mod_jk2)3) This installation was a little different (worse), and I wound up making some mods to the very poorly documented process that the Jakarta folks give you. I made it look a little more like my previous 4.0.4 mod_jk configuration. Hey, it worked. 4) First, get the source (I got the source for all of Tomcat 5.0.16 in one bundle, including the jk2 connector. Also, jk2 requires the Apache Portable Runtime, which comes with the Apache 2 server, but not with 1.3. So, you'll need to go find a source distro of the Runtime, called apr. I used apr-0.9.4 and apr-util-0.9.4. 5) Untar the APR into /usr/src, or wherever you like to build stuff. Then build it. This didn't really work for me, but I'll show you what I did anyway.
cd /usr/src/apr-0.9.4
Then, do the APR util package.
cd /usr/src/apr-util-0.9.4
Then, you are left with some static libraries, named lib*.a* in the .libs subdirectory. I didn't wantto rebuild Apache from scratch with those static libs inside, so I really wanted shared object (so) files to load dynamically. However, the APR documentation is awful, and I couldn't quickly figure out how to build shared libs. My makefile only build .a files. So, what I tried was going into my apache 2 installation directory (I have it installed just for test purposes, not deployment) and I found some APR shared libs in there. They were a slightly older version, but I was hoping that wouldn't matter. The mod_jk2 code is what depends on APR, not vice versa, so I was hopeful that the versioning wouldn't be tighly tied together. It wasn't. I just copied the APR libraries into the Apache 1.3 modules directory:
/usr/lib/apache/apr.exp /usr/lib/apache/libapr-0.la
/usr/lib/apache/libapr-0.so.0.9.3
6) Then, you need to build the mod_jk2 connector, which depends on the Apache version, and APR version you're integrating with. So, you'll need to configure the connector source as follows:
cd /usr/src/jakarta-tomcat-5.0.16-src/src/jakarta-tomcat-connectors/jk/native2
Make sure that the version of apxs you point to is exactly the version that goes with the version of Apache your going to be using. I actually slightly mismatched this once (1.3.26 vs. 1.3.29) and it caused major breakage. Also, you may notice that I point to the APR 0.9.4 source tree even though I installed the shared libraries that I got from the Apache 2 install that had a 0.9.3 version. That could potentially be a problem, but it wasn't for me, so I didn't worry about it. Hopefully, the APR author has got enough stability in his interfaces that this isn't a big deal. But, if you want to, it would clearly be better to get the source that matches (if not 'produces') your APR share libs. So don't do like I did!! 7) After this, you should be set to do your build. Unfortunately, it doesn't look like this source gets a lot of testing before it's released, so I had to modify a couple of files to actually get the build to work. A couple script file permissions needed changing (chmod +x), and there were some compile errors, too. A couple of files had C preprocessor directive in them like this: #error "This file is deprecated"
Which causes the build to fail. I had no idea what to do to fix that, so I just removed the #error lines are recompiled. It worked. Deprecation usually isn't a show-stopper if you ignore it, so I just plodded on. Next, I got some errors in the Makefiles that the buildconf and configure scripts produce. First of all, there were malformatted library include lines that caused the following error:
/usr/local/java/jre/lib/: file not recognized: Is a directory
I had to change jakarta-tomcat-5.0.16-src/src/jakarta-tomcat-connectors/jk/native2/server/apache13/Makefile:
JAVA_LIB=-L ${JAVA_HOME}/jre/lib/${ARCH} -L ${JAVA_HOME}/lib/${ARCH}/native_threads
to
JAVA_LIB=-L${JAVA_HOME}/jre/lib/${ARCH} -L${JAVA_HOME}/lib/${ARCH}/native_threads
Basically, in case you can't tell, I just removed a couple of spaces after the -L instances. Then, the had to change Makefile.apxs in the same apache13 folder: mod_jk2.so: $(APXS) -c -o $@ -Wc,"${JK_INCL}
${APR_CFLAGS} ${APR_LDFLAGS}" "${JAVA_INCL}" ${C_FILES} ${COMMON_C_FILES}
I don't know why there are quotes in this line. They caused errors for my build, so I removed them (all the " chars). At last, you should do make
and verify the existence of a jakarta-tomcat-connectors/jk/build/jk2/apache13/mod_jk2.so file. Install this libary by copying it to your apache lib directory (e.g. /usr/lib/apache), and making sure the permissions are ok. 8) From here, the process gets similar to the first installation branch I described. In your httpd.conf file, add the LoadModule and AddModule lines as before, except that you replace mod_jk with mod_jk2. 9) However, since you have a new jk2 module that depends on the APR, you also need to load those libraries. Also, unless you build thread support into your Apache (which I didn't), then, you need to load the pthread shared library (that should come with your Linux distro). So, my httpd.conf file also has these lines, near the very start:
LoadFile /usr/lib/libpthread.so
If you don't have these, upon starting the httpd you will get loader errors that pthread, or apr symbols are not available. 10) The Jakarta Connector documents don't describe this, but I still choose to have a tomcat_jk.conf and tomcat_jk_ssl.conf file, to be included in the http and https VirtualHosts section of httpd.conf, as explained above. However, there may be some different syntax in these files for JK2, since the wonderful guys at Jakarta decided the old syntax wasn't good enough. Here's what my new tomcat_jk.conf file looks like: (as always, you could put this directly in httpd.conf, instead of Including it).
Alias /print "/opt/jakarta/tomcat/webapps/print"
This again defines the web application aliasing and Directory configuration properties. It also defines the worker connection properties to use for the *.jsp requests, which were defined in workers.properties for the older mod_jk configuration. 11) Also, you need a workers2.properties file, which bears no resemblance to the mod_jk workers.properties file. Here is mine. You notice the URI mapping lines:
#Map the Tomcat examples to the web server uri space
You can map the URI space with these lines, but since there is only one of these files, you need to map all your URIs in this file, including those for http/normal and https/secure VirtualHosts. By default this will make the JSPs available via both normal and secure web VirtualHosts, which may not be what you want. You need to explicitly go into your httpd.conf section for each virtual host (which is what I use my tomcat_jk.conf and tomcat_jk_ssl.conf files for), and explicitly allow and/or disallow each application. This is because the workers2.properties file will map URIs to all Apache hosts. You could use lines like these
<Location "/print/*.jsp">
in your tomcat_jk_ssl.conf (secure VirtualHost section). Unfortunately, if that's all you have, then thatLocation has no access control. I thought I'd be cute, and add the "AuthType Basic", etc. sections to a Location block like this, right after the JkUriSet directive. But unfortunately, the lame mod_jk2 code sees the Jk mapping directive for a given Location, and it will dispatch the request to Tomcat, even if the authentication fails! So, as far as I can tell, using the Location-JkUriSet method is only ok if you have no need to specify special options for that Location. This makes it unusable for restricted JSPs. 12) You should also check to make sure your settings are consistent with the jk2.properties file that ships in the $CATALINA_HOME/conf directory. View my file via the link here. 13) Finally, you need to activate the Tomcat JK2 connector in the tomcat server.xml file ($CATALINA_HOME/conf/server.xml). Here is a sample entry from my file:
<!-- Define a Coyote/JK2 AJP 1.3 Connector on port 8009 -->
Now, you should be able to restart everything and get the two servers talking. Hope this helps. |
|
![]() |
Copyright ©2003-2016 Enscand, Inc. All Rights Reserved Modified February 21, 2016 |
Privacy Security Environment |