You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-user@logging.apache.org by Jacob Kjome <ho...@visi.com> on 2004/06/22 15:44:54 UTC

UGLI -vs- Monitor (was: Re: conversion patterns and caller class information)

I completely missed this reply for some reason.  Sorry to bring it up 
again, but just a couple comments...

At 04:04 PM 6/8/2004 +0200, you wrote:
>If we take a concrete example, namely logging in ANT, then one can
>clearly see that ANT is following a listener pattern (a.k.a monitor
>pattern). Claiming that the monitor pattern is a general solution to
>most logging problems is imho not based on reality but on wishful
>thinking. In the ANT case, ANT *is* the application. It can set up the
>logging environment as it sees fit. When the Main class in ANT sets
>the logger listener the rest of the ANT components such as tasks and
>targets all say Amen, and that's the end of the logging
>problem. Moreover, ANT already has an event model which is useful
>independently of its logging aspects, although in the BuildListener
>case, the interface is tainted by logging-specific methods.

So it would be better for Ant classes to arbitrarily use Loggers which 
could be named in any which way or even to use arbitrary logging 
implementations in each class (Note: I haven't verified the Ant source to 
see how logging is set up)?  Whatever Ant is doing, the use of a Monitor 
forces all classes to use the same sort of logging mechanism.  Logging 
becomes componentized and consistent.  Anyway, I'm not going to attempt to 
defend Ant logging because I really don't know how it is implemented.  I 
don't really use it much.

>IMHO, the monitor pattern maybe useful under certain circumstances. It
>is not a universally applicable pattern. I just don't buy the argument
>that it demands less on the environment and can serve as a more
>general pattern.

The pattern *is* general, the implementation of the pattern is more 
specific.  Encapsulated within Prevayler, the pattern works right in 
concert with everything else since Prevayler is pretty well componentized 
based on its own defined interfaces.  And it *does* demand less on the 
environment, other than the initial configuration.  But that isn't so hard 
using the PrevaylerFactory which provides defaults for things you don't 
want to set yourself.  The defaults, of course, use component 
implementations which don't require libraries outside of Prevayler.

>I don't think the unsuspecting library author gains much in swapping
>the a dependence on the UGLI API on a dependence on the monitor
>API. It only makes sense if you consider logging as a very secondary
>feature (which btw might be a well justified hypothesis) and you
>already have a monitor interface built in your software.

Which is why I think we are arguing past each other.  The Monitor *is* 
built into Prevayler.  The Monitor interface is localized, not 
external.  It is how Prevayler provides the user with its internal logging 
messages.  Because the Monitor interface is internal, it removes any 
dependency on an external logging library or set of interfaces like 
UGLI.  I love Log4j, but there are times when I just want to use a piece of 
software and don't care about seeing logging output, yet there is always a 
dependency on Log4j whether I want to use it or not when using Log4j in the 
classic way.  If I don't put it in the classpath, the application 
breaks.  Usually this is not too painful, but is it absolutely 
necessary?  I think the Monitor shows that it is not.

>Basically, using the monitor interface is equivalent to saying screw
>logging, which is btw perfectly OK.

Like I said above, in certain cases, yes.  But keep in mind that this is 
not the author saying "screw logging" and simply removing any sort of 
logging from the software (as does Picocontainer).  This is left up to the 
user.  If they want to see logging, they can see it in any sort of way they 
want.  Heck, they can provide their own Log4jMonitor implementation and 
change the way loggers are named.  How can you argue with the user?  If the 
user doesn't want logging, they are not "wrong".  That's like saying 
because I don't want to... buy a new computer, I am "wrong".  The concept 
doesn't even make sense.  On the other hand, if the author decides to 
"screw logging", you have an argument because the user may want to see what 
is happening and the author is hiding the internal workings of the 
application against the user's wishes.  After all, it is the user who 
counts.  Software may be authored, but if it is not used, it is worthless.

More below...


>At 01:30 AM 6/8/2004, Jacob Kjome wrote:
>
>>>If you read Paul Hammant's article as well as
>>>http://wiki.apache.org/avalon/AvalonNoLogging carefully, you should
>>>realize that the Monitor idea is really about the irrelevance of logging
>>>output. The Monitor technique is a way for library authors ignore the
>>>logging issue with the option of enabling it if the end user really
>>>wants it. The monitor's approach does not solve the problem it claims
>>>it solves, it just defers it. Hence, it's appeal to the unsuspecting
>>>masses.
>>
>>Whatever the motivations of Paul Hammant (who is also responsible for 
>>AvalonNoLogging, BTW), I don't think that the Monitor makes logging 
>>irrelevant.  If we didn't want logging at all, we wouldn't be using the 
>>Monitor interface in the first place.
>
>Not true. The assumption is that you have a listener interface to
>begin with.

