bug-jel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [Bug-jel] Re: Class Not Found


From: Hajratwala, Nayan (N.)
Subject: RE: [Bug-jel] Re: Class Not Found
Date: Wed, 20 Nov 2002 15:38:28 -0500

Thanks! It worked!

FYI, under WebSphere 3.5, I simply placed the JEL classes right along with my 
regular application code rather than in the classpath for the JVM.

Strange but true =)

-----Original Message-----
From: Konstantin L. Metlov [mailto:address@hidden 
Sent: Wednesday, November 20, 2002 3:16 PM
To: Hajratwala, Nayan (N.)
Cc: address@hidden
Subject: [Bug-jel] Re: Class Not Found


Dear Nayan Hajratwala,

The situation you have encountered is not a bug in JEL, but rather a 
manifestation of intricacy of Java classloaders.

In short, the problem is related to the fact that your class 
"com.ford.hr.framework.user.IUser" might be present in the classpath TWICE by 
being accessible by two _different_ classloaders at the same time. This often 
happens in a servlet engines having both "default" and so called 
"zone-specific" classloaders.

The solution is to load JEL (preferably as a whole, but loading only 
gnu.jel.ImageLoader class is sufficient) into your JVM using the same 
"zone-specific" classloader your classes (e.g. 
com.ford.hr.framework.user.IUser) are loaded with.

Thank you for your interest in JEL !

If some questions still remain, please ask.

With the best regards,
                          Konstantin.



                                 APPENDIX

For more detailed explanation, please read the following excerpt from my E-mail 
to one of JEL users having the same problem (in this explanation class 
"Message" plays the same role as your "com.ford.hr.framework.user.IUser", and 
"TestRouter" stands for a class within your package referring to 
"com.ford.hr.framework.user.IUser"  
directly, e.g. not through JEL):

--------------
First, a little of common knowledge (probably redundant). A ClassLoader is a 
java class, which loads other Java classes into the memory of Java VM and 
maintains their namespace. Actually, the only way to load a bytecode into JVM 
is via a ClassLoader of some kind. There can be several classloaders active at 
the same time, and, thus several namespaces.

Servlet engines, often, separate different parts of the web site (sometimes 
they are called "servlet zones") by using different classloaders for each zone. 
Additionally, in each JVM instance, there is a "default" classloader, which 
loads classes from a global JVM classpath.

When loading compiled expressions into JVM, JEL does it in the same context 
(e.g. in the namespace of the same classloader) the class gnu.jel.ImageLoader 
(a part of JEL library) was loaded.  This means, if JEL is in the global 
classpath -- the compiled expressions will be loaded in the context of 
"default" classloader. Servlets, on the other hand, are loaded by a classloader 
specific to their "servlet zone".

The problem arizes when JEL is loaded by "default" classloader and the same 
classes (in your case "Message") can be loaded both by "default" and 
zone-specific classloaders (e.g. they are on "classpath" of both). In this 
case, when expression is compiled the byte code contains only a link to Message 
class. When it is loaded into JVM this link is resolved using the "default" 
classloader and your Message class is loaded by it. On the other hand, there 
exists another instance of Message class (please note the difference with 
object), which is loaded by zone-specific classloader (the one, which allows 
you to access Message from within your HttpServlet implementation).

Next, when you call the expression, you pass the instance of Message class held 
in Router.msg (which was loaded by zone-specific classloader) into JEL 
expression, containing the reference to Message class (which was loaded by 
"default" classloader). The main point is that these two classes are considered 
DIFFERENT by JVM and can not be converted into one another.

See e.g.

http://216.239.53.100/search?q=cache:A0_GzRToobgC:www.dcs.gla.ac.uk/~huw/papers/eufurt.ps.gz+%22two+classes+with+the+same+name%22+%22different+classloaders%22+ClassCastException&hl=en&ie=UTF-8

for reference.

Therefore, please check that the whole JEL (and gnu.jel.ImageLoader in
particular) is loaded into your JVM not via global CLASSPPATH, but through the 
same zone-specific classloader you use to load TestRouter class.
---------------------

and its continuation, with some simple pictures:
---------------------
May be this will explain the situation with classloaders better.

Each classloader has a "parent" classloader to which it passes the requests to 
load the classes it can not resolve. This allows to organize classloaders into 
a tree (since a single classloader can be a parent of many). The "default" 
classloader is a root.

WRONG SITUATION

          |-------->    "default"
          |    namespace:
          |    java.lang.*
          |    java.net.*
          |    ...
          |    gnu.jel.ImageLoader(g.j.I)
          |    Message
          |
          |------------------------------- ....    -------
          |                  |                            |
     g.j.I (instance1)  g.j.I (instance2)           servlet classloader
     namespace:         namespace:                  namespace:
     gnu.jel.E_1        gnu.jel.E_2                 TestRouter
                                                    Message

The class message appears in two namespaces. This is because the compiled 
expression refers to it, at its load time the g.j.I classloader, obviously 
(because it does not know about anything except JEL expressions), passes the 
request to load its parent (which is "default" classloader in this case). The 
second Message appears in servlet classloader namespace because TestRouter 
refers to it, and this reference is resolved upon loading of the TestRouter 
class.

CORRECT SITUATION


          |-------->    "default"
          |    namespace:
          |    java.lang.*
          |    java.net.*
          |    ...
          |
          ---------------
                         |
                         |
          ------> servlet classloader
          |    namespace:
          |    TestRouter
          |    Message
          |    ...
          |    gnu.jel.ImageLoader
          |
          |------------------------------- ....
          |                  |
     g.j.I (instance1)  g.j.I (instance2)
     namespace:         namespace:
     gnu.jel.E_1        gnu.jel.E_2

In this case the parent of JEL classloaders is "servlet classloader", to which 
g.j.I (correctly) readdressed request to load Message class, so that only one 
instance of Message class exists in JVM.

One g.j.I per compiled expression is required to enable the garbage collection 
of classes (additionally to objects).
---------------







_______________________________________________
Bug-jel mailing list
address@hidden
http://mail.gnu.org/mailman/listinfo/bug-jel




reply via email to

[Prev in Thread] Current Thread [Next in Thread]