Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migration of unmigrated content due to installation of a new plugin

...

Wiki Markup
A component naturally has references to objects in the container; the fact that the container provides classes (which are objects) that are visible to the component is the most obvious example. This causes no problems for garbage-collecting of the component.  Problems come when the links become _bidirectional_, and classes within the container also have references to classes and objects within the components. The servlet and j2ee frameworks are carefully designed to avoid this where possible; where that is unavoidable the container \*knows\* about those situations and ensures the necessary references are cleared when a component is undeployed \[1\] \[2\]

But if users of the container start tossing libraries that aren't designed to avoid such references into classloaders that are "above" the classloader of the component and the container does not know about these libraries then bidirectional references are very likely to occur and failure to undeploy correctly will result.

...

Wiki Markup
\[1\] Except for the brain-dead design of JDBC where jdbc drivers loaded via a custom classloader apparently get stored in a map within java.sql.DriverManager thereby causing cyclic references to that classloader.

Wiki Markup
\[2\] And except for the cache of classes held by the java.beans.Introspector class. In at least some versions of java, introspecting a class loaded by component's classloader causes a strong reference to that class to be put into a global cache. This means that the component's classloader is then prevented from being unloaded. A workaround is to call java.beans.Introspector.flushCaches() when the component is unloaded. Some containers may do this automatically; Apache Tomcat 5.x certainly does. In other cases, a ServletContextListener may need to be registered to force this to be done.

Container libs are responsible for managing themselves

...

The problem where commons-logging would fail to initialise due to being unable to cast a Log class loaded from a component into a Log class loaded from the container is a separate issue and is not addressed here. And again avoiding abuse of the container model by keeping component libs inside the component will mean this problem never occurs.

Comments by Ceki Gulcu

Simon, I've enjoyed reading your article. Cognizant of the memory leak problem you mention, the version of log4j which is currently CVS HEAD, does "not" include a context selector based on class loaders. The only selector which is included is based on JNDI. Unless I am missing something, ContextJNDISelector does not cause memory leaks. Previous versions of log4j (e.g. 1.2) did not ship with any selectors.