On Wed, 2005-03-16 at 00:21 -0800, Brian Stansberry wrote: > After exploring more with the JCL code, I'm almost > certain the reference to FloatConverter in > BeanUtilsBean.convertUtilsBean.converters is what's > causing o.a.c.beanutils.converter.MemoryTestCase to > fail.
I should have been a little clearer about MemoryTestCase. There are two tests that are failing: * testComponentRegistersCustomConverter This fails for a reasonably obvious reason, and it's the same one that is already documented in the javadoc for JCL's WeakHashtable class. Unfortunately as this test shows, it will be encountered quite often when people use beanutils converter functionality in a j2ee-like environment. * testComponentRegistersStandardConverter This fails for no reason I can understand. It is very similar to testComponentRegistersCustomConverter except that it does not involve loading a class via a child classloader, and therefore should not trigger the bug I believe exists. And yes, commending out the reference to FloatConverter in the testComponentRegistersStandardConverter test does make it pass; the million-dollar question is: why does the test fail when FloatConverter is used? Maybe it's because when running "maven test", the unit test code is actually run within a custom classloader? Does maven itself use BeanUtils? Hmm.. > > When I wrote before, I only said "likely" because I > couldn't see why JCL wouldn't always have the same > failure, and I had tests where it didn't. But I've > now created tests where it does (see below); tests > that are basically analogous to MemoryTestCase. Ok, I'm glad the same issue has been replicated in JCL; I thought it would be. Well, glad may be the wrong word, but at least I've not been proved a total idiot :-) > Will have to be another day before I submit a patch > for the JCL tests (after midnight now). But, I've > found in JCL the classloader is not released when > LogFactoryImpl is loaded by a parent loader and the > Log wrapper is loaded by a child. I've identified > two basic configurations where this might happen: Yep. Both of these (see below) cause exactly the scenario you originally documented in the javadoc for class WeakHashtable and that my javadoc patch expanded on (via Robert's editorial control :-). It's just that the scenario is referred to as "unusual" in the javadoc but I am now thinking it is reasonably common. > > 1) Parent-first delegation model, where the parent has > commons-logging-api.jar, child has commons-logging.jar > and child wants to use Log4j or Avalon (or some custom > Log implementation). Yep. LogFactory is loaded by parent, but Log4jLogger is loaded by child, because that class is not present in the commons-logging-api.jar file. So the WeakHashtable member of LogFactory contains an entry keyed by the child classloader, with a value object whose getClass().getClassLoader() points back to the child classloader ==> the classloader never gets gc'd. > 2) Child-first delegation model that uses the > configuration I proposed in my "Further Analysis" > document; i.e. where the parent has > commons-logging-api-xxx.jar, child has > commons-logging-impl.jar and child wants to use Log4j > or Avalon. Yep again. LogFactory loaded by parent classloader because it isn't present in the commons-logging-impl.jar file. Log4jLogger is loaded by child because it is. And this leads back to the same scenario as above. My conclusion is that writing the Singleton pattern correctly in a j2ee environment is extremely difficult, and may in fact be impossible. And unfortunately the singleton pattern is in use in a number of commons libs. I've been working on some weird ideas that *might* just work, but I'm not ready to toss them out for review yet. Note to others: this issue is quite separate from the recent debate on commons-logging "discovery". Cheers, Simon --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]