No, it was developer consensus that there be no default runtime dependency 
on any logging API and no non-configurable logging 
(ie.  System.out.println()).  That meant either using the Monitor concept 
or removing logging altogether.   The fact that we chose the Monitor rather 
than no logging whatsoever is a clear indication that we found logging to 
be relevant.


>>  What this buys us is a way for the user to decide whether they want 
>> logging and, if so, what implementation to use (ie.  what external 
>> libraries do I, the user, want to declare a dependency upon).  The 
>> Log4jMonitor is there in case they want to use Log4j, in which case they 
>> can use their standard Log4j config file and view logging messages from 
>> Prevayler just like they do in their own application.  They don't need 
>> to know anything special about how a Monitor works since it doesn't 
>> change the way they think about logging in the first place.  Please go 
>> into more detail about why a user should have reason to "suspect" anything!
>
>Sweeping the dirt under the rug does not actually clean anything. It
>just moves the dirt to a less visible place. The unsuspecting masses
>will say, we can't see the dirt, it must be gone.

What dirt?  What's under the rug?  Oh, you mean...

public class MyClass {
     private static final Logger logger = Logger.getLogger(MyClass.class);
}

versus...

public class MyClass {
     private Logger;

     public MyClass(Logger logger) {
         this.logger = logger;
     }
}

Which one looks more like "dirt under the rug" to you?


>>>>Like I said, the above would be just fine, except that the idea that 
>>>>every logging framework out there would implement that interface is 
>>>>unlikely and the fact that the Monitor is meant for internal use (while 
>>>>still being able to use a single Log4j logging configuration chosen by 
>>>>the user just like normal if the Log4jMonitor interface is used).
>>>
>>>What a library author needs from the logging API is for it to be
>>>
>>>1) non-disruptive
>>
>>Yep, the Monitor succeeds at this.
>>
>>>2) Integrate seamlessly with the user's existing logging environment
>>
>>Yep, the Monitor succeeds at this.
>
>Not true. The monitor interface makes logging pluggable as much as
>logger injection would. However, this does not mean seamless
>integration within a bigger environment. For example, I don't think it
>is possible to get Ant logging integrating from the context of a
>bigger application, say a web-application.

Fine, I'm not arguing about Ant logging.  Like I said, I know very little 
about it.  The Prevayler Monitor interface is perfectly useable under any 
environment you want it to run in and *is* seamless other than the fact 
that if you want to use the Log4jMonitor, you will have to configure 
Prevayler to use it (and make sure Log4j is in the classpath, of course), 
but that is all part of starting up Prevayler.  It would be pretty weak to 
claim that, for this reason, that the Monitor fails to provide "seamless" 
logging integration.

>>>JDK 1.4 logging is unlikely to switch to UGLI but that does not mean
>>>that one cannot write an UGLI adapter for JDK 1.4 logging. As for the
>>>various Avalon logging APIs, I expect them to *eventually* adopt UGLI,
>>>although one can never be sure.
>>
>>I wonder if we are discussing the same thing?  The Monitor doesn't 
>>interfere with anything, removes a runtime dependency on any particular 
>>logging api except via the user's explicit choice to depend on it, and 
>>free's the library author to set up an internal logging paradigm of 
>>his/her own choice while, at the same time, leaving the user unaffected.
>>
>>UGLI is a fine interface, but does create a dependency on an external 
>>package (however minimal or trivial one might view that) and it fails to 
>>free the library author from a logging paradigm of his/her own choice. 
>>UGLI still doesn't solve the Logging API dependency problem.  for 
>>instance in the classic Log4j usage...
>>
>>private static final org.apache.ugli.Logger logger = 
>>org.apache.log4j.Logger.getLogger(MyClass.class.getName());
>
>Not exactly, it's going to be:
>
>private final o.a.ugli.Logger logger = 
>o.a.ugli.LoggerFacade.getLoggerRepository().getLogger("x");

That's certainly better, although the idea of an UGLI adapter for JDK1.4 
logging smells like commons-logging.

