Page 1 of 2 12 LastLast
Results 1 to 10 of 22

Thread: Remove Commons Logging in favor of Log4j 1.3 UGLI

Hybrid View

  1. #1
    Join Date
    Aug 2004
    Location
    Seattle
    Posts
    30

    Default Remove Commons Logging in favor of Log4j 1.3 UGLI

    When Log4j 1.3 comes out it, it will be suggesting that people use UGLI (funny ackronym) rather than Jakarta Commons Logging (JCL) due to the class loading hell it causes as described in this doc:

    http://www.qos.ch/logging/classloader.jsp

    Here is the UGLI documentation link:
    http://logging.apache.org/log4j/docs/ugli.html

    You basically use it just like JCL. My main rant is that I would rather call a log variable "log" rather than "logger". Less typing. I would also just like 1 import if at all possible.

    Both future version of Jetty and XMLC look like they will be switching. It seams like a better way to do it. I'm wondering if Spring might switch in a future version.

    Cameron

  2. #2
    Join Date
    Aug 2004
    Location
    San Mateo, CA
    Posts
    1,265

    Default

    We haven't thought of switching at this point. It would be interesting to try to discuss any switch across popular packages like Spring/Struts etc. that presently use Commons Logging. Otherwise, just one project switching on its own isn't likely to make much difference.
    Rod Johnson - GM, SpringSource Division, VMware
    http://www.springsource.com
    Spring From the Source

  3. #3
    Join Date
    Nov 2005
    Location
    México, D.F.
    Posts
    1

    Post Why wait?

    Quote Originally Posted by Rod Johnson
    Otherwise, just one project switching on its own isn't likely to make much difference.
    So you're saying that Spring will change only if other project does it before? I like spring cause it is really simple and powerfull but have you noticed how many post relating to log config problems are in this forum? I know it isn't a spring fault but wouldn't be nice if spring (and perhaps other projects)would provide two distributions, one with JCL an other with SLF4J so spring users don't have to wait till other projects do it before.

    Yes, i know there still would be other project using JCL and we will has to face 2 facades but if no project wants to be first then how its supossed to achieve this goal.
    Last edited by edgarcruz; Nov 18th, 2005 at 11:23 AM.

  4. #4
    Join Date
    Nov 2005
    Posts
    1

    Default Gradual migration

    SLF4J also allows for a gradual migration path away from JCL. For more details see http://www.slf4j.org/manual.html#gradual

  5. #5
    Join Date
    May 2005
    Location
    San Francisco
    Posts
    61

    Default

    It looks like release of JCL 1.0.5 is nearing that's supposed to fix most of the problems associated with multi-classloader environment.

    Unfortunetely, some of the issues will probably go unfixed. One of the problems I keep running into is the log creation in the shared environment. For instance, we have Spring libraries deployed in the shared location (Tomcat's shared/lib).

    I recently talked to Simon Kitching [skitching@apache.org] on this issue and he pointed out:
    Do you mean that you have a class in a "shared" location with this?
    private static Log log = LogFactory.getLog("...");

    The use of static fields for loggers in a class that may be shared is a
    known issue and is described in the FAQ. The answer is to *not* use
    static fields; make the logger an instance member.

    Or even better, don't deploy classes in "shared" locations. I personally
    believe this is not good design; applications in a container are meant
    to be independent.
    I don't really see a reason to move Spring to application's war instead of shared/lib. Spring is shared-lib and TCCL friendly, so I wanted to take advantage of this.

    As for static logs, I noticed Spring's classes do use instance logs in many cases with exception of mainly helper classes, such as DataSourceUtils.

    Would it be possible to get rid of the static logs for such classes? This would basically mean, that Spring is completely shared-CL friendly.
    thanks,
    Dimitry E Voytenko

  6. #6
    Join Date
    Dec 2005
    Posts
    16

    Default

    Quote Originally Posted by dvoytenko
    I recently talked to Simon Kitching [skitching@apache.org] on this issue and he pointed out:

    Quote Originally Posted by Simon Kitching
    Or even better, don't deploy classes in "shared" locations. I personally believe this is not good design; applications in a container are meant to be independent.
    I agree with Simon -- putting libs in shared locations isn't the best way to go.

    Problems that sharing libs can cause:
    1. Class loader problems - you found this one
    2. Independance - what if you want to deploy two instances of your app - one with spring 1.2 and one with 2.0?
    3. Maintenance - like independance (above), good luck upgrading shared libs. I've had multiple apps deployed on the same servers that *required* different lib versions.


    Additional benefits of libs in war:
    1. App installation and removal is simplier.
    2. Purity. wars/ears stay as "everything the app needs to work", just like they should be.
    3. Lib version mismatch reduced.


    Costs of libs in war:
    1. Disk space? At most, a couple of megs of jars repeated a couple of times on any modern machine? Not an issue.
    2. Memory space? Again, not enough to matter on modern machines.


    In short, the savings of sharing libs is not worth the cost.

  7. #7
    Join Date
    Aug 2004
    Location
    Seattle
    Posts
    30

    Default

    Quote Originally Posted by Rod Johnson
    Otherwise, just one project switching on its own isn't likely to make much difference.
    I agree. If the packages I depend on still use Jakarata Commons Logging (JCL), then I still have to deal with the classloading issues from it and it doesn't make much sense for me to move away from it. That is why I brought it up to you, because I'll probably follow.

    I would be interested in finding out what the Hibernate and Tomcat teams think of it as well. Hopefully, there will be more traction/publicity when Log4j 1.3 is released. It seams like a pretty simple search and replace.

    Cameron

  8. #8
    Join Date
    Aug 2004
    Location
    u.s.a
    Posts
    399

    Default

    Is UGLI pronounced "ugly"?


  9. #9
    Join Date
    Oct 2004
    Location
    Herndon, VA, US
    Posts
    648

    Default

    And when I first read about UGLI = Universal and Generic Logging Interface, the first thought was, "hmm, so now someone came up with something else to abstract away commons-logging?"
    --Jing Xue

  10. #10
    Join Date
    Aug 2004
    Posts
    218

    Default

    I agree...it would be nice to see Spring switch from JCL to something else for the reasons those articles mention. I'm having class loading issues that I can only resolve by putting the commons-logging, spring, and hibernate jars in the system classpath (yuk!).

    My situation is I have one service that calls another service. Each service is it's own application in WebLogic and thus has its own classloader. I am seeing JCL.jar conflicts despite the fact that they should be isolated. I wonder if maybe I could take a different approach to loading the applicationContext rather than using ClassPathXmlApplicationContext and maybe specify the classloader myself through XmlBeanDefinitionReader (the abstract parent class allows you to specify the classloader). Spring defaults to the contextLoader. Has anyone had any experience trying this? Has anyone found any workarounds to JCL classloader hell??

    This is the error I'm seeing:
    Code:
    Object=org.springframework.orm.hibernate.SessionFactoryUtils$JtaSessionSynchronization@2b04839, Exception=java.lang.ExceptionInInitializerError
    java.lang.ExceptionInInitializerError
    at net.sf.hibernate.util.JDBCExceptionReporter.logWarnings(Ljava.sql.SQLWarning;)V(JDBCExceptionReporter.java:???)
    at net.sf.hibernate.impl.BatcherImpl.closeConnection(Ljava.sql.Connection;)V(BatcherImpl.java:297)
    at net.sf.hibernate.impl.SessionImpl.disconnect()Ljava.sql.Connection;(SessionImpl.java:3352)
    at net.sf.hibernate.impl.SessionImpl.close()Ljava.sql.Connection;(SessionImpl.java:576)
    at org.springframework.orm.hibernate.SessionFactoryUtils.doClose(Lnet.sf.hibernate.Session;)V(SessionFactoryUtils.java:651)
    at org.springframework.orm.hibernate.SessionFactoryUtils.closeSessionOrRegisterDeferredClose(Lnet.sf.hibernate.Session;Lnet.sf.hibernate.SessionFactory;)V(SessionFactoryUtils.java:640)
    at org.springframework.orm.hibernate.SessionFactoryUtils.access$300(Lnet.sf.hibernate.Session;Lnet.sf.hibernate.SessionFactory;)V(SessionFactoryUtils.java:86)
    at org.springframework.orm.hibernate.SessionFactoryUtils$SpringSessionSynchronization.beforeCompletion()V(SessionFactoryUtils.java:776)
    at org.springframework.orm.hibernate.SessionFactoryUtils$JtaSessionSynchronization.afterCompletion(I)V(SessionFactoryUtils.java:874)
    at weblogic.transaction.internal.ServerSCInfo.callAfterCompletions(I)V(ServerSCInfo.java:853)
    at weblogic.transaction.internal.ServerTransactionImpl.callAfterCompletions()V(ServerTransactionImpl.java:2708)
    at weblogic.transaction.internal.ServerTransactionImpl.afterCommittedStateHousekeeping()V(ServerTransactionImpl.java:2606)
    at weblogic.transaction.internal.ServerTransactionImpl.setCommitted()V(ServerTransactionImpl.java:2638)
    at weblogic.transaction.internal.ServerTransactionImpl.globalRetryCommit(II)V(ServerTransactionImpl.java:2436)
    at weblogic.transaction.internal.ServerTransactionImpl.globalCommit()V(ServerTransactionImpl.java:2365)
    at weblogic.transaction.internal.ServerTransactionImpl.internalCommit()V(ServerTransactionImpl.java:278)
    at weblogic.transaction.internal.ServerTransactionImpl.commit()V(ServerTransactionImpl.java:244)
    at weblogic.ejb20.internal.BaseEJBObject.postInvoke(Lweblogic.ejb20.internal.InvocationWrapper;Ljava.lang.Throwable;)V(BaseEJBObject.java:299)
    at weblogic.ejb20.internal.StatelessEJBObject.postInvoke(Lweblogic.ejb20.internal.InvocationWrapper;Ljava.lang.Throwable;)V(StatelessEJBObject.java:140)
    at com.bea.wlw.runtime.core.bean.SyncDispatcher_k1mrl8_EOImpl.invoke(Lcom.bea.wlw.runtime.core.request.Request;)Lcom.bea.wlw.runtime.core.request.Response;(SyncDispatcher_k1mrl8_EOImpl.java:110)
    at com.bea.wlw.runtime.core.dispatcher.Dispatcher.remoteDispatch(Lcom.bea.wlw.runtime.core.dispatcher.DispFile;Lcom.bea.wlw.runtime.core.request.Request;)Lcom.bea.wlw.runtime.core.request.Response;(Dispatcher.java:161)
    at com.bea.wlw.runtime.core.dispatcher.Dispatcher.dispatch(Lcom.bea.wlw.runtime.core.dispatcher.DispFile;Lcom.bea.wlw.runtime.core.request.Request;Ljavax.servlet.http.HttpServletResponse;Ljavax.servlet.ServletContext;)V(Dispatcher.java:49)
    at com.bea.wlw.runtime.core.dispatcher.HttpServerHelper.executePostRequest(Ljavax.servlet.http.HttpServletRequest;Ljavax.servlet.http.HttpServletResponse;Ljavax.servlet.ServletContext;Ljavax.servlet.ServletConfig;)V(HttpServerHelper.java:713)
    at com.bea.wlw.runtime.core.dispatcher.HttpServer.doPost(Ljavax.servlet.http.HttpServletRequest;Ljavax.servlet.http.HttpServletResponse;)V(HttpServer.java:49)
    at javax.servlet.http.HttpServlet.service(Ljavax.servlet.http.HttpServletRequest;Ljavax.servlet.http.HttpServletResponse;)V(HttpServlet.java:760)
    at javax.servlet.http.HttpServlet.service(Ljavax.servlet.ServletRequest;Ljavax.servlet.ServletResponse;)V(HttpServlet.java:853)
    at weblogic.servlet.internal.ServletStubImpl$ServletInvocationAction.run()Ljava.lang.Object;(ServletStubImpl.java:996)
    at weblogic.servlet.internal.ServletStubImpl.invokeServlet(Ljavax.servlet.ServletRequest;Ljavax.servlet.ServletResponse;Lweblogic.servlet.internal.FilterChainImpl;)V(ServletStubImpl.java:419)
    at weblogic.servlet.internal.ServletStubImpl.invokeServlet(Ljavax.servlet.ServletRequest;Ljavax.servlet.ServletResponse;)V(ServletStubImpl.java:315)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run()Ljava.lang.Object;(WebAppServletContext.java:6456)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(Lweblogic.security.subject.AbstractSubject;Ljava.security.PrivilegedAction;)Ljava.lang.Object;(AuthenticatedSubject.java:321)
    at weblogic.security.service.SecurityManager.runAs(Lweblogic.security.acl.internal.AuthenticatedSubject;Lweblogic.security.acl.internal.AuthenticatedSubject;Ljava.security.PrivilegedAction;)Ljava.lang.Object;(SecurityManager.java:118)
    Caused by: org.apache.commons.logging.LogConfigurationException: org.apache.commons.logging.LogConfigurationException: org.apache.commons.logging.LogConfigurationException: Invalid class loader hierarchy. You have more than one version of 'org.apache.commons.logging.Log' visible, which is not allowed. (Caused by org.apache.commons.logging.LogConfigurationException: Invalid class loader hierarchy. You have more than one version of 'org.apache.commons.logging.Log' visible, which is not allowed.) (Caused by org.apache.commons.logging.LogConfigurationException: org.apache.commons.logging.LogConfigurationException: Invalid class loader hierarchy. You have more than one version of 'org.apache.commons.logging.Log' visible, which is not allowed. (Caused by org.apache.commons.logging.LogConfigurationException: Invalid class loader hierarchy. You have more than one version of 'org.apache.commons.logging.Log' visible, which is not allowed.))
    at org.apache.commons.logging.impl.LogFactoryImpl.newInstance(Ljava.lang.String;)Lorg.apache.commons.logging.Log;(LogFactoryImpl.java:543)
    at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(Ljava.lang.String;)Lorg.apache.commons.logging.Log;(LogFactoryImpl.java:235)
    at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(Ljava.lang.Class;)Lorg.apache.commons.logging.Log;(LogFactoryImpl.java:209)
    at org.apache.commons.logging.LogFactory.getLog(Ljava.lang.Class;)Lorg.apache.commons.logging.Log;(LogFactory.java:351)
    at net.sf.hibernate.util.JDBCExceptionReporter.<clinit>&#40;&#41;V&#40;JDBCExceptionReporter.java&#58;12&#41;
    at jrockit.vm.RNI.getRunnableCode&#40;I&#41;I&#40;Unknown Source&#41;
    at jrockit.vm.RNI.trampoline&#40;&#41;V&#40;Unknown Source&#41;

Similar Threads

  1. Log4j, Commons Logging in JRun 4 problem
    By virgo_ct in forum Container
    Replies: 4
    Last Post: Jul 13th, 2005, 04:17 AM
  2. Stop Spring Logging
    By jgchristopher in forum Container
    Replies: 6
    Last Post: Dec 8th, 2004, 10:32 AM
  3. Spring Framework DEBUG logging with Log4J
    By lukasbradley in forum Container
    Replies: 4
    Last Post: Nov 29th, 2004, 06:47 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •