Tomcat
Sorry, but you will fail to find much structure in this document. It is all kinds of tomcat findings and problems thrown together.
Note that all kinds of tomcat versions are used tomcat6/tomcat7/tomcat8. I leave those in because I know the section worked for that version.
As of July 2017, i focus on tomcat8 ! As of 2022 tomcat9
Setup
Add these lines to the file : /etc/tomcat8/tomcat-users.xml
| /etc/tomcat8/tomcat-users.xml | |
|---|---|
- manager-gui is for the management interface
- manager-status is for the server status page only
- manager-script is for plain text tools interface and the status page
- manager-jmx is for the jmx proxy interface and the status page
Just add all. This is the only line needed to get started, no extra roles or users.
of course, change at will with your own username and pass, then :
| restart | |
|---|---|
Logging
Ok, tired of not seeing a bloody thing in the logs accept GET /hello/ let's set EVERYTHING ON !!
| /etc/tomcat7/logging.properties | |
|---|---|
FINALLY i see something happening when running :
| catalina | |
|---|---|
Catalina.out is the logfile for the output of the main 'executable' tomcat itself. It will probably be your best guess. There is also /var/log/tomcat7/localhost-date.log that you might want top watch.
Let's start with ... problems :
autoDeploy
Next problem is the constant stream of messages about redeploying all servlets. It does that every 10 seconds and it clogs up the logs if you want it set to FINEST. There are in fact 2 solutions to this, disable autoDeploy or set the loglevel to FINE. See above for the second solution.
Edit /etc/tomcat7/server.xml and search for autoDeploy. Set it to "false".
404 : description The requested resource (/hello) is not available.
This is fantastically poorly documented. So here is what worked and what did not. A servlet with no package to keep it simple : ServletDemo.java :
So the class will be ServletDemo(.class) and the mapping should be set in webapps/hello/WEB-IBNF/web.xml :
| webapps/hello/WEB-IBNF/web.xml | |
|---|---|
Hoping this would work on url http://localhost:8080/hello it will not... it works on http://localhost:8080/hello/hello
So map a servlet-class with a url-pattern by matching the 'servlet-name' tag. Then you will have these combinations work/fail :
/hello
only works with :
| working url | |
|---|---|
All these will fail :
| failing | |
|---|---|
However, using this url :
/
Will work with all of the above/below :
| all working | |
|---|---|
| except all the others | |
|---|---|
To make it simple, use the latter, since it is the only format that will let your deployed file work with the tomcat interface itself. Notice that it will say /hello. So it will give a 404 error if you click on it unless you use '/'
directory tree
This tree is enough to get the above example running :
hello
└── WEB-INF
├── classes
│ └── ServletDemo.class
├── lib
│ └── servlet-api.jar
└── web.xml
project-name=hello
builder=kees klop
tomcat-manager-url=http://localhost:8080/manager/text
tomcat-manager-username=tomcat
Remember that tomcat operates on port 8080, and apache is on port 80. Just placing calls from apache javascript to tomcat will not work because it is regarded another url : x.x.x.x:80 -> x.x.x.x:8080 is just as forbidden as x.x.x.x:80 -> y.y.y.y:80
So you need to setup tomcat as an apache proxy to smooth that out, add a file called tomcat to /etc/apache2/conf.d with these contents:
```apache html title="config" linenums="1" LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so LoadModule proxy_ftp_module modules/mod_proxy_ftp.so LoadModule proxy_http_module modules/mod_proxy_http.so LoadModule proxy_connect_module modules/mod_proxy_connect.so ProxyPass /bag http://localhost:8080/bag ProxyPassReverse /bag http://localhost:8080/bag
Now these should give the same result
If you get this error.
| error | |
|---|---|
It means you forgot the other two modules as described above.
| add | |
|---|---|
I mention this because the tutorial i used did not mention those modules.
setup ant
If not already installed :
| install ant | |
|---|---|
And to take advantage of some ant tasks provides by tomcat, you need to make catalina-ant.jar reachable for ant so just copy it :
| get jar file | |
|---|---|
You will have to find these directories yourself, in my case it was :
| get jar file | |
|---|---|
development
Cannot skip to deployment until I have an application. So some hello world would be nice. I will be using ant, which has some aids in creating directories etc. But you will need a build.xml first.
| build.xml | |
|---|---|
View the build.xml and most importantly search for the catalina.home setting, it has to be set to your installation. I found mine by looking in /etc/init.d/tomcat6 , where it turned out to be /usr/share/tomcat6. After that running
| run | |
|---|---|
Will create some basic build directories for you.
The basic layout of a project directory should be :
``` project structure projectdir src doc web WEB-INF
I use the sample app as a base , so WEB-INF will be create automatically :
cd web
wget http://tomcat.apache.org/tomcat-7.0-doc/appdev/sample/sample.war
jar -xvf sample.war
compilation
First set some properties needed for compilation and deployment. You can do that in the file build.properties alongside build.xml :
<pre>
app.path=/hello
# Tomcat 7 installation directory
catalina.home=/usr/share/tomcat6
# Manager webapp username and password
manager.username=kees
manager.password=][p][p
build.sysclasspath=ignore
</pre>
<pre>
compile:
[javac] /home/kees/projects/jsp/hello/build.xml:282: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
</pre>
| ant install | |
|---|---|
yep, that's it. the tomcat server's /text service knows where to put the war file with the data from build.properties. So look at http://localhost:8080/hello
after that however, ant install will complain about already being installed, docs say you should use reload for that :
But i cannot make that work for now. Here are the task you can use with ant :<pre>
<!-- Configure the custom Ant tasks for the Manager application -->
<taskdef name="deploy" classname="org.apache.catalina.ant.DeployTask"/>
<taskdef name="install" classname="org.apache.catalina.ant.InstallTask"/>
<taskdef name="list" classname="org.apache.catalina.ant.ListTask"/>
<taskdef name="reload" classname="org.apache.catalina.ant.ReloadTask"/>
<taskdef name="remove" classname="org.apache.catalina.ant.RemoveTask"/>
<taskdef name="resources" classname="org.apache.catalina.ant.ResourcesTask"/>
<taskdef name="roles" classname="org.apache.catalina.ant.RolesTask"/>
<taskdef name="start" classname="org.apache.catalina.ant.StartTask"/>
<taskdef name="stop" classname="org.apache.catalina.ant.StopTask"/>
<taskdef name="undeploy" classname="org.apache.catalina.ant.UndeployTask"/>
</pre>
ant remove ant install
because that seems to stick. For a shorthand, make this your entry in build.xml
Of course, rename the old reload target to "reloadbogus" or something.
Physically, your app is now copied to /var/lib/tomcat7/webapps :
gives<pre>
...
./webapps/hello
./webapps/hello/WEB-INF
./webapps/hello/WEB-INF/classes
./webapps/hello/WEB-INF/classes/mypackage
./webapps/hello/WEB-INF/classes/mypackage/Hello.class
./webapps/hello/WEB-INF/lib
./webapps/hello/WEB-INF/web.xml
./webapps/hello/images
./webapps/hello/images/tomcat.gif
./webapps/hello/hello.jsp
./webapps/hello/index.html
./webapps/hello/META-INF
./webapps/hello/META-INF/MANIFEST.MF
...
</pre>
Development 2 (continued)
The first dev chapter was just to aid deployment, let's dig in some deeper here.
Servlets and jsp pages
jsp means javaserver pages, and they are html; pages that allow java code to be evaluated inside. Servlets are server side java applets, and actually jsp pages are converted to servlets : (source : http://en.wikipedia.org/wiki/JavaServer_Pages)
the .jsp page :
<pre>
<%@ page errorPage="myerror.jsp" %>
<%@ page import="com.foo.bar" %>
<html>
<head>
<%! int serverInstanceVariable = 1;%>
<% int localStackBasedVariable = 1; %>
<table>
<tr><td><%= toStringOrBlank( "expanded inline data " + 1 ) %></td></tr>
</pre>
troubleshooting
unable to startup,particularly port 8005
This is the port at with tomcat listen for shutdown !!. Nevertheless it will hang with :
| shutdown hang | |
|---|---|
Check your /etc/hosts file !!!
This is NOT a problem with the port already being used, it is a problem with resolving localhost.
In my case i mistyped localhost :
| wrong localhost | |
|---|---|
Where of course it should be
| /etc/hosts | |
|---|---|
Debugging
tomcat preparation
This is for tomcat8 but the advise comes from tomcat7 docs. Lot's of advise about starting tomcat to listen on debug port 8000 focuses on the startup scripts, but that just does not startup by hand so here is a systemd version.
Edit /etc/default/tomcat8 and scroll to these lines:
| /etc/default/tomcat8 | |
|---|---|
Obviously uncomment the 3rd line, and then restart tomcat8 :
You will get a connection, but you will need
jdb usage
An actual example for the backend project, which just printed :
HTTP Status 405 - Method Not Allowed
Thank you.. but this is a problem occurring earlier then jdb can be of any help.
so to see what is happening connect to tomcat with jdb :
| debug | |
|---|---|
This will give you a prompt from where to start, you can list the threads to verify you are actually debugging tomcat :
| list the threads | |
|---|---|
Now you can issue a run command but it will say: "nothing suspended". Maybe forcing the error will help ?
intellij usage
Later...