Nightmare: Upgrading Tomcat 5.5 to 6.0

2019-05-10 21:07发布

问题:

I'm trying to upgrade a perfectly running embedded Tomcat 5.5 to Tomcat 6.0. I understand that all I need to do is replace Tomcat 5.5 jars with 6.0. That's what I did.

So I replaced the following jars:

catalina-5.0.28.jar catalina-5.5.9.jar catalina-optional-5.5.9.jar 
commons-el.jar commons-modeler-1.1.0.jar jasper-compiler-jdt.jar 
jasper-compiler.jar jasper-runtime.jar jmx-5.0.28.jar jsp-api-2.0.jar 
naming-factory.jar naming-resources.jar servlet-api-2.4.jar 
servlets-default.jar tomcat-coyote.jar tomcat-http.jar tomcat-util.jar

with:

annotations-api.jar  catalina.jar    jasper.jar         tomcat-dbcp.jar
catalina-ant.jar     el-api.jar      jsp-api.jar        tomcat-i18n-es.jar
catalina-ha.jar      jasper-el.jar   servlet-api.jar    tomcat-i18n-fr.jar
catalina-tribes.jar  jasper-jdt.jar  tomcat-coyote.jar  tomcat-i18n-ja.jar
tomcat-juli.jar

As soon as I start the server, I get the following message in the logs at INFO level:

INFO: Starting Servlet Engine: Apache Tomcat/6.0.29
Dec 31, 2010 6:04:18 AM org.apache.catalina.loader.WebappClassLoader validateJarFile
INFO: validateJarFile(/usr/local/blah/blue/./WEB-INF/lib/servlet-api.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/Servlet.class

Based on the this explanation, I need to remove a jar file which has a conflicting Servlet.class. I swear to God, there is no other conflicting jar file, I grepped system wide for Servlet.class, it matched only servlet-api.jar.

I also downloaded javaee.jar and replaced it by servlet-api.jar, to same avail.

Having tried lot of these stuff, I did not have much to look upto, so set the tomcat logging level to ALL. In the log I could see that it is trying to check for Servlet.class in each and every jar it is loading until it finds servlet-api.jar and throws "jar not loaded" message as soon as it finds servlet-api.jar. See below:

FINE:  Checking for javax/servlet/Servlet.class
Jan 2, 2011 7:39:33 AM org.apache.catalina.loader.WebappLoader setRepositories
FINE: Deploy JAR /WEB-INF/lib/servlet-api.jar to /usr/local/blah/blue/./WEB-INF/lib/servlet-api.jar
Jan 2, 2011 7:39:33 AM org.apache.catalina.loader.WebappClassLoader addJar
FINE: addJar(/WEB-INF/lib/servlet-api.jar)
Jan 2, 2011 7:39:33 AM org.apache.catalina.loader.WebappClassLoader validateJarFile
FINE:  Checking for javax/servlet/Servlet.class
Jan 2, 2011 7:39:33 AM org.apache.catalina.loader.WebappClassLoader validateJarFile
INFO: validateJarFile(/usr/local/blah/blue/./WEB-INF/lib/servlet-api.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/Servlet.class
Jan 2, 2011 7:39:33 AM org.apache.catalina.loader.WebappLoader setRepositories

UPDATE I'm able to remove the above "jar not added" error by placing servlet-api.jar in a separate folder(like $CATALINA_HOME/common/lib). However the GUI still shows blank(Error 404) when I hit an URL :(. The log message when the URL is hit is described below. UPDATE ends

Please note however, that Tomcat starts successfully! And as soon as I hit the URL on the browser, I get blank page(this may be in my case only, I guess 'cuz of my web.xml, sorta different from most. Other people on the internet have got Error 404 instead.) with following log statements(at finest level)

Jan 2, 2011 9:40:01 AM org.apache.catalina.connector.CoyoteAdapter parseSessionCookiesId
FINE:  Requested cookie session id is 0FBA716E3F9B0147C3AF7ABAE3B1C27B
Jan 2, 2011 9:40:01 AM org.apache.catalina.authenticator.AuthenticatorBase invoke
FINE: Security checking request GET /login.jsp
Jan 2, 2011 9:40:01 AM org.apache.catalina.realm.RealmBase findSecurityConstraints
FINE:   Checking constraint 'SecurityConstraint[protected]' against GET /login.jsp --> false
Jan 2, 2011 9:40:01 AM org.apache.catalina.realm.RealmBase findSecurityConstraints
FINE:   Checking constraint 'SecurityConstraint[protected]' against GET /login.jsp --> false
Jan 2, 2011 9:40:01 AM org.apache.catalina.realm.RealmBase findSecurityConstraints
FINE:   Checking constraint 'SecurityConstraint[protected]' against GET /login.jsp --> false
Jan 2, 2011 9:40:01 AM org.apache.catalina.realm.RealmBase findSecurityConstraints
FINE:   Checking constraint 'SecurityConstraint[protected]' against GET /login.jsp --> false
Jan 2, 2011 9:40:01 AM org.apache.catalina.realm.RealmBase findSecurityConstraints
FINE:   No applicable constraint located
Jan 2, 2011 9:40:01 AM org.apache.catalina.authenticator.AuthenticatorBase invoke
FINE:  Not subject to any constraint
Jan 2, 2011 9:40:01 AM org.apache.catalina.core.StandardWrapper allocate
FINEST:   Returning non-STM instance

I'm not sure if the above log message is important, but I'm for all-out disclosure here.

One interesting thing though, I manually created a dummy jsp file containing only "helloooo" just outside WEB-INF folder(no security constraints for this file). This file was accessible and could be displayed. But, all my jsp's and classes are inside WEB-INF(ofcourse).

Sick and tired of this issue, please help me solve it. I've already spent 20-24 hours on this unsuccessfully.

Any pointers directions hints leads?

回答1:

The servlet-api.jar is definitely needed for running tomcat embedded. However, is seems to be a classloader issue here. The Classloader for the webapp must not have "direct" access to the servlet.jar, only through its parent class loader.

If you only replaced jars, then there must be a subtle difference in the ClassLoaders of 6.0 vs. 5.5, but I cannot say where.



回答2:

Tomcat 5.5 and Tomcat 6.0 have some significant differences. My suggestion is to move the WAR files to the new Tomcat instead of trying to gut the old one. One particular difference that comes to mind is that the JAR files are all organized differently.

Since Tomcat 6.0 obviously comes with all of the Tomcat 6.0 JAR files, it stands to reason that you won't have any conflicts if you just use a fresh Tomcat 6.0 install and then move your WAR file applications to the new Tomcat 6.

You will probably still have conflicts, but you'll at least have one variable knocked out, you'll know you're working with a fresh, solid, Tomcat installation instead of one that might be broken or might not be broken.

Good call setting the logging level to ALL, just make sure you get all of the logging.properties files as sometimes there may be more than one.

http://tomcat.apache.org/tomcat-6.0-doc/logging.html

Good luck!



回答3:

This seems strange - if you didn't change your own web app this issue must exit in 5.5, too.

As @daniel said, your web app is not allowed to have a jar file containing servlet stuff. If i interpret the log correctly, there is a servlet-api in the web app directory. Delete servlet-api completely there.

EDIT

  • What is the directory layout of your application, where do the jars (especially the tomcat jars) live.
  • What is the log output when tomcat starts without the servlet-api in your web app
  • How do you "embedd" tomcat
  • What's the classpath when you start your app

EDIT

You MUST separate the environment lets say in

\yourapp
|
+ lib
|
+ webapp
  |
  + lib (this is where your webapp lives, WITHOUT servlet-api)

If this has similiarity to standard JavaEE container structure - it is NOT by pure hazard :-)

yourapp\lib hosts your application and tomcat libraries. This forms the classpath for starting.

The yourapp\webapp\lib jars are never referenced by the classpath, only by the webapp classloader. You must take the correct path to them into account when you configure your builtin tomcat to point to this webapp, otherwise the web app loader may not find them.

EDIT

Maybe start with something less ambitioned than a JSP. Do you have a simple test servlet deployed?

You must take care to which web application context you have deployed your application. In the log i see you use the root context. Is this really true? If for example you said

  tomcat.addWebapp("foo", appBase);

in your embedding, you must request /foo/servlet, not /servlet in your browser.



回答4:

So the issue really was: not compiling the source code with latest jars. The classes present on the machine were pre-existent and compiled using Tomcat 5.5 jars and not Tomcat 6.0. Transferring fresh classes solved my problem.

Big thanks to mtraut for showing interest on this question. I wish I could up-vote you more than once. :)