dev2dev.bea.com.cn
首页 资源中心 dev2dev学堂 在线技术论坛 专家Blog User Group CodeShare

如果遇到这样的问题……

2006-03-24 00:00:00 | 评论 (0) | 被访问(1105)次

Satya Ghattu
  Satya Ghattu加入BEA公司已经有4年多了,担任软件工程师,专门负责WebLogic Platform的Operations Administration以及Management方面。Satya拥有将近8年的软件开发经验,主要是在应用服务器、核心java以及相关的(J2EE)技术方面。他还领导着dev2dev上CodeShare中的几个开源项目,并向dev2dev社区贡献了大量的代码示例。Satya是WebLogic Scripting Tool (WLST)的最初设计者,该工具是BEA官方支持的WebLogic Server命令行工具。在加入BEA之前,他曾在许多软件公司担任各种不同的职务,做过高级Java开发人员、软件分析师,还做过Oracle数据库管理员。Satya持有俄亥俄州Akron大学的工程学硕士学位。


  我遇到了一个让我完全措手不及的问题,我花了很长时间才弄明白到底怎么了。Struts 1.2.7发行版附带了commons logging 1.0.4和log4j 1.2.8。当我将控制台升级到struts 1.2.7并试图将其部署到服务器上时,部署失败了,出现了下面的错误:

java.lang.NoSuchMethodError: isEnabledFor
      at org.apache.commons.logging.impl.Log4JCategoryLog.isErrorEnabled(Log4JCategoryLog.java:189)
      at org.apache.beehive.netui.util.logging.Logger.isErrorEnabled(Logger.java:97)
      at org.apache.beehive.netui.pageflow.internal.AdapterManager.getServletContainerAdapter(AdapterManager.java:47)
      at org.apache.beehive.netui.pageflow.PageFlowUtils.createURLTemplatesFactory(PageFlowUtils.java:1716)

  最初,我以为这是由于系统类路径中某处存在另一个commons-logging.jar版本并被应用程序获得而引起的。但是仔细查看了类路径以及应用程序中的其他库之后,我没发现任何不妥之处,这使我快要疯了。后来我想应该装备Log4JCategoryLog类,看看org.apache.log4j.Category中什么方法使它产生了NoSuchMethodError错误。编译并将其重新包装进commons-logging.jar之后,我惊奇地发现一切都正常了。我可以看到装备Log4jCategoryLog时的调试输出。这使我考虑:把类文件打包在commons-logging.jar中是否不正确?为了验证,我把问题只限定在commons-logging和log4j上。在一个同事的帮助下,下面这个简单的再现类指出了问题所在:

public class Foo {
   // Ensure that your classpath has commons-logging-1.0.4.jar and log4j-1.2.8.jar
   public static void main(String[] args) {
      org.apache.commons.logging.impl.Log4JCategoryLog x = new org.apache.commons.logging.impl.Log4JCategoryLog();
      x.isErrorEnabled();
   }
}

  这个简单的客户端因与部署控制台时相同的错误而失败。我相信问题出在来自apache的commons-logging-1.0.4中的类上面:使用了错误的log4j Category类对其进行编译。

  如果使用commons-logging-1.0.4.jar在类路径中执行javap -c org.apache.commons.logging.impl.Log4JCategoryLog,就可以看到isErrorEnabled方法:

public boolean isErrorEnabled();
Code:
0: aload_0
1: getfield #7; //Field category:Lorg/apache/log4j/Category;
4: getstatic #14; //Field org/apache/log4j/Level.ERROR:Lorg/apache/log4j/Level;
7: invokevirtual #17; //Method org/apache/log4j/Category.isEnabledFor:(Lorg/apache/log4j/Level;)Z
10: ireturn

  这里,log4j的Category的isEnabledFor使用Level作为参数,但是Log4JCategoryLog应该是一个Priority类型的参数。如果重新编译Log4JCategoryLog并将其重新打包,并对该类执行javap –c,则将得到以下结果:

public boolean isErrorEnabled();
Code:
0: aload_0
1: getfield #2; //Field category:Lorg/apache/log4j/Category;
4: getstatic #9; //Field org/apache/log4j/Priority.ERROR:Lorg/apache/log4j/Priority;
7: invokevirtual #12; //Method org/apache/log4j/Category.isEnabledFor:(Lorg/apache/log4j/Priority;)Z
10: ireturn

  可以看出,log4j的Category的isEnabledFor使用一个Priority类型的对象作为参数,这是正确的。用google搜索了一下,我发现这个问题在新的commons-logging jar中已经被纠正了,可从下面的页面上得到新版本:http://www.ibiblio.org/maven/commons-logging/jars/commons-logging-1.1-dev.jar

  原文出处:http://dev2dev.bea.com/blog/sghattu/archive/2006/02/in_case_you_run.html



Tags: log4j commons logging jar
文章评论:(以下网友留言只代表个人观点,不代表BEA观点和立场)
暂时没有评论!

2006年03月

    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    
             
RSS订阅

Satya Ghattu's Blog搜索