>No dependency on log4j but UGLI alone. The application can configure
>the UGLI LoggerFacade which logging repository it wants to use in a
>particular context.

That's great.  Will Log4j-1.3 be UGLI compatible?  When will the other 
API's?  Again, I think the adapter smells like commons-logging and I try to 
stay as far away from that as I can.

>Oh, by the way the LoggerFacade can be static or dynamic, I don't
>know yet.
>
>>What does this buy us?  There is now not only a dependency on the Log4j 
>>package but also the UGLI package without providing any benefit to the 
>>user.... unless you pass in the UGLI Logger via IOC, in which case the 
>>UGLI api becomes useful as a Logging implementation-neutral API.  Are you 
>>following me here?  Am I following you?
>
>OK, the IOC approach has the most flexibility. However, we cannot always 
>assume IOC.

Ok, there's the disconnect.  My question to you is "when will IOC *not* be 
available"?  See the example of MyClass above which takes a Logger as a 
parameter of its constructor.  That's IOC.  The "C" stands for "Control", 
not "Container".  That's why apps written with the idea of using 
Picocontainer, generally, don't depend on Picocontainer.  The container can 
help to do many things that might be consider drudgery or simply help avoid 
writing extra code.  However, you can always do..

o.a.ugli.Logger logger = 
o.a.ugli.LoggerFacade.getLoggerRepository().getLogger("x");
MyClass obj = new MyClass(logger);

Of course the issue here is that the logger is named in one specific 
way.  That's where the Monitor comes in.  UGLI would solve this by 
providing, for instance..

public void debug(Class clazz, Object msg, Throwable t);

Where the Class parameter is the class in which logging is to be provided 
for.  The name of the logger will be obtained from the Class 
parameter.  And that's really what the Monitor does.

   void error(Class clazz, String message, Exception ex) {
       Logger.getLogger(clazz).log(callerFQCN, level, message, ex);
   }

All that said, if UGLI became a universally adopted API, I'd certainly use 
it for my own applications.  The Monitor still wouldn't be obsolete, since 
it would continue to remove any mandatory external runtime dependency, but 
that argument becomes less powerful with a logging API that is a just a few 
K in size.

Jake

>>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-user-unsubscribe@logging.apache.org
>For additional commands, e-mail: log4j-user-help@logging.apache.org


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


Re: problem with log4j on weblogic 8.1 on linux

Posted by Jacob Kjome <ho...@visi.com>.
Quoting Keith <kh...@aol.com>:

> Hi,
> 
> I have a problem deploying a war file containing log4j1.2.8.jar on
> weblogic 8.1 sp2 running on RedHat  kernal version 2.4.21-4
> 
> The strange thing is it deploys fine on tomcat, and weblogic running on
> windows. Just loses it when I try to deploy it on linux?
> 
> Once I remove the log4j jar it deploys fine.
> 
> Any ideas? Anyone seen this before?
> 

I would guess that you are experiencing classloader problems.  Maybe you have a
couple different instances of Log4j in Weblogic?  Seems like they might be
different versions as well.  Beyond that, i can't tell you much.  Weblogic can
be classloader hell, at least in my experience.

Jake


