Frustrating Tomcat 5.5.x Issue Solved (conflicting jars...)

Posted by ryan
at 3:05 PM on Thursday, January 27, 2005

I’ve recently decided to move most of my web apps from a Tomcat 4.x platform to Tomcat 5.5.x (which also means moving to jdk 1.5). All went fine with Java-Frameworks.com (since decommissioned), but I ran into an issue when upgrading another app of mine. When I would access any page or action I would get the following stack trace:

SEVERE: Servlet.service() for servlet jsp threw exception
org.apache.jasper.JasperException: Unable to read TLD "META-INF/c-1_0.tld" from JAR file "file:/opt/java/jakarta-tomcat-5.5.4/webapps/bblmgr/WEB-INF/lib/standard-tags.jar": org.apache.jasper.JasperException: Failed to load or instantiate TagLibraryValidator class: org.apache.taglibs.standard.tlv.JstlCoreTLV
        at org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:50)
        at org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:407)
        at org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:179)
        at org.apache.jasper.compiler.TagLibraryInfoImpl.<init>(TagLibraryInfoImpl.java:181)
        at org.apache.jasper.compiler.Parser.parseTaglibDirective(Parser.java:418)
        at org.apache.jasper.compiler.Parser.parseDirective(Parser.java:483)
        at org.apache.jasper.compiler.Parser.parseElements(Parser.java:1539)
        at org.apache.jasper.compiler.Parser.parse(Parser.java:126)
        at org.apache.jasper.compiler.ParserController.doParse(ParserController.java:211)
        at org.apache.jasper.compiler.ParserController.parse(ParserController.java:100)
        at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:146)
        at org.apache.jasper.compiler.Compiler.compile(Compiler.java:286)
        at org.apache.jasper.compiler.Compiler.compile(Compiler.java:267)
        at org.apache.jasper.compiler.Compiler.compile(Compiler.java:255)
        at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:556)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:296)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:295)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:245)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
        at com.opensymphony.module.sitemesh.filter.PageFilter.parsePage(PageFilter.java:129)
        at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:61)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:186)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:825)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:731)
        at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:526)
        at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
        at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
        at java.lang.Thread.run(Thread.java:595)

Ok, seems like I had run into this before… oh yeah, I needed to upgrade the apache commons standard tag library to the JSTL 1.1 version located (here). Ok, downloaded that and put it in the app’s lib dir. Let’s give it another go. Nope, getting this now:

org.apache.jasper.JasperException: Unable to read TLD "META-INF/c-1_0.tld" from JAR file "file:/opt/java/jakarta-tomcat-5.5.4/webapps/bblmgr/WEB-INF/lib/standard.jar": org.apache.jasper.JasperException: Failed to load or instantiate TagLibraryValidator class: org.apache.taglibs.standard.tlv.JstlCoreTLV
  at org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:50)
  at org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:407)
  at org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:179)
  at org.apache.jasper.compiler.TagLibraryInfoImpl.<init>(TagLibraryInfoImpl.java:181)
  at org.apache.jasper.compiler.Parser.parseTaglibDirective(Parser.java:418)
  at org.apache.jasper.compiler.Parser.parseDirective(Parser.java:483)
  at org.apache.jasper.compiler.Parser.parseElements(Parser.java:1539)
  at org.apache.jasper.compiler.Parser.parse(Parser.java:126)
  at org.apache.jasper.compiler.ParserController.doParse(ParserController.java:211)
  at org.apache.jasper.compiler.ParserController.parse(ParserController.java:100)
  at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:146)
  at org.apache.jasper.compiler.Compiler.compile(Compiler.java:286)
  at org.apache.jasper.compiler.Compiler.compile(Compiler.java:267)
  at org.apache.jasper.compiler.Compiler.compile(Compiler.java:255)
  at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:556)
  at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:296)
  at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:295)
  at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:245)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
  at com.opensymphony.module.sitemesh.filter.PageFilter.parsePage(PageFilter.java:129)
  at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:61)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:186)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
  at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
  at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
  at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
  at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
  at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
  at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
  at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:825)
  at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:731)
  at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:526)
  at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
  at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
  at java.lang.Thread.run(Thread.java:595)

with a root cause of …

SEVERE: Servlet.service() for servlet jsp threw exception
java.lang.ClassCastException: org.apache.taglibs.standard.tlv.JstlCoreTLV
        at org.apache.jasper.compiler.TagLibraryInfoImpl.createValidator(TagLibraryInfoImpl.java:647)
        at org.apache.jasper.compiler.TagLibraryInfoImpl.parseTLD(TagLibraryInfoImpl.java:246)
        at org.apache.jasper.compiler.TagLibraryInfoImpl.<init>(TagLibraryInfoImpl.java:162)
        at org.apache.jasper.compiler.Parser.parseTaglibDirective(Parser.java:418)
        at org.apache.jasper.compiler.Parser.parseDirective(Parser.java:483)
        at org.apache.jasper.compiler.Parser.parseElements(Parser.java:1539)
        at org.apache.jasper.compiler.Parser.parse(Parser.java:126)
        at org.apache.jasper.compiler.ParserController.doParse(ParserController.java:211)
        at org.apache.jasper.compiler.ParserController.parse(ParserController.java:100)
        at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:146)
        at org.apache.jasper.compiler.Compiler.compile(Compiler.java:286)
        at org.apache.jasper.compiler.Compiler.compile(Compiler.java:267)
        at org.apache.jasper.compiler.Compiler.compile(Compiler.java:255)
        at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:556)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:296)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:295)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:245)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
        at com.opensymphony.module.sitemesh.filter.PageFilter.parsePage(PageFilter.java:129)
        at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:61)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:186)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:825)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:731)
        at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:526)
        at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
        at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
        at java.lang.Thread.run(Thread.java:595)\

After at least 2 and a half hours of trying the nightly builds of Tomcat and the standard tag libraries (when does that ever work – should have known better), I took a closer look at the last exception thrown above – ClassCastException. Don’t know why I had been mostly ignoring the significance of that exception, but it became clear to me that I probably had conflicting jsp/jstl classes on my classpath. Tomcat probably provided one set and my app another. Sure enough, I had included a “jsp-api.jar” in my application’s lib directory, and Tomcat had its own version in $CATALINA_HOME/common/lib. I removed the jar from my application and everything loaded just fine. I could have also just copied the version from Tomcat to my app, but since I didn’t need it there was no sense in keeping it around.

And so ends this particular hurdle, can’t wait to see what’s next.

In my googling for a solution to this issue there was very little out there – so I thought I’d better post it in case anybody else runs into this issue. Ascintillating it’s not, but hopefully it will be helpful.

This little tidbit may help find jars with conflicting class files – it’s how to use the Linux “find” and “xargs” command to do just that. If you’re on windows then… Cygwin?

Dedicated server for $30/month

Posted by ryan
at 4:10 PM on Monday, January 17, 2005

Thanks to the Google ads I have on my site, I recently came across a pretty damn good deal for a dedicated server. Right now I’m running all my mail and web sites on a virtual private server from Linode.com and have no complaints at all. However, I’m paying $40/month for 4GB and 128 MB of dedicated resources – pretty steep.

The add I saw was for ServerPronto.com for a $30/month deal for a wholely dedicated server with a 40GB HDD and 256 MB. Of course I signed up for it just to give it a try and have been please so far. Good bandwidth although it doesn’t have the management console that Linode.com does.

I’m thinking about running all my Java stuff on the dedicated server since it has more memory and just running my mail on the Linode. Seems like a fair compromise for somebody that doesn’t really need two servers out there anyways.

And I thought the Google ads were supposed to make me money, not entice me into buying more stuf…

Software Suspend support on Dell Latitude D500 w/ Debian kernel v2.6.9

Posted by ryan
at 3:57 PM on Monday, January 17, 2005

Getting suspend functionality was probably the most challenging part of setting up my laptop so far. You’d be surprised how annoying it is to have to shutdown everytime you want to close your laptop lid and take it on a 10 minute journey home. A big thanks goes out to Nigel Cunningham who actually responded to my direct email when the mailing lists were down (Nigel is one of the software suspend developers, and I found his name while searching for an error message that I was receiving – his name was on the commit for the file with that error message. Despite his friendly help, I’m sure he curses Google daily.) So here are the steps I took to get software suspend working on my laptop:

Make sure you have the kernel sources, headers and initrd-tools installed:

  • apt-get install kernel-source-2.6.9 kernel-headers-2.6.9-x-686 initrd-tools
  • cd /usr/src
  • (If “linux” already exists): unlink linux
  • ln -s kernel-source-2.6.9 linux

