Hello Jake,
The newly introduced changes merely generalize the concepts already found in 1.2.x. Previously, only the default repository could be automatically configured whereas now all repositories can be configured automatically.
In other words, the ContextJNDISelector provides a full-blooded (as in complete) solution to the logging separation problem consisting of a few easy installation steps. However, the are no changes in principle remain the same. There is no obligation to use ContextJNDISelector . In that case, log4j will behave the same way as in 1.2.x.
Moreover, if these installation steps for the cannot be performed for whatever reasons, for example for lack of access to the container, then the user can fallback on the default solution of including log4j.jar in WEB-INF/lib.
As for your concern for the placement of the configuration file, the user can specify a "log4j/configuration-resource" environment entry pointing to the desired config file. Only when no "log4j/configuration-resource" is specified that ContextJNDISelector will search for the files log4j.xml or log4j.properties. Note that this is very similar to the way log4j 1.2.x searches for config files for the default repository, i.e. the new code generalizes the old.
Also note that automatic configuration is optional. If no "log4j/configuration-resource" is specified and no log4j.xml or log4j.properties files can be found, then no automatic configuration will occur, as in 1.2.x.
I am pretty confident that the ContextJNDISelector will work well with the JBoss unified class loader. Placing log4j.jar in the servers class loader ensures that all application will have access to log4j. However, that does not mean that resources cannot be application specific. Actually, that is the way the unified class loaders are intended to work. Have application specific configuration resources but share the jar files which is pretty smart imho.
More comments below.
At 02:13 PM 3/27/2004 -0600, you wrote:
Hi Ceki,
At 05:31 PM 3/27/2004 +0000, you wrote:The tiny web-applications Hello and Tata demonstrate how multiple web-apps can live in separate logging contexts.
Here are the installation steps to run the examples.
Steps performed on the Java Web Server (Servlet Container) =========================================================
- Place log4j-VERSION.jar, where VERSION is 1.3 or above, in your web server's (YES, server's) shared class loader directory.
For example, for Tomcat versions 4 or 5, that would be common/lib/, for Resin version 2.1.x that would be the lib/ directory under the Resin installation folder. Other Servlet containers such as Jetty also have folders for shared jar files.
Will things break if this doesn't happen? That is, if there is a log4j.jar in WEB-INF/lib in any given webapp, do things no longer work? It should work either way. As Yoav always stresses, application dependencies should be kept with the webapp in WEB-INF/lib to maximize portability. Of course, using a repository selector in this case under Tomcat is overkill. However, other servers behave differently in how they load classes. A repository selector would be needed under JBoss or Weblogic whether one included log4j.jar in WEB-INF/lib or not since they both include Log4j at a higher level and don't seem to enforce servlet-spec recommended classloading behavior for webapps, so Log4j in the parent classloader is used in preference to the one in WEB-INF/lib. But, then again, there is no guarantee that any particular appserver uses Log4j, nor does one always have control over what classes get added to the appserver's system classloader. The only guarantee is what you decided to put into WEB-INF/lib, so this stuff needs to work whether log4j.jar is in WEB-INF/lib or in a shared classloader.
If the user cannot count on the server having installed log4j.jar, then she can still include log4j.jar in her application. More on this below.
BTW, what if different versions of Log4j are in the server and the webapp. Any clashes? Again, this is difficult to control in an environment you don't own.
- When launching your java web *server*, make sure to add the log4j.repositorySelectorClass system property on the java command line.
For the JNDIContextSelector the exact system property to add is:
-Dlog4j.repositorySelectorClass="JNDI"
Again, if you control the server, this is great. However, not all developers control the server environments. Is there a backup plan here such as the way my InitShutdownController works in logging-log4j-sandbox where it installs a repository selector if one doesn't already exist? This way, if one has no control over the server environment, a repository selector may still be used.
You can still install a repository selector through an initialization servlet or a context listener.
- You can now run the supplied web-applications hello.war and tata.war.
Steps performed per web-application ==================================
- In each web-application's web.ml file add a JNDI environment entry for the log4j logging context name. For the "Hello" web-application this takes the following form:
<env-entry> <description>JNDI logging context for this app</description> <env-entry-name>log4j/context-name</env-entry-name> <env-entry-value>hello</env-entry-value> <env-entry-type>java.lang.String</env-entry-type> </env-entry>
See also the file examples/tiny-webapp/Hello/src/WEB-INF/web.xml
- Include a log4j.properties or log4j.xml configuration file in your web-application's WEB-INF/classes directory.
This file will be automatically taken to configure the repository instance specific for your web-application.
This is great, except that I keep log4j.xml out of WEB-INF/classes for the specific reason that I gather some info at runtime and set those as environment variables before performing configuration (done via a servlet context listener). Is this still something that will continue to work, even with your changes?
There is "log4j/configuration-resource" for that case.
Note that you will need log4j-VERSION.jar to compile the web-applications but log4j-VERSION.jar file should not be included within the web-application's jar file.
Like I said above, this is not very enforceable nor necessarily a wise thing to do, so things should work whether log4j.jar is in the server's classpath only, in WEB-INF/lib only, or in both. If not, Logj4 will be too fragile for production use. I'll see if I can test out your sample webapps and verify some of this for myself and let you know if I find any quirkiness.
I don't think that placing log4j.jar systematically in both WEB-INF/lib and the server will work well on the long run. Either you put log4j.jar in the server common class path (but not in WEB-INF/lib) with the various web-apps using different logger repositories, or you place log4j.jar in WEB-INF which replies merely on class loader separation with no cooperation between the various logger repository instances.
In summary, there are two approaches.
1) Assuming some control over the server, use the ContextJNDISelector approach with no log4j.jar in the WEB-APP/lib.
2) assume nothing, place log4j.jar in WEB-APP/lib and hope for the best as is the case today.
Given that approach 1) provides for a clean, simple and headache-free solution, people will adopt it fairly quickly. If they don't, that is fine too. We will back where we were all along.
I hope the above alleviates some of the concerns you raised. In any case, I am looking forward for the results of your tests.
Jake
-- Ceki G�lc�
For log4j documentation consider "The complete log4j manual"
ISBN: 2970036908 http://www.qos.ch/shop/products/clm_t.jsp
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