> Below is the exception
> 
> CHeers,
> Keith
> 
> <22-Jun-2004 11:38:58 o'clock IST> <Warning> <Deployer> <BEA-149004>
> <Failures were detected while initiating Deploy task for application
> rsistats.>
> <22-Jun-2004 11:38:58 o'clock IST> <Error> <Deployer> <BEA-149201>
> <Failed to complete the deployment task with ID 0 for the application
> rsistats.
> java.lang.NoSuchMethodError:
> org.apache.log4j.spi.RootCategory.<init>(Lorg/apache/log4j/Level;)V
>          at org.apache.log4j.LogManager.<clinit>(LogManager.java:69)
>          at org.apache.log4j.Logger.getLogger(Logger.java:85)
>          at
> org.apache.commons.logging.impl.Log4JLogger.<init>(Log4JLogger.java:102)
>          at
> sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
>          at
>
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
>          at
>
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
>          at java.lang.reflect.Constructor.newInstance(Constructor.java:274)
>          at
>
org.apache.commons.logging.impl.LogFactoryImpl.newInstance(LogFactoryImpl.java:525)
>          at
>
org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:272)
>          at
>
org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:246)
>          at
> org.apache.commons.logging.LogFactory.getLog(LogFactory.java:395)
>          at
> com.sun.faces.config.ConfigureListener.<clinit>(ConfigureListener.java:95)
>          at
> sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
>          at
>
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
>          at
>
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
>          at java.lang.reflect.Constructor.newInstance(Constructor.java:274)
>          at java.lang.Class.newInstance0(Class.java:306)
>          at java.lang.Class.newInstance(Class.java:259)
>          at
>
weblogic.servlet.internal.WebAppServletContext.registerEventListener(WebAppServletContext.java:2808)
>          at
>
weblogic.servlet.internal.WebAppServletContext.activateFromDescriptors(WebAppServletContext.java:2383)
>          at
>
weblogic.servlet.internal.WebAppServletContext.activate(WebAppServletContext.java:5610)
>          at
>
weblogic.servlet.internal.WebAppServletContext.setActive(WebAppServletContext.java:5588)
>          at
> weblogic.servlet.internal.WebAppModule.activate(WebAppModule.java:841)
>          at
>
weblogic.j2ee.J2EEApplicationContainer.activateModule(J2EEApplicationContainer.java:3127)
>          at
>
weblogic.j2ee.J2EEApplicationContainer.activate(J2EEApplicationContainer.java:2081)
>          at
>
weblogic.j2ee.J2EEApplicationContainer.activate(J2EEApplicationContainer.java:2062)
>          at
>
weblogic.management.deploy.slave.SlaveDeployer$ComponentActivateTask.activateContainer(SlaveDeployer.java:2592)
>          at
>
weblogic.management.deploy.slave.SlaveDeployer$ActivateTask.doCommit(SlaveDeployer.java:2515)
>          at
>
weblogic.management.deploy.slave.SlaveDeployer$Task.commit(SlaveDeployer.java:2317)
>          at
>
weblogic.management.deploy.slave.SlaveDeployer$Task.checkAutoCommit(SlaveDeployer.java:2399)
>          at
>
weblogic.management.deploy.slave.SlaveDeployer$Task.prepare(SlaveDeployer.java:2311)
>          at
>
weblogic.management.deploy.slave.SlaveDeployer$ActivateTask.prepare(SlaveDeployer.java:2479)
>          at
>
weblogic.management.deploy.slave.SlaveDeployer.processPrepareTask(SlaveDeployer.java:798)
>          at
>
weblogic.management.deploy.slave.SlaveDeployer.prepareDelta(SlaveDeployer.java:507)
>          at
>
weblogic.management.deploy.slave.SlaveDeployer.prepareUpdate(SlaveDeployer.java:465)
>          at
> weblogic.drs.internal.SlaveCallbackHandler$1.execute(SlaveCallbackHandler.java:25)
>          at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:197)
>          at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:170)
> --------------- nested within: ------------------
> weblogic.management.ManagementException:  - with nested exception:
> [java.lang.NoSuchMethodError:
> org.apache.log4j.spi.RootCategory.<init>(Lorg/apache/log4j/Level;)V]
>          at
>
weblogic.management.deploy.slave.SlaveDeployer$ActivateTask.prepare(SlaveDeployer.java:2491)
>          at
>
weblogic.management.deploy.slave.SlaveDeployer.processPrepareTask(SlaveDeployer.java:798)
>          at
>
weblogic.management.deploy.slave.SlaveDeployer.prepareDelta(SlaveDeployer.java:507)
>          at
>
weblogic.management.deploy.slave.SlaveDeployer.prepareUpdate(SlaveDeployer.java:465)
>          at
> weblogic.drs.internal.SlaveCallbackHandler$1.execute(SlaveCallbackHandler.java:25)
>          at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:197)
>          at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:170)
>  >
> 
> 
> 
> 
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
> For additional commands, e-mail: log4j-user-help@logging.apache.org

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


problem with log4j on weblogic 8.1 on linux

Posted by Keith <kh...@aol.com>.
Hi,

I have a problem deploying a war file containing log4j1.2.8.jar on 
weblogic 8.1 sp2 running on RedHat  kernal version 2.4.21-4

The strange thing is it deploys fine on tomcat, and weblogic running on 
windows. Just loses it when I try to deploy it on linux?

Once I remove the log4j jar it deploys fine.

Any ideas? Anyone seen this before?

Below is the exception

CHeers,
Keith

