WAS上部署Jmx应用中包冲突解决过程
近日,在was6.0上面部署基于JMX的一个应用,出现一个JMX类的JMXConnectorFactory.resolveClassLoader()的MethodNotFound的错误,但是明明JMX的类也就是jmx-remote.jar包里面的类有该类的方法,如图:
在开发机器上的tomcat上跑没有错,为什么布署在was上就有问题,肯定是环境出了问题,幸好有点was部署经验,出现此类java ERROR级别的错误,绝大多数是jar包冲突的的问题,于是打开was控制台,利用was的类装入器查看器发现在was的一个名为management.jar包里面也有同为JMXConnectorFactory的类,于是抓下来一看究竟。
果然不出所料,没有resolveClassLoader方法,然而management的类加载层次肯定是比jmx-remote.jar的层次高,默认的类加载策略是先加载父类,理说当然,jmx-remote.jar包中的类不可能被加载。
说起为什么冲突,还得说说历史。Jmx在jdk1.4时代是作为sun的一个扩展包存在的,并不是标准的jdk的包,于是乎ibm也有他的jmx的实现,而且包名和sun的一样,要是不一样就不会有冲突了。
好吧,能不能不使用基于JMX的包里面的实现,用management里面的实现呢,结果很失望,management里RmiConnectorServer根本没有实现。自己照着jmx-remote.jar里面的实现重写?实践了才发现不可能,重写一个得重写几十个类,还不能保证运行正常。
由于jmx的jar包在was上面部署的时候是采用共享包的方式部署的,我首先考虑的是能否考虑这个共享库的加载方式,改成后加载父类。为了便于理解
我们假设java的boot classloader叫做A,was的系统jar包classloader叫做B,
共享库的classloader加载C,应用程序的classLoader叫做D。他们的层次如图:
其中C加载器加载jmx-remote.jar,如果能改变C的加载策略,改变为后加载父类,那么就可以避免加载management里面的类了。
解决方案有两种:
还有一种可能想到的解决方案,就是能不能在A和B之间有一个classload E,让E去加载jmx相关的类。这样要找的肯定是E加载器中的jmx相关的类了。理想是好了,而且我们确实可以把E加载器放在A和B之间。
可以设置-Djava.ext.dirs变量或者设置-Djava.class.path变量,多个目录用”:”隔开,这种设置的前提是要知道变量的值是多少,否则就破坏系统的设置了。
一切看起来完美,布署运行,出现以下错误:
Caused by: java.lang.LinkageError: Class javax/management/remote/JMXServiceURL violates loader constraints: parent and child already loaded different classes
at java.lang.ClassLoader.defineClass0(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java(Compiled Code))
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java(Compiled Code))
at java.net.URLClassLoader.defineClass(URLClassLoader.java(Compiled Code))
at java.net.URLClassLoader.access$500(URLClassLoader.java(Inlined Compiled Code))
at java.net.URLClassLoader$ClassFinder.run(URLClassLoader.java(Compiled Code))
at java.security.AccessController.doPrivileged1(Native Method)
at java.security.AccessController.doPrivileged(AccessController.java(Compiled Code))
at java.net.URLClassLoader.findClass(URLClassLoader.java(Compiled Code))
at java.lang.ClassLoader.loadClass(ClassLoader.java(Compiled Code))
at java.lang.ClassLoader.loadClass(ClassLoader.java(Compiled Code))
at javax.management.remote.JMXConnectorServerFactory.newJMXConnectorServer(JMXConnectorServerFactory.java:275)
灰常底层的错误啊!google,baidu之。原因是这样的
Classloader D 调用一个方法JMXConnectorServerFactory. newJMXConnectorServer(JMXServiceURL serviceURL,Map environment,
MBeanServer mbeanServer)来新建一个ConnectorServer
这个方法可以从spring的源码中看到。先看看目前的类加载器:
D会去找JMXConnectorServerFactory类,由于B中没有所以找到了E中的JMXConnectorServerFactory,同时也会去找JMXServiceURL,找到B的时候,这里是关键,由于Classloader B (WAS引导程序扩展类装入器)出于保护was类的原因,其策略是后加载父类(parent_last),所以找到了B中的JMXServiceURL。然而实际上,JMXConnectorServerFactory.newJMXConnectorServer方法需要的是E中的JMXServiceURL类,并且E中的JMXServiceURL和B中的JMXServiceURL字节码不一样,所以会出现violates loader constraints: parent and child already loaded different classes这种错误,也就是类装入器约束违反。
如果还不清楚的话,可以参考:
写道
http://www.ibm.com/developerworks/cn/java/j-dclp4/
既然绕不过B,还是只能有上述两种解决方案了。两种比较而言方案二更安全点,毕竟jvm上面跑的不只是这一个应用,动配置的事情能影响小就影响小点吧。
- 大小: 81.2 KB
- 大小: 67.8 KB
- 大小: 3.1 KB
- 大小: 5.2 KB
分享到:
相关推荐
jmx相关jar包
jmx和jmx在glassfish中的应用
该文档包含了详细的JMX的编程接口,在APi中拷贝下来的
catalina-jmx-remote.jar放到tomcat/lib目录下 如果是windows版本,编辑TOMCAT_HOME/bin/catalina.bat,在开头加入下面几行: set CATALINA_OPTS=%CATALINA_OPTS% -Djava.rmi.server.hostname=JMX_HOST set CATALINA...
JMX一步一步来,从最基本的应用开始入手,快速应用开发。
使用jmx技术所需要的jar包,共有4个jar文件,可用于jmx开发
书中不仅有对于基础知识的介绍,还有对于JMX开发中重大的体系架构问题的深入探讨,总结了大量JMX开发中的设计模式,并讨论了框架、安全性与性能等等。书中提供了几个典型的例子,兼顾各种开发平台,这些例子的代码...
JMX应用实例与实现,通过一个简单的JavaWeb应用来验证JMX在应用中的植入管理和应用
Java分布式应用学习笔记08JMX规范与各种监控场景
完美解决jmx中的HtmlAdaptorServer找不到的问题,完美解决jmx中的HtmlAdaptorServer找不到的问题,
jmxri.jar包下载。
它还提供一些高级特性,比如集群、JMX、Web Service。它还整合了IIOP(Internet Inter-ORB Protocol)。 因为JBoss代码遵循LGPL许可,你可以在任何商业应 用中免费使用它,而不用支付费用。JBoss是纯Java的Web应用...
jmx-1_2_1-ri.zip 解压后的lib目录包含jmxri.jar、jmxtools.jar jmx_remote-1_0_1_03-ri.zip 解压后的lib目录包含jmxremote.jar、jmxremote_optional.jar、rmissl.ja
使用JMX接口来编写PMI应用程序,经验证,确实可行。
分析了当前网络监控中面临的主要问题,提出了采用JMX方案来解决的办法。介绍了JMX的技术特点,并采用该技术实现了IP网络管理中的网络监控任务的调配和管理。
JMX应用技术架构系统(包括具体开发说明),详细介绍了JMX的应用场景以及MX4J在分布式应用监控方面的应用开发方法.
Fiddler导出jmx文件,解决Fiddler导出文件中 没有jmx文件选项,各个版本fiddler都适用
jmx依赖jar包 jmxtools-1.2.1.jar jmxri-1.2.1.jar
jmx简单实例装有jms-1.1.jar、jmxri-1.2.1.jar、jmxtools-1.2.1.jar包,完整项目能跑,附带简单使用说明...