[Top][All Lists]
[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