<22-Jun-2004 11:38:58 o'clock IST> <Warning> <Deployer> <BEA-149004> 
<Failures were detected while initiating Deploy task for application 
rsistats.>
<22-Jun-2004 11:38:58 o'clock IST> <Error> <Deployer> <BEA-149201> 
<Failed to complete the deployment task with ID 0 for the application 
rsistats.
java.lang.NoSuchMethodError: 
org.apache.log4j.spi.RootCategory.<init>(Lorg/apache/log4j/Level;)V
         at org.apache.log4j.LogManager.<clinit>(LogManager.java:69)
         at org.apache.log4j.Logger.getLogger(Logger.java:85)
         at 
org.apache.commons.logging.impl.Log4JLogger.<init>(Log4JLogger.java:102)
         at 
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
         at 
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
         at 
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
         at java.lang.reflect.Constructor.newInstance(Constructor.java:274)
         at 
org.apache.commons.logging.impl.LogFactoryImpl.newInstance(LogFactoryImpl.java:525)
         at 
org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:272)
         at 
org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:246)
         at 
org.apache.commons.logging.LogFactory.getLog(LogFactory.java:395)
         at 
com.sun.faces.config.ConfigureListener.<clinit>(ConfigureListener.java:95)
         at 
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
         at 
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
         at 
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
         at java.lang.reflect.Constructor.newInstance(Constructor.java:274)
         at java.lang.Class.newInstance0(Class.java:306)
         at java.lang.Class.newInstance(Class.java:259)
         at 
weblogic.servlet.internal.WebAppServletContext.registerEventListener(WebAppServletContext.java:2808)
         at 
weblogic.servlet.internal.WebAppServletContext.activateFromDescriptors(WebAppServletContext.java:2383)
         at 
weblogic.servlet.internal.WebAppServletContext.activate(WebAppServletContext.java:5610)
         at 
weblogic.servlet.internal.WebAppServletContext.setActive(WebAppServletContext.java:5588)
         at 
weblogic.servlet.internal.WebAppModule.activate(WebAppModule.java:841)
         at 
weblogic.j2ee.J2EEApplicationContainer.activateModule(J2EEApplicationContainer.java:3127)
         at 
weblogic.j2ee.J2EEApplicationContainer.activate(J2EEApplicationContainer.java:2081)
         at 
weblogic.j2ee.J2EEApplicationContainer.activate(J2EEApplicationContainer.java:2062)
         at 
weblogic.management.deploy.slave.SlaveDeployer$ComponentActivateTask.activateContainer(SlaveDeployer.java:2592)
         at 
weblogic.management.deploy.slave.SlaveDeployer$ActivateTask.doCommit(SlaveDeployer.java:2515)
         at 
weblogic.management.deploy.slave.SlaveDeployer$Task.commit(SlaveDeployer.java:2317)
         at 
weblogic.management.deploy.slave.SlaveDeployer$Task.checkAutoCommit(SlaveDeployer.java:2399)
         at 
weblogic.management.deploy.slave.SlaveDeployer$Task.prepare(SlaveDeployer.java:2311)
         at 
weblogic.management.deploy.slave.SlaveDeployer$ActivateTask.prepare(SlaveDeployer.java:2479)
         at 
weblogic.management.deploy.slave.SlaveDeployer.processPrepareTask(SlaveDeployer.java:798)
         at 
weblogic.management.deploy.slave.SlaveDeployer.prepareDelta(SlaveDeployer.java:507)
         at 
weblogic.management.deploy.slave.SlaveDeployer.prepareUpdate(SlaveDeployer.java:465)
         at 
weblogic.drs.internal.SlaveCallbackHandler$1.execute(SlaveCallbackHandler.java:25)
         at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:197)
         at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:170)
--------------- nested within: ------------------
weblogic.management.ManagementException:  - with nested exception:
[java.lang.NoSuchMethodError: 
org.apache.log4j.spi.RootCategory.<init>(Lorg/apache/log4j/Level;)V]
         at 
weblogic.management.deploy.slave.SlaveDeployer$ActivateTask.prepare(SlaveDeployer.java:2491)
         at 
weblogic.management.deploy.slave.SlaveDeployer.processPrepareTask(SlaveDeployer.java:798)
         at 
weblogic.management.deploy.slave.SlaveDeployer.prepareDelta(SlaveDeployer.java:507)
         at 
weblogic.management.deploy.slave.SlaveDeployer.prepareUpdate(SlaveDeployer.java:465)
         at 
weblogic.drs.internal.SlaveCallbackHandler$1.execute(SlaveCallbackHandler.java:25)
         at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:197)
         at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:170)
 >







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