You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by Jacob Kjome <ho...@visi.com> on 2004/03/27 21:13:18 UTC

Re: tiny-webapp

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.

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 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?

>     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.


Jake



---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org


Re: tiny-webapp

Posted by Ceki Gülcü <ce...@qos.ch>.
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: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org