• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • paul wheaton
  • Paul Clapham
  • Ron McLeod
Sheriffs:
  • Jeanne Boyarsky
  • Liutauras Vilda
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Roland Mueller
  • Piet Souris
Bartenders:

Tomcat Common Classloader issue

 
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello all,

I am a java newbie and need your help in understanding the common loader in tomcat. Please pardon me if I have created a duplicate topic/thread, I am new to the community.

Here is my issue:

I have class called PortletTitelComparator that is present in two jar's(ext-service.jar and portal-service.jar), the first jar((portal-service.jar) has method with 2 parameters and the other (ext-service.jar) has it with 3 parameters. I have made both these jar's available under tomcat/common/lib/ext/

my common loader in tomcat/conf/catalina.properties is defined as below:
Trail 1)common.loader=${catalina.home}/common/classes,${catalina.home}/common/i18n/*.jar,${catalina.home}/common/endorsed/*.jar,${catalina.home}/common/lib/*.jar,${catalina.home}/common/lib/ext/*.jar (or)
Trail2)common.loader=${catalina.home}/common/classes,${catalina.home}/common/i18n/*.jar,${catalina.home}/common/endorsed/*.jar,${catalina.home}/common/lib/*.jar,${catalina.home}/common/lib/ext/*.jar,${catalina.home}/common/lib/ext/ext-service.jar

I run into issue when one of my jsp that uses the ext-service.jar (the method defined here with3 parameters) try to compile , i see the following error, even though the jar is in my common loader path. There is a difficulty for the container to know which one has to be picked up. For some reason it never goes to the actual jar that has this class.

The constructor PortletTitleComparator(ServletContext, Locale, Hashtable) is undefined

But when I tweak my common loader as below:

Success 1) common.loader=${catalina.home}/common/classes,${catalina.home}/common/lib/ext/ext-service.jar,${catalina.home}/common/i18n/*.jar,${catalina.home}/common/endorsed/*.jar,${catalina.home}/common/lib/*.jar,${catalina.home}/common/lib/ext/*.jar

things start working as expected and the jsp gets compiled. The container can now distinguish the difference between both classes.

All that was done is to have the jar mentioned out explicitly in the common loader path before ${catalina.home}/common/lib/*

I am a bit confused here and would like to know what is happening and how does a tomcat class loader behaves and on what criteria does it load its classes when 2 jars have a similar class that exhibit method overloading. Even when i had the specific jar written (see trail-2 above) at the end of the common load path it seemed it did get picked correctly.

I would be happy if some one can explain what exactly is going on here.

Thanks in advance for any one who can spare a bit of there time and explain.

alex

I have gone thru:http://tomcat.apache.org/tomcat-5.5-doc/class-loader-howto.html {but did not find the answer that i am looking for } the reason i am looking at tomcat 5.5 is I am working on tomcat 5.5.


 
Saloon Keeper
Posts: 28765
211
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Welcome to the JavaRanch, Alex!

You really should move up from Tomcat 5.5. Aside from the usual reasons, the tomcat server library structure changes radically beginning with Tomcat6, so any games you play at that level would be pre-obsolescent.

It is generally not a good idea to put application logic in any Tomcat common library directory. For one thing, WARs should be self-contained. For another, unlike the regular webapp resources, library resources are shared between multiple apps and will break in unpredictable ways and unpredictable times if they are not meticulously thread-safe.

You should avoid at all costs having classes with the same fully-qualified (class+package) name in any Java system, whether web-based or not and most definitely not have multiple definitions of the class that are not 100% identical. That's just basic Java. Along with that you should never assume that there is a predictable and repeatable classpath search order. Yes, I think that Tomcat does run up the various tiers sequentially, but absent RTFM'ing, I wouldn't assume so. And definitely not within a tier. It's just too likely that the loader might be using a hashmap to find the classes.
 
alex russo
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for the response Tim, I really appreciate taking time out.
Agreed I have to move to Tomcat 6 but I have to live with 5.5 currently since all our environments are working on this, migration is scheduled.

But here is the thing that confuses me, the Trail 1 scenario was set up on a 32-bit machine and it had always worked successfully, never had issue at least for the last 3 years it has been running the JVM knew which class to be invoked but recently we have undergone an infrastructure migration and we moved up to 64 bit servers with "Red Hat Enterprise Linux Server release 5.3 (Tikanga)' earlier we were on 32bit we were on Redhat 4.

We cam e across this issue only after migration, but note all other variables like the tomcat version, JDK , Apache all remained same just changed from 32 bit Redhat 4 to 64 bit Redhat5.3

Even if the loader is using "hashmap" is should have been able to locate the expected class with Trail 2.

Thanks once again.

-alex
 
Tim Holloway
Saloon Keeper
Posts: 28765
211
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
When you violate a standard and "it works" that doesn't mean that it will always continue to work. In fact, Murphy's Law specifically dictates that it is most likely to stop working exactly when it's most painful and expensive to have it fail. That's one reason why I use loud colors and big fonts to tell people not to write data files into their WARs. "It works". Until someone reconfigures Tomcat. Or the webapp is updated and all the added files get incinerated.

It's highly recommended that you upgrade Tomcat, but not essential. On the other hand, having 2 different classes with the same name is just begging for trouble. It's bad enough when you have 2 different versions of the same class ("DLL Hell", anyone?). But when they have 2 different functionalities, that's, well, there's just no nice way I can say it.

When you do have multiple copies of the same class, you should either rename one of them or place the classes in divergent classpaths so that their there will be no conflict now or ever. In the case of webapps, that means that the jars in question should be located in the WEB-INF/lib directories of their respective WARs and not placed in the shared global part of their classpaths.
 
alex russo
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Tim
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic