zoukankan      html  css  js  c++  java
  • JBoss jar包冲突及jar加载顺序

    http://blog.163.com/javaee_chen/blog/static/17919507720116149511489/将一个完整的.war包部署到Jboss容器中,启动后报如下错误:
    15:04:48,632 ERROR [ContextLoader] Context initialization failed
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.apache.activemq.xbean.XBeanBrokerService#0' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: org.slf4j.MDC.getCopyOfContextMap()Ljava/util/Map;
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1338)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:473)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
            at java.security.AccessController.doPrivileged(Native Method)
    分析情况:
    在jboss根目录下执行如下命令
    $find . -name slf4j*.jar                      
    ./bin/configuration/org.eclipse.osgi/bundles/24/1/.cp/slf4j-log4j12-1.4.3.jar
    ./bin/configuration/org.eclipse.osgi/bundles/24/1/.cp/slf4j-api-1.4.3.jar
    ./server/default/deploy/configuration/org.eclipse.osgi/bundles/14/1/.cp/slf4j-log4j12-1.4.3.jar
    ./server/default/deploy/configuration/org.eclipse.osgi/bundles/14/1/.cp/slf4j-api-1.4.3.jar
    ./server/default/deploy/etl_sngps.war/WEB-INF/lib/slf4j-api-1.6.1.jar
    ./server/default/deploy/etl_sngps.war/WEB-INF/lib/slf4j-log4j12-1.6.1.jar
    ./server/default/deploy/jboss-web.deployer/configuration/org.eclipse.osgi/bundles/14/1/.cp/slf4j-log4j12-1.4.3.jar
    ./server/default/deploy/jboss-web.deployer/configuration/org.eclipse.osgi/bundles/14/1/.cp/slf4j-api-1.4.3.jar
    明明项目中lib地下的是1.6版本的,为什么还提示java.lang.NoSuchMethodError: org.slf4j.MDC.getCopyOfContextMap()Ljava/util/Map;(注:1.4一下版本会报这个错误,因为其不存在这里面的某个方法)
     
    查看Jboss jar加载文档:
    1)        org.jboss.Main.main(String[]) 为入口. 
    2)        main 函数创建一个名叫”jboss”的线程组, 然后创建一个属于该组的线程, 在线程中执行boot方法. 
    3)        boot 方法首先处理main函数中的参数(及一些其它的系统环境设置), 接着就用系统的属性创建了org.jboss.system.server.ServerLoader实例[new ServerLoader(props)]. 
    4)        ServerLoader 注册Jboss相关的类路径, 包括XML解析器, jboss-jmx.jar, concurrent.jar及其它的一些额外的类路径. 
    这里一般都是在JBOSS_HOMElib下面的jar
    5)        ServerLoader 通过load(ClassLoader)方法创建Jboss Server实例. 参数ClassLoader是ClassLoader parentCL = Thread.currentThread(). getContextClassLoader( )得到的当前线程的类加载器. 创建的Server实例是org.jboss.system.server.Server接口的实现. load(ClassLoader)方法的细节: 
    ?  用jar包及在ServerLoader中注册的类路径创建一个URLClassLoader的实例, 把传入的ClassLoader作为该URLClassLoader的parent. 
    ?  Server 接口的实现类由系统属性 jboss.server.type决定, 默认是 org.jboss.system.server.ServerImpl. 
    ?  URLClassLoader 通过无参构造函数加载Server接口实现的实例. 在加载前把当前线程的类加载器置为该URLClassLoader, 在加载完成后再置回之前传入的ClassLoader. 
     
    6)        Server 实例用系统属性进行初始化[server.init(props)]. 
    7)        服务起动[server.start()]. 起动过程的默认实现如下: 
    ?  把当前线程类型加载器置为加载该Server接口实现实例的ClassLoader. 
    ?  在jboss域内, 通过MBeanServerFactory的createMBeanServer(String)方法创建MbeanServer实例. 
    ?  在MBean Server上注册ServerImpl和ServerConfigImpl两个MBean. 
    ?  初始化统一的类加载仓库(unified class loader repository), 用来装载服务器配置目录及其它可选目录下的jar文件. 对于每一个jar文件和类目录都会创建一个相应的org.jboss.jmx.loading.UnifiedClassLoader实例, 并且注册到统一的仓库中. 其中一个UnifiedClassLoader实例会被设置为当前线程上下文的ClassLoader. [?: This effectively makes allUnifiedClassLoaders available through the thread context class loader.] 
    ?  接下来创建org.jboss.system.ServiceController的MBean实例. ServiceController管理JBoss MBean服务的生命周期. 
     
    需要注意的是:JBOSS在加载自带的核心JAR之后,将会优先加载下面的两个目录 
    1、D:jbossserverdefaultlib 
    2、D:jbossserverdefault mpdeploy 
     
    但是上面三组均不在以上1 2 所指的2个目录中。接着看......
    找到如下文件,注意这个文件里面蕴藏着jar加载的有一个规则.
    jboss-4.2.3.GAserverdefaultconfxmdesc org.jboss.deployment.MainDeployer-xmbean.xml
    最先加载的是后缀名为deployer目录下应用或者服务;
    250:.rar,300:-ds.xml,400:.jar,500:.war,550:.jse,650:.ear,800:.bsh
    <descriptors>
             <value value="250:.rar,300:-ds.xml,400:.jar,500:.war,550:.jse,650:.ear,800:.bsh"/>
    </descriptors>
    可以通过调整这个value来改变加载规则。
     
    这里已经很清楚了,上面所引爆的问题,正是由于/jboss-web.deployer下面所用的1,4版本导致的。删除后,一切正常。
    这里面还有一个问题,有些时候我们在使用jboss容器前,应该认真的看下jboss目录的机构及大致各个目录的作用,然后做一些精简删除无用的或者无关精要的目录,不仅可以让jboss瘦身还能减少问题引发的根源。
  • 相关阅读:
    Java之多线程(实现Runnable接口)
    Java之使用HttpClient发送GET请求
    hbase中文内容编码转换
    Java之utf8中文编码转换
    Java之正则表达式
    Java之List排序功能举例
    maven测试时中文乱码问题解决方法
    Hbase之IP变更后无法启动问题解决
    Hbase远程连接:Can't get the locations
    重启Hbase命令
  • 原文地址:https://www.cnblogs.com/svennee/p/4075511.html
Copyright © 2011-2022 走看看