> craigmcc    01/06/22 14:57:08
>
>   Log:
>   Add some unit tests for bean references from a servlet (Session01 or
>   Session03) to beans in the following locations:
>   * SessionBean is in the same /WEB-INF/lib/tester.jar JAR file as the
>     servlet classes are
>   * UnsharedSessionBean is unpacked under /WEB-INF/classes in the
>     tester web app, but should be loaded by the same webapp class loader
>     that loads the servlet.
>   * SharedSessionBean is in a JAR file under $CATALINA_HOME/lib, so it
>     should be loaded by the parent classloader
>
>   There definitely appears to be a problem with class loading, and trying
>   this stuff fails under either WebappClassLoader and StandardClassLoader.
>   Right now, I've commented things in the build.xml file out so that all
the
>   classes get built into tester.jar, and running the "HttpSession" target
>   all succeeds.
>
>   If you uncomment the following sets of lines in build.xml, though:
>   * 75-76 to copy UnsharedSessionBean to /WEB-INF/classes
>   * 95-96 to exclude SharedSessionBean and UnsharedSessionBean
>     from tester.jar
>   * 151-156 to create and deploy SharedSessionBean into the
>     $CATALINA_HOME/lib directory
>
>   then you will get NoClassDefFound exceptions when trying to execute
either
>   Session01 or Session03.
>
>   Conclusion:  class loading fails when a class within a JAR file under
>   /WEB-INF/lib references a class in /WEB-INF/classes, or in a shared JAR
>   file in the parent class loader.

I don't think that test case is valid.

Both of the following explanations are theories. I could be wrong. Comments
by CL gurus are welcome.

Case A (Craig's test) :

Basically, what happens here is :
- The Webapp CL which manages the tester webapp loads Session01
- It then notices it needs to be linked with other classes (SessionBean,
SSB, and USB)
- It loads USB, no problem
- It asks the parent CL to load SSB, because it can't find it
- Parent loads SSB, checks linking
- It notices it needs to load SB
- It can't find SB (since it's in his child CL repository)

I don't see how we can have that work. It's a case where classes from the
shared loader depend on classes from the webapp loader.

Case B (Jon's reloading) :

- Class A which depends on class B (which is also loaded by CL 1 -
everything would be ok if it was loaded by the parent CL) gets loaded
(perhaps along with class B) by CL 1
- Touch class A
- Reload
- CL 1 gets destroyed, and CL 2 is created, and contains the same
repositories as CL 1
- all the classes loaded by CL 1 are still there
- Later, reload new class A
- New class A needs class B, which CL 2 doesn't know
- CL 2 loads another class B
- The other objects instance of the old class B are unaffected, which leads
to an error at some point

To solve this, I would try doing a ctx.stop + ctx.start (instead of
ctx.reload) whenever class reloading is needed. I think the current
reloading will only be able to reload reliably things like the HelloWorld
servlet (ie, classes which are fully independent from other classes from the
webapp).

Remy

Reply via email to