On Mon, 2005-02-14 at 12:14, Ceki G�lc� wrote: > Robert, > > I am a bit surprised by your question.
i needed to make sure that i hadn't misunderstood what you were trying to say... > As the current release manager > for JCL, I suppose that you are aware that LogFactoryImpl only uses > the thread context class loader (TCCL) to search for classes. You were > aware of that, weren't you? of course > In theory, this is supposed to let a copy > of commons-logging.jar placed in a parent class loader to discover > another logging API, say log4j, whose classes are visible to a child > class loader with the child loader also set to be the TCCL. that's untrue and a little misleading: the reason why those who wrote the classloading code relied on the context classloader is that this is the classloader that should be used by well behaved components running in J2EE containers. this is what correct isolation in a container environment means. there are many consequences which spring from this design decision. some of these are a little unfortunate. i think i agree with richard that a more pragmatic (rather than dogmatic) approach would be wiser. it would better to ensure that the configuration was appropriately isolated and then load a compatible class which satisfies the configuration. i suppose some thought would need to be put into whether there are any realistic security implementations if this approach were adopted. > However, > this dynamic discovery does not work. The copy of log4j.jar must be > placed next to commons-logging.jar. this is a basic feature of delegating classloaders. (i even looked this one up to make sure my memory wasn't playing any tricks: http://java.sun.com/docs/books/vmspec/2nd-edition/html/ConstantPool.doc.html#72007) for example, suppose class Alpha is linked to class Beta which is linked to class Gamma, that classloader C is a child of classloader P, that C defines Alpha and Gamma and P Beta but not Gamma or Alpha. (apologies that my diagrams aren't up to richard's standards) Classloader Defines ----------- ------- P Beta ^ | C Alpha Gamma Links ----- Alpha -> Beta -> Gamma now consider what happens what Alpha is loaded by C. C defines Alpha which is linked to Beta. therefore C is used to load Beta. C delegates to P which defines Beta. Beta links to Gamma. P defines Beta and is therefore used to load Gamma. However, P cannot load Gamma and so everything blows up. a practical example occurs when jars containing Alpha and Gamma is placed as a utility library in an EJB container and a jar containing Beta is placed in the container base loader. the usual rule (when delegating classloaders are involved) is that any dependencies need to be placed together or higher in the classloader hierarchy. since commons-logging-api by default has a runtime dependency upon commons-logging and commons-logging (a slightly fuzzy one) upon log4j when commons-logging-api is placed in the root classloader, so must the other jars. this would be equally true for a static arrangement (UGLI say). all dependent jars would need to be placed together or higher in the hierarchy. so, i'm not sure how this pertains to the static-verses-dynamic debate. IMHO, from a practical perspective having to ensure that libraries are in the right places comes with the territory: it's something that anyone involved with deployer J2EE applications gets used to doing. > Moreover, the copy of > commons-logging.jar must be placed very high in the class loader tree, > say in the system class loader or the application server's class > loader, but that is not all. There must not be other copies of > commons-logging.jar in war files of web-apps. i'm not sure how true that is. the stock advice arises from the fact that JCL is used very widely and has a habit of turning up unexpected high in classloader hierarchy. > To cut a long story short, do to anything meaningful reliably, JCL is > a lot more complicated to set and even when set up "correctly" brings > no benefits when compared to static API binding as found in UGLI. there are several use cases when static binding is admittedly superior. (for those i would prefer byte code engineering over multiple distributions since it allows selective doping of particular components but let's keep focused on compile time solutions). however, the price of deploying a statically bound API high in the hierarchy (where JCL is expected to be able to function) is that applications can no longer be configured in isolation. so, there is price to pay. > I urge you run though the examples in [1] which should demonstrate to > you how badly and irreparably JCL is broken. The source code is all > there. Even if you don't trust my opinion, i'm very reluctant to take anyone's opinion on trust when it comes to JCL. the gestation of JCL was very difficult and the classloading code was developed over a period by senior tomcat folks. JCL also has a huge user base. in practical terms, it's successful but limited. > at least trust your java > compiler and your JVM. but it's not the code that's the issue. i just don't understand what the issue is that provokes such a strong reaction from you. the api/implementation separation doesn't work very well. this is a known issue and if this turns out to be at the root of your complaint then you'd have a point. there is actually one thing i discovered about the LogFactory that i didn't expect (but i wanted to reply before). it's better coded than i thought it was which leads me to wonder why it doesn't work better. but i wanted to finish this email before investigating... - robert --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
