<This post has been retained for historical reasons to avoid 404 errors as it has been referenced on other forums >
This is with reference to my previous post where I had to use a workaround to deploy a .war file for our Hospital Management Software. However as our date to go live approached, I was forced to do additional reading and experiment on the same and here are my conclusions. For your information, we are using Ubuntu Server 9.1 (Selecting LAMP + Tomcat Java Server from tasksel after the base install). the problem is still not sorted out but hopefully will soon be. The war file was deployed in /var/lib/tomcat6/webapps/. The logs are found at /var/log/tomcat6/
These are the error messages from the Catalinaxxxx.log.
jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/Servlet.class
jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/Servlet-api.class
The war file when copied to the /var/lib/tomcat6/ folder did not deploy. Trying to access it from the browser resulted in a 404 resource not found error
On Googling this error online, I came across the following description for Servlet Spec 2.3, section 9.7.2.
Servlet spec 2.3 sec 9.7.2 recommends … The classloader that a container uses to load a servlet in a WAR must allow the developer to load any resources contained in library JARs within the WAR following normal J2SE semantics using getResource. It must not allow the WAR to override J2SE or Java servlet API classes. It is further recommended that the loader not allow servlets in the WAR access to the web container’s implementation classes. It is recommended also that the application class loader be implemented so that classes and resources packaged within the WAR are loaded in preference to classes and resources residing in container-wide library JARs.
There were several solutions posted around the net and I am listing them out below.
- The most common solution peddled online was to delete the offending file(s) from the WEB-INF/lib/ folder and ignore the error message. This seems to have worked for at least a few people. In our case, deleting the files did not enable the app to deploy properly. In fact we were rewarded with the -SEVERE: Error listenerStart error.
- Other possible problems…That our developers had included the servlet-api.jar in the runtime library (in the .WAR) – and that it was only needed during build time. (They had)
- Remove the jar from WEB-INF/lib, and update your build script to point to the new location. This too seems to be a possible solution, but this was out of my hands, and the solution was therefore passed on to the developers. (who just ignored it)
- The problem could be that we had some other jar files which were not supposed to be in our war as they were bundled with the container(tomcat). To quote from another source, “It is a common mistake to keep these jars in WEB-INF/lib folder for compilation and ship it with the war file as these are only required for compiling your app (notably servlet-api.jar or j2ee.jar), but they should not be deployed as part of the webapp.” Another possibility -and conveyed to our developers with the same result as above… zzzz
- “This is when you don’t have servlet-api.jar in class path. check that servlet-api.jar is in tomcat6/lib” -once again could be part of a possible problem but I have no access to the source code to verify this.
- From yet another source, “the Servlet Spec 2.3, section 9.7.2 being referred to says that the Servlet Container (E.g. Tomcat) will supply the implementation class of the J2EE spec. The j2ee.jar (servlet-api.jar in our case?) in your WEB-INF/lib directory is trying to supply the same info. Having application specific implementations is a stability and security problem that is disallowed by the spec 2.3 and by Tomcat.” (Seems highly likely!!)
- Here is an incomplete list of jar files (listed below) which are not supposed to be included in the war file but in the container’s lib directory.
j2ee.jar, jasper-*.jar, jsp-api.jar, rt.jar,tools.jar, servlet.jar, servlet-api.jar, xerce.jar, xerces.jar and xercesImpl.jar, jboss.jar, gwt-user.jar, gwt-dev-linux.jar, gwt-dev-windows.jar, standard.jar
Unfortunately for us, I found information online which said that using servlet.jar & the servlet-api.jar for compiling is passe and compiling should preferably be done by using j2ee.jar instead. I’m still waiting for a reply from them (our developers) and have refused to deploy our software from a folder using a standalone copy of Tomcat. I received an email saying that there was no difference in both the methods -however they have been unable to deploy with the bundled version of Tomcat 6 in Ubuntu server, -how then were they able to compare both methods when they haven’t been able to set it up is anybody’s guess -divine guidance perhaps?
As a systems guy, for me the logic is simple. When anything is installed from a repository, the system administrator is assured of a centralized update and also automatically installed security updates (if opted for) -this is all the more important for us as we would ultimately be deploying around 20 servers running Ubuntu Server edition in primarily rural locations with no proper IT support -let alone Linux administrators. In addition to that we would use this system at least for the next 8-10 years so the technology used must be current. If I use the method propounded by our developers, (because doing it the optimal way would be additional work for them -incidentally they also prefer to always run as root) then I’d be running tomcat6 for the next 8-10 years and also the existing servlet-api.jar (among others). On the other hand, if I choose to run the Tomcat sever installed using tasksel or apt and the developers used the servlets bundled with it, then (its current servlet-api.jar in /usr/share/tomcat6/lib/ is a symlink to servlet-api-2.5.jar) I can get updates without breaking the app as any references to /usr/share/tomcat6/lib/servlet-api.jar gets pointed to its latest bug fixed/enhanced avatar, currently /usr/share/tomcat6/lib/servlet-api-2.5.jar. Since I am not a developer I and do not have access to the programming/compiling details or the source code, I cannot come to any definite conclusion for now but will append to this post as soon as I have more information on the same.
Posted some months later…
I tried a few experiments but couldn’t do much as I did not have access to the source code. The solution seems to build the package on the Eclipse Java EE IDE for Linux. It is available from the Eclipse Website. Download, extract and run.
Here is a screenshot of the screen after I imported the WAR file. It clearly states that ” Unselected libraries will be imported into the WEB-INF/lib folder as jar files” and that seems to be the most likely solution to the problem… build on Linux and select the libraries so that they don’t get included in your WEB-INF/lib folder! ( i.e. they won’t get included in your build and the copies that install along with Tomcat6 on the production server will be used) I’ve marked the libraries that are causing us issues with big red dots. The best way would be to select all so that Tomcat’s (on the production server) own libraries are used.
Importing a WAR into the Eclipse Java EE IDE on Linux
Posted a few months later:
In our case, what did work out finally was to set TOMCAT6_SECURITY=no in /etc/init.d/tomcat6 (The default is yes). Note: In Ubuntu Server 10.04 Lucid Lynx, the default is already set to no, so our HIS software works without a hitch. However the same error still shows up in the log files. It does not seem to affect any of its functionality though.
This is a stop gap “solution” from our software developers who have designed the software. (knowing them, read that as a permanent solution) Can’t expect local Windows programmers to understand or care about the nitty-gritties of Linux security or trouble themselves even with Windows security for that matter. The last time I met them, their actions convinced me that they were not keen to explore the dilemma of their custom libraries residing in /WEB-INF/lib . I’m convinced that only third party libraries must make it into the/WEB-INF/lib folder -I could be wrong though, but if I was one of them, I’d avoid bundling the web libraries that are in any case automatically installed by default along with Tomcat. Its like bundling DLLs in a Windows application that Windows already has by default. The logic is simple, even in Tomcat on Linux as in Windows. The DLLs in the System folders in Windows are protected, secure and automatically updated, the dupes that the software developer has provided with the software that’s installing, might at best be outdated or at worst compromised! The only problem I see on using the system DLL’s would be that your app might break as part of a Windows or Linux update. Well that’s not supposed to happen (or happen only rarely) if you coded right in the first place!
In our case, the problem was point No. 6 among the possibilities listed above. However our developers continued to ignore our feedback. It wasn’t just a Tomcat problem, its just that they continued with their same callous attitude in all areas of their software. We finally threw them out and found some really great guys to work with for our HIS systems 🙂
This post has been read 8014 times 🙂