From: Ceki G. <ce...@qo...> - 2005-02-10 13:52:14
|
> Ceki is quiet right and that JCL's discover mechanism is rather > broken. The standard jetty startup tries to avoid this by setting the > system property to force a JCL factory - I assume this avoids the > dynamic discover process, but I have to say that I have not explicitly > checked this. Hi Greg, Pier, Setting the "org.apache.commons.logging.Log" system property does not avoid any of the class loader problems because the problematic code is not only in the discovery but in the *combination* of class discovery and class loading. In Jetty, does the class loader for web-applications follow child-first delegation or parent-first delegation? |
From: Ceki <ce...@qo...> - 2005-02-10 16:44:36
|
Greg, > In Jetty it is an option to load child first or parent first. From [1] I gather that child-first delegation is the default. [1] http://jetty.mortbay.org/javadoc/org/mortbay/http/ContextLoader.html > What has the reception to UGLI been? positive? are people actually > going to use it? I am not aware of anyone using UGLI for the moment, except log4j itself which relies on UGLI for internally generated logs. > I am very attracted to the simplicity of it - in that it will allow > jetty users to pick there logging mechanism of choice but without > runtime complexity. > > BUT - riddle me this log man - how would you see the following > scenarios working: > > Jetty uses UGLI api and has the ugli-log4j.jar and a log4j.jar in it's > system classpath. Not that it matters for the purposes of this discussion but there is no ugli-log4j.jar because log4j.jar already embeds all the required UGLI files. The file ugli-nop.jar embeds the UGLI interface and its NOP implementation. The file ugli-simple.jar embeds the UGLI interface and its Simple implementation. The file ugli-jdk14.jar includes the UGLI interface and the UGLI implementation wrapping java.util.logging where, needless to say, java.util.logging ships with the JDK. So, let us assume log4j.jar is in the system class path because jetty uses it. (I am just paraphrasing your example.) > A webapp has it's own log log4j.jar (potentially different version to > that used by Jetty) and is running in child-first delegation. OK. > How would the two instances of log4j be configured? what search path > would the webapps log4j perform looking for it's configuration (could > be an ancient log4j). Before the web-app can be configured, log4j classes must be loaded into memory. Jetty will load log4j classes from the system class path while the web-app will load log4j classes from the class loader of the web-app. So at least at the java class level, you will get isolation. (Assuming child-first delegation for the web-app class loader.) Once the log4j (or UGLI) classes are loaded into memory, we can consider configuration of the logging environment. Since log4j 1.2 and log4j 1.3 automatically search for default configuration files, namely log4j.xml and log4j.properties. If jetty exposed its config file, say, log4j.xml, and the web-app does not contain a default config file, then the copy of log4j loaded by the wep-app would inherit jetty's default config file. Both Jetty and the web-app would have distinct log4j environments sharing the same configuration. The results would not be pretty as the conflicting environments would clobber each other's log files and other system resources. Jetty could very easily avoid such an unfavorable turn of events by not exposing its config file. For example by using a config file named jetty-log4j.xml instead of log4j.xml. It's not more complicated than that. > How would this change if parent first loading was used? (I'll attempt > to answer this... webapp would see global log4j and either work or > crash if API had changed too much - which is reasonable I think). In principle, yes. Note that the log4j API that users directly access in their java code is quite small. Most of the set up is done through config files. Let me put this to you this way: the API that users access directly is not about to change in an backward incompatible way anytime soon. > Some other questions to consider. The servlet spec says that a > servers implementation classes should not be available to the webapp. > Would you consider UGLI (or log4j) part of server implementation? Yes, UGLI could be considered as part of the server. One of the goals in log4j 1.3 is to enable the use of log4j by any piece of code, even code that log4j requires for its own use. > Should it be hidden from the webapp? I may actually make this > configurable in Jetty, so that you can hide an arbitrary set of > packages from webapps. As a user of Jetty, I would not care if Jetty hid its copy of UGLI from my web-applications as long as Jetty allowed me (the user) to configure the log format and destination as well as the logging API (log4j, jdk14, ...) to my liking. If there is interest I could also mention how you could achieve separation of logging contexts even if only a single copy of log4j.jar were present in the system. Cheers, --=20 Ceki G=FClc=FC The complete log4j manual: http://www.qos.ch/log4j/ |
From: Greg W. <gr...@mo...> - 2005-02-10 21:07:16
|
Ceki Gülcü wrote: > lots of good answers. OK I'm even more tempted..... I'm going to be opening a beta branch of 5.2.x series for Jetty in the next few days/weeks and I'll try making a conversion to using log4j via the UGLI API. That will avoid the discovery problem. With the classloading config I have just added, I think almost any combination/unification of server/webapp configuration should be possible. Eg. even if a webapp has a log4.jar and is in child-first mode, you could list the org.apache.log4j API as a system class and thus force the webapp to use the jetty version of it! Users will be able to plug in other logging implementations using the UGLI API if they wish (and I will may port the Jetty logs mechanism to it if there is demand) And of course it is big benefit to use a logging system whose author reads the Jetty lists :-) So does anybody object to that rough plan for the future? cheers |
From: Ceki <ce...@qo...> - 2005-02-11 15:00:41
|
At 10:06 PM 2/10/2005, Greg Wilkins wrote: >Ceki G=FClc=FC wrote: >>lots of good answers. > >OK I'm even more tempted..... I'm going to be opening a beta branch of=20 >5.2.x series >for Jetty in the next few days/weeks and I'll try making a conversion to=20 >using log4j via >the UGLI API. > >That will avoid the discovery problem. With the classloading config I=20 >have just added, I think >almost any combination/unification of server/webapp configuration should=20 >be possible. >Eg. even if a webapp has a log4.jar and is in child-first mode, you could= =20 >list the org.apache.log4j API as a system class and thus force the webapp= =20 >to use the jetty version of it! If Jetty is going to use log4j, you might want to consider whether=20 ContextJNDISelector can be installed by Jetty. Even without any specific=20 support by Tomcat, ContextJNDISelector works remarkably well. It ships with= =20 log4j version 1.3. You can read more about ContextJNDISelector below: http://cvs.apache.org/viewcvs.cgi/logging-log4j/examples/tiny-webapp/INSTALL= .txt?rev=3D1.9 Installing ContextJNDISelector will allow web-applications to have an=20 entirely separate logging environment even if the log4j classes are loaded= =20 into memory only once, for example by Jetty itself. >Users will be able to plug in other logging implementations using the UGLI= =20 >API if they wish >(and I will may port the Jetty logs mechanism to it if there is demand) Just shout if you need help. The current version of UGLI uses static=20 (compile time) binding. To do this, we create a custom version of=20 LoggerFactory.java for each logging API. So in order to add a new API, you= =20 would need a custom copy of LogFactory.java. See [1] for the ant build file= =20 wherein the only mildly interesting task is "ugli-IMPL.jar". [1]=20 http://cvs.apache.org/viewcvs.cgi/logging-log4j/ugli.xml?rev=3D1.7&view=3Dma= rkup It is really much simpler than it sounds. >And of course it is big benefit to use a logging system whose author reads= =20 >the Jetty lists :-) I'll do my best to help. --=20 Ceki G=FClc=FC The complete log4j manual: http://www.qos.ch/log4j/ |
From: Ceki <ce...@qo...> - 2005-02-10 17:11:10
|
On Thu, 10 Feb 2005 14:30:19 +0000, Yannick Menager wrote: > No, actually that's the whole reason behind using the ClassLoader > Factory cache, each classloader has it's own private log > implementation. So two webapps can each have it's own private version > of log4j, for example. In that aspect the JCL discovery system is > quite good, the problem comes from the fact that they use the > Hashtable to map ClassLoader to Factory, which is the root of all the > JCL evils. However that is easily solved by using a WeakHashMap > instead ( losing 1.1 compatibility by doing that ). Hello Yannick, Problems of Type-III, that is holding references to class loader instances, is just the tip of the iceberg. JCL's problems of Type-I and Type-II are more subtle, harder to spot and tend to be diffused throughout the code. Unless you have a JVM embedded in your brain, you can be staring at the bug for an hour and still not see that it is there. --=20 Ceki G=FClc=FC The complete log4j manual: http://www.qos.ch/log4j/ |
From: Yannick M. <yan...@fa...> - 2005-02-10 23:50:07
|
Ceki Gülcü wrote: > > On Thu, 10 Feb 2005 14:30:19 +0000, Yannick Menager wrote: > > > No, actually that's the whole reason behind using the ClassLoader > > Factory cache, each classloader has it's own private log > > implementation. So two webapps can each have it's own private version > > of log4j, for example. In that aspect the JCL discovery system is > > quite good, the problem comes from the fact that they use the > > Hashtable to map ClassLoader to Factory, which is the root of all the > > JCL evils. However that is easily solved by using a WeakHashMap > > instead ( losing 1.1 compatibility by doing that ). > > Hello Yannick, > > Problems of Type-III, that is holding references to class loader > instances, is just the tip of the iceberg. JCL's problems of Type-I > and Type-II are more subtle, harder to spot and tend to be diffused > throughout the code. Unless you have a JVM embedded in your brain, you > can be staring at the bug for an hour and still not see that it is > there. Hmm... interesting, i thought that was the only problem... Can you point me to some more details on those Type-II problems |
From: Yannick M. <yan...@fa...> - 2005-02-11 00:11:20
|
Yannick Menager wrote: > Ceki Gülcü wrote: > >> >> On Thu, 10 Feb 2005 14:30:19 +0000, Yannick Menager wrote: >> >> > No, actually that's the whole reason behind using the ClassLoader >> > Factory cache, each classloader has it's own private log >> > implementation. So two webapps can each have it's own private version >> > of log4j, for example. In that aspect the JCL discovery system is >> > quite good, the problem comes from the fact that they use the >> > Hashtable to map ClassLoader to Factory, which is the root of all the >> > JCL evils. However that is easily solved by using a WeakHashMap >> > instead ( losing 1.1 compatibility by doing that ). >> >> Hello Yannick, >> >> Problems of Type-III, that is holding references to class loader >> instances, is just the tip of the iceberg. JCL's problems of Type-I >> and Type-II are more subtle, harder to spot and tend to be diffused >> throughout the code. Unless you have a JVM embedded in your brain, you >> can be staring at the bug for an hour and still not see that it is >> there. > > Hmm... interesting, i thought that was the only problem... Can you point > me to some more details on those Type-II problems OOOPSS... My bad... it's on that link :) Nevermind that.. long day lol |
From: Yannick M. <yan...@fa...> - 2005-02-11 01:51:50
|
Ceki Gülcü wrote: > Problems of Type-III, that is holding references to class loader > instances, is just the tip of the iceberg. JCL's problems of Type-I > and Type-II are more subtle, harder to spot and tend to be diffused > throughout the code. Unless you have a JVM embedded in your brain, you > can be staring at the bug for an hour and still not see that it is > there. Yup you're quite right... However i'm thinking that actually that is a problem introduced by the container ( because it uses a 'non-tipical' child-first classloader ), that can be solved by the container, by further customizing the classloader to be parent-first when the logging framework classes are requested. Or is there other issues that would make that difficult or impossible ? |
From: Greg W. <gr...@mo...> - 2005-02-11 08:34:56
|
Yannick Menager wrote: > However i'm thinking that actually that is a problem introduced by the > container ( because it uses a 'non-tipical' child-first classloader ), > that can be solved by the container, by further customizing the > classloader to be parent-first when the logging framework classes are > requested. Or is there other issues that would make that difficult or > impossible ? Your bad again :-) That's what I just posted - Jetty in CVS now allows the loader to be configured with classes that are system (always parent first) or that are server (invisible) classes. This as you say can allows a child-first webapp to load its logging from the server, even if it has it's own logging classes. cheers. |
From: Yannick M. <yan...@fa...> - 2005-02-11 20:37:38
|
Greg Wilkins <gregw <at> mortbay.com> writes: > Your bad again > > That's what I just posted - Jetty in CVS now allows the loader to > be configured with classes that are system (always parent first) or > that are server (invisible) classes. > > This as you say can allows a child-first webapp to load its logging > from the server, even if it has it's own logging classes. *kicks himself in the backside* Ok... No more posting at 2am when brain has already gone in power-saving mode ;) |
From: Greg W. <gr...@mo...> - 2005-02-10 14:10:10
|
Ceki, In Jetty it is an option to load child first or parent first. What has the reception to UGLI been? positive? are people actually going to use it? I am very attracted to the simplicity of it - in that it will allow jetty users to pick there logging mechanism of choice but without runtime complexity. BUT - riddle me this log man - how would you see the following scenarios working: Jetty uses UGLI api and has the ugli-log4j.jar and a log4j.jar in it's system classpath. A webapp has it's own log log4j.jar (potentially different version to that used by Jetty) and is running in child-first delegation. How would the two instances of log4j be configured? what search path would the webapps log4j perform looking for it's configuration (could be an ancient log4j). How would this change if parent first loading was used? (I'll attempt to answer this... webapp would see global log4j and either work or crash if API had changed too much - which is reasonable I think). Some other questions to consider. The servlet spec says that a servers implementation classes should not be available to the webapp. Would you consider UGLI (or log4j) part of server implementation? Should it be hidden from the webapp? I may actually make this configurable in Jetty, so that you can hide an arbitrary set of packages from webapps. cheers Ceki Gulcu wrote: >>Ceki is quiet right and that JCL's discover mechanism is rather >>broken. The standard jetty startup tries to avoid this by setting the >>system property to force a JCL factory - I assume this avoids the >>dynamic discover process, but I have to say that I have not explicitly >>checked this. > > > Hi Greg, Pier, > > Setting the "org.apache.commons.logging.Log" system property does not > avoid any of the class loader problems because the problematic code is > not only in the discovery but in the *combination* of class discovery > and class loading. > > In Jetty, does the class loader for web-applications follow > child-first delegation or parent-first delegation? > > > > > ------------------------------------------------------- > SF email is sponsored by - The IT Product Guide > Read honest & candid reviews on hundreds of IT Products from real users. > Discover which products truly live up to the hype. Start reading now. > http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click |