Patch the kernel with software suspend support (http://softwaresuspend.berlios.de/HOWTO-2.html#ss2.3)

Now that the patch has been applied, you need to download the debian specific script as outlined here: http://swsusp.sourceforge.net/wiki/DebianInitrd

  • copy the script from the above URL into a new file called ”/etc/mkinitrd/scripts/swsusp2”

Compile your kernel and make the kernel and initrd images:

  • cd /usr/src/linux
  • make-kpkg clean
  • make-kpkg —append-to-version -swsuspend—config menuconfig—initrd kernel_image kernel_headers

In the kernel menu config make sure of the following selections (I only had success building them as modules (M))

  • Power management options —> Software Suspend 2 --> Software Suspend 2
  • Swap Writer
  • LZF image compression
  • Text mode console support

Install your kernel

  • dpkg -i kernel-headers-2.6.9-swsuspend.deb kernel-image-2.6.9-swsuspend.deb

After installing your kernel, you will need to edit your grub configuration for your new kernel to include the swap space that software suspend uses to suspend to. While there’s a blurb on the software suspend wiki where you downloaded the swsusp2 script that the script made you not need this parameter, I still had to include it:

  • cd /boot/grub/
  • nano (or your fav editor) menu.lst
  • Look for the entry representing your new kernel (this should be the first entry) and add “resume2=swap:/dev/hda3” to the “kernel” line. Mine looks like this:

    “kernel /vmlinuz-2.6.9-mppe-swsuspend root=/dev/hda6 resume2=swap:/dev/hda3”

    The ”/dev/hda3” is your swap space device. To find out what yours is run this command: “cat /etc/fstab | grep swap”.

Now you need to install the hibernate script that actually invokes the suspend functionality. It’s available as a debian package “hibernate”, but I downloaded and installed from the package available on the software suspend site. If any steps differ here it’s probably b/c of that:

The default hibernate configuration didn’t work for me out of the box b/c while the software suspend script you included earlier in /etc/mkinitrd/scripts/ loads the necessary suspend modules, it also unloads them – serving just to make sure the proper modules are available. The hibernate support needs these modules loaded to function so it has to re-load them when hibernate is invoked. Fortunately, it’s an easy update the hibernate.conf file that will make this happen:

  • cd /etc/hibernate
  • nano (or your fav editor) hibernate.conf
  • Uncomment the line starting with “LoadSuspendModules”
  • Add “suspend_core” to the list of modules. My line looks like this:

    “LoadSuspendModules suspend_core suspend_swap suspend_lzf suspend_text”

At this point, all should be ready for a reboot into your new kernel. Go ahead and reboot and select your new kernel from the list (again, it should be the first in the list). If everything goes well, you should see the following scroll by (also retrievable once logged in w/ “dmesg”:

Software Suspend Core.
Software Suspend text mode support loaded.
Software Suspend LZF Compression Driver registered.
Software Suspend Swap Writer registered.
Looking for first block of swap header at block 0.
Setting logical block size of resume device to 4096.
Software Suspend 2.1.5: Swap space signature found.
Software Suspend 2.1.5: Suspending enabled.
Software Suspend 2.1.5: This is normal swap space.
Software Suspend Swap Writer unloading.
Software Suspend 2.1.5: No writers have been registered.
Software Suspend LZF Compression Driver unloading.
Software Suspend text mode support unloading.
Software Suspend Core unloading.

If you see something like: “BIG FAT WARNING!!!”, then a double check that the “resume2=swap:/dev/hdx” option on the kernel boot line (in /boot/grub/menu.lst) is there and points to your swap space device. If you don’t see any errors, and do see the Software Suspend module messages on startup, then things are looking pretty good for you.

After your reboot, go ahead and login as root. Run the “hibernate” command and your machine should switch to text mode where it shows a progress bar saving your memory to disk. Press the power on button to startup again, choosing the same kernel you were in when you suspended, and your applications etc… should be loaded back into memory – including X.

This process was frought with many errors and messages that I didn’t record while I was figuring them out, so if you run into an error, let me know (using the comments), there’s a good chance I’ve seen it before. Good luck!

When following this guide on my work D600 I ran across the following error. After doing a complete build etc… and booting into the new kernel I was getting this error:

=== Software Suspend ===

BIG FAT WARNING!! Can't check whether to resume. Suspend's core module isn't loaded.

If you continue booting, note that any image WILL NOT BE REMOVED.
Suspend is unable to do so because the appropriate modules aren't
loaded. You should manually remove the image to avoid any
possibility of corrupting your filesystem(s) later.
Press SPACE to reboot or C to continue booting with this kernel

After scratching my head for awhile I noticed that when I copied and pasted the script from http://download.berlios.de/softwaresuspend/software-suspend-2.1.5-for-2.6.9.tar.bz2 to ”/etc/mkinitrd/scripts/swsusp2” I didn’t change the file to be executable. So…, I restarted from that point and did a “chmod +x /etc/mkinitrd/scripts/swsusp2”. After recompiling again, etc…, the reboot still had the same problem. Crap! I ended up just copying and pasting my vmlinuz and initrd image from my working D500 laptop onto the laptop where I was having these issues (my work D600). Luckily, that worked! I still think that the swsusp2 script wasn’t getting picked up when the initrd image was built (I think this b/c after one of the faulty boots, there was no /proc/software_suspend dir – which the swsusp2 initrd script creates?) For those that think it might be useful, I’ve uploaded both my working kernel and my image – you may only need the image?. (Note: this kernel and image include both mppe support and swsuspend2 support)

MS Office / MS Money in Crossover Office 0

Posted by ryan
at 10:53 PM on Tuesday, January 11, 2005

I recently purchased Crossover Office 4.1 after having a great experience with their 3.x version. While OpenOffice.org has been doing great for me, there’s always that need to natively open and edit a Word or Excel doc (although I miss the export to PDF button that OO has). I just got the install of Office done tonight, and it always amazes me how much faster Microsoft’s own apps run on Linux than on Windoze. Crossover is definitely worth the $30 if you have the need (it has great Outlook support too for those of you still chained to that app).

What really surprised me is that I got MS Money 2004 to install. Crossover doesn’t have “certified” support for Money, but a few people have gotten it to work – I guess I’m now among those lucky few. As somebody who is absolutely reliant on my personal finance package, this rocks. I did stumble across a little hack that made the install function though… When I did a normal install it hung on me. As part of my attempt to kill the processes I killed what appeared to be the main process (wine-server?) that seemed to un-hang the install. Anyway, I’m a happy man and have no problem paying for software like Crossover Office.