使用JMX监控WebLogic因classpath中jar包顺序导致的一些诡异问题
来源:互联网 发布:java版百战天虫 编辑:程序博客网 时间:2024/04/29 00:47
近期在用JMX监控WebLogic的状态信息,包括线程池,JVM,数据源,Session数量等。在一个demo工程中做得差不多了,把代码移动到正式工程中,然后问题就出来了,折腾了几个小时才搞清楚到底啥问题,因此记录一下。最开始对WebLogic的MBean体系不是很清楚,折腾了几天慢慢也弄明白了,代码不复杂,demo示例:
package com.baosight.ebsm.wl;import java.io.IOException;import java.net.MalformedURLException;import java.util.Hashtable;import javax.management.MBeanServerConnection;import javax.management.MalformedObjectNameException;import javax.management.ObjectName;import javax.management.remote.JMXConnector;import javax.management.remote.JMXConnectorFactory;import javax.management.remote.JMXServiceURL;import javax.naming.Context;public class WeblogicMonitor {private static MBeanServerConnection connection; private static JMXConnector connector; private static final ObjectName service; // Initializing the object name for DomainRuntimeServiceMBean // so it can be used throughout the class. static { try { service = new ObjectName( "com.bea:Name=DomainRuntimeService,Type=weblogic.management.mbeanservers.domainruntime.DomainRuntimeServiceMBean"); }catch (MalformedObjectNameException e) { throw new AssertionError(e.getMessage()); } } /* * Initialize connection to the Domain Runtime MBean Server */ public static void initConnection(String hostname, String portString, String username, String password) throws IOException, MalformedURLException { String protocol = "t3"; Integer portInteger = Integer.valueOf(portString); int port = portInteger.intValue(); String jndiroot = "/jndi/"; String mserver = "weblogic.management.mbeanservers.domainruntime"; JMXServiceURL serviceURL = new JMXServiceURL(protocol, hostname, port, jndiroot + mserver); Hashtable h = new Hashtable(); h.put(Context.SECURITY_PRINCIPAL, username); h.put(Context.SECURITY_CREDENTIALS, password); h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES, "weblogic.management.remote"); connector = JMXConnectorFactory.connect(serviceURL, h); connection = connector.getMBeanServerConnection(); } /* * Get an array of ServerRuntimeMBeans */ public static ObjectName[] getServerRuntimes() throws Exception { return (ObjectName[]) connection.getAttribute(service, "ServerRuntimes"); }/* * Iterate through ServerRuntimeMBeans and get the name and state */public void printJDBCState(ObjectName[] serverRT) throws Exception {int length = serverRT.length;for (int i = 0; i < length; i++) {ObjectName jdbcSR = (ObjectName) connection.getAttribute(serverRT[i], "JDBCServiceRuntime");ObjectName[] jdbcDSRM = (ObjectName[]) connection.getAttribute(jdbcSR, "JDBCDataSourceRuntimeMBeans");int jdbcDRMLength = jdbcDSRM.length;for (int x = 0; x < jdbcDRMLength; x++) {System.out.println("JDBCDataSourceRuntime Info .................................");//System.out.println(jdbcDSRM[x].getCanonicalName());System.out.println("Name = " + connection.getAttribute(jdbcDSRM[x], "Name"));System.out.println("ActiveConnectionsAverageCount = " + connection.getAttribute(jdbcDSRM[x], "ActiveConnectionsAverageCount"));System.out.println("ActiveConnectionsCurrentCount = " + connection.getAttribute(jdbcDSRM[x], "ActiveConnectionsCurrentCount"));System.out.println("ActiveConnectionsHighCount = " + connection.getAttribute(jdbcDSRM[x], "ActiveConnectionsHighCount"));System.out.println("ConnectionsTotalCount = " + connection.getAttribute(jdbcDSRM[x], "ConnectionsTotalCount"));System.out.println("NumAvailable = " + connection.getAttribute(jdbcDSRM[x], "NumAvailable"));System.out.println("HighestNumAvailable = " + connection.getAttribute(jdbcDSRM[x], "HighestNumAvailable"));System.out.println("ConnectionsTotalCount = " + connection.getAttribute(jdbcDSRM[x], "ConnectionsTotalCount"));System.out.println("CurrCapacity = " + connection.getAttribute(jdbcDSRM[x], "CurrCapacity"));}}}public void printVMState(ObjectName[] serverRT) throws Exception {int length = serverRT.length;for (int i = 0; i < length; i++) {ObjectName jvmRT = (ObjectName) connection.getAttribute(serverRT[i], "JVMRuntime");System.out.println("JVM Info .................................");//System.out.println(jvmRT.getCanonicalName());System.out.println("HeapSizeMax = " + connection.getAttribute(jvmRT, "HeapSizeMax"));System.out.println("HeapFreeCurrent = " + connection.getAttribute(jvmRT, "HeapFreeCurrent"));System.out.println("HeapFreePercent = " + connection.getAttribute(jvmRT, "HeapFreePercent"));System.out.println("HeapSizeCurrent = " + connection.getAttribute(jvmRT, "HeapSizeCurrent"));System.out.println("JavaVendor = " + connection.getAttribute(jvmRT, "JavaVendor"));System.out.println("JavaVersion = " + connection.getAttribute(jvmRT, "JavaVersion"));System.out.println("JavaVMVendor = " + connection.getAttribute(jvmRT, "JavaVMVendor"));System.out.println("Name = " + connection.getAttribute(jvmRT, "Name"));}}public void printThreadState(ObjectName[] serverRT) throws Exception {int length = serverRT.length;for (int i = 0; i < length; i++) {ObjectName tpRT = (ObjectName) connection.getAttribute(serverRT[i], "ThreadPoolRuntime");System.out.println("ThreadPoolRuntime Info .................................");System.out.println(tpRT.getCanonicalName());System.out.println("CompletedRequestCount = " + connection.getAttribute(tpRT, "CompletedRequestCount"));System.out.println("ExecuteThreadIdleCount = " + connection.getAttribute(tpRT, "ExecuteThreadIdleCount"));System.out.println("ExecuteThreads = " + connection.getAttribute(tpRT, "ExecuteThreads"));System.out.println("ExecuteThreadTotalCount = " + connection.getAttribute(tpRT, "ExecuteThreadTotalCount"));System.out.println("Throughput = " + connection.getAttribute(tpRT, "Throughput"));}}public void printSessionState(ObjectName[] serverRT) throws Exception {int length = serverRT.length;for (int i = 0; i < length; i++) {ObjectName[] arRT = (ObjectName[]) connection.getAttribute(serverRT[i], "ApplicationRuntimes");for(int j = 0 ; j < arRT.length ; j++){ObjectName[] crRT = (ObjectName[]) connection.getAttribute(arRT[j], "ComponentRuntimes");for(int n = 0; n < crRT.length; n++){String componentType = (String) connection.getAttribute(crRT[n], "Type");if (componentType.toString().equals("WebAppComponentRuntime")) {System.out.println("WebAppComponentRuntime Info .................................");String componentName = (String)connection.getAttribute(crRT[n], "ComponentName");System.out.println("ComponentName = " + componentName);if(componentName.contains("/")){System.out.println("ApplicationIdentifier = " + connection.getAttribute(crRT[n], "ApplicationIdentifier"));System.out.println("OpenSessionsCurrentCount = " + connection.getAttribute(crRT[n], "OpenSessionsCurrentCount"));System.out.println("OpenSessionsHighCount = " + connection.getAttribute(crRT[n], "OpenSessionsHighCount"));}}}}}}public void printClusterRuntime(ObjectName[] serverRT) throws Exception {int length = serverRT.length;for (int i = 0; i < length; i++) {ObjectName cRT = (ObjectName) connection.getAttribute(serverRT[i],"ClusterRuntime");if(cRT == null){continue;}System.out.println("ClusterRuntime Info .................................");System.out.println("HealthState = "+ connection.getAttribute(cRT, "HealthState"));System.out.println("AliveServerCount = "+ connection.getAttribute(cRT, "AliveServerCount"));System.out.println("SecondaryServerDetails = "+ connection.getAttribute(cRT, "SecondaryServerDetails"));String[] serverNames = (String[]) connection.getAttribute(cRT, "ServerNames");for(int j = 0 ; j < serverNames.length; j++){System.out.println("serverNames = "+ serverNames[j]);}}}public static void main(String[] args) throws Exception {String hostname = "10.25.34.230";String portString = "7001";String username = "eqadmin";String password = "webl0gic";long start = System.currentTimeMillis();WeblogicMonitor s = new WeblogicMonitor();initConnection(hostname, portString, username, password);ObjectName[] serverRT = getServerRuntimes();long runTime = System.currentTimeMillis();s.printJDBCState(serverRT);System.out.println("");long jdbcTime = System.currentTimeMillis();s.printVMState(serverRT);System.out.println("");long vmTime = System.currentTimeMillis();s.printThreadState(serverRT);System.out.println("");long threadTime = System.currentTimeMillis();s.printClusterRuntime(serverRT);System.out.println("");long clusterTime = System.currentTimeMillis();s.printSessionState(serverRT);long end = System.currentTimeMillis();System.out.println("total time: " + (end - start));System.out.println("runTime = " + (runTime -start));System.out.println("jdbcTime = " + (jdbcTime -start));System.out.println("vmTime = " + (vmTime -jdbcTime));System.out.println("threadTime = " + (threadTime -vmTime));System.out.println("clusterTime = " + (clusterTime -threadTime));System.out.println("sessionTime = " + (end -clusterTime));connector.close();}}
工程依赖了weblogic.jar,wlclient.jar,wljmxclient.jar和wlthint3client.jar。在demo工程中一切可以正常运行之后。把代码移动到正式的工程中,添加好需要依赖jar包,执行代码,问题相继出现了。
1. 报告ClassNotFoundException
既然报告class没找到,那就把包含这个class的jar包也加入到classpath中吧。WebLogic的jar包又特别多,一个一个的jar包去看,server下的lib都翻遍了,然后还有class没有找到,又在modules里面去找jar包,花了很久终于把缺的class相关的jar包都加入classpath了,增加了com.bean.core打头的几个jar包。这下链接却连不上了,郁闷了,报告连接异常
Caused by: javax.naming.CommunicationException [Root exception is java.net.ConnectException: t3://10.25.78.202:7002: Bootstrap to: 10.25.78.202/10.25.78.202:7002' over: 't3' got an error or timed out]at weblogic.jndi.internal.ExceptionTranslator.toNamingException(ExceptionTranslator.java:40)at weblogic.jndi.WLInitialContextFactoryDelegate.toNamingException(WLInitialContextFactoryDelegate.java:788)at weblogic.jndi.WLInitialContextFactoryDelegate.getInitialContext(WLInitialContextFactoryDelegate.java:366)at weblogic.jndi.Environment.getContext(Environment.java:315)at weblogic.jndi.Environment.getContext(Environment.java:285)at weblogic.jndi.WLInitialContextFactory.getInitialContext(WLInitialContextFactory.java:117)at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:667)at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)at javax.naming.InitialContext.init(InitialContext.java:223)at javax.naming.InitialContext.<init>(InitialContext.java:197)at weblogic.management.remote.common.ClientProviderBase.makeConnection(ClientProviderBase.java:178)... 5 more对比2个工程,除了jar包数量不一样(正式工程中还有其他的jar),是不是由于其他jar包导致的这个问题呢?把正式工程中除了和JMX相关的jar包都删除了,问题依旧。使用jVisualVM dump出正常工程的heap,也对比现在有问题的正式工程的heap,是有区别,class数量等,但是也看不出来问题所在。没辙,再创建一个,把最初工程的代码和jar包都copy过去,com.bean.core打头的几个jar包没有加入classpath中,新问题又出现了
2. 不报ClassNotFoundException,程序无响应
这次ClassNotFoundException却没有了,但是执行程序,半边没有任何反应,这下郁闷了。到底有哪里不一样呢,最初的工程是好好的可以跑。先检查了一遍eclipse从界面上看起来2个工程其他配置都一样,java版本,路径设置,唯一有点区别的是Java Bulider Path中Libraries的顺序有那么一点点不一样。就打开2个工程的文件.classpath文件,对比了一番,jar包的顺序是不一样的。对比如下:
无响应的工程<?xml version="1.0" encoding="UTF-8"?><classpath><classpathentry kind="src" path="src"/><classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/><classpathentry kind="lib" path="lib/weblogic.jar"/><classpathentry kind="lib" path="lib/wlthint3client.jar"/><classpathentry kind="lib" path="lib/wljmxclient.jar"/><classpathentry kind="output" path="bin"/></classpath>可以执行的工程<?xml version="1.0" encoding="UTF-8"?><classpath><classpathentry kind="src" path="src"/><classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/><classpathentry kind="lib" path="lib/wljmxclient.jar"/><classpathentry kind="lib" path="lib/weblogic.jar"/><classpathentry kind="lib" path="lib/wlthint3client.jar"/><classpathentry kind="output" path="bin"/></classpath>
然后把不能正常执行的工程的classpath的顺序换成可以执行的工程,程序就可以正常跑了。现在就很清楚是classpath中jar包顺序是有影响的。
wljmxclient.jar必须在weblogic.jar的前面!打开wljmxclient.jar和weblogic.jar,里面发现有一模一样的class,大小还不一样!这下知道问题所在了,如果加载的是
weblogic.jar里面的class,程序就会没有响应!话说weblogic.jar里面的package很混乱,打开其他几个jar包也好不到哪里去,怪不得会出现这么诡异的问题呢,同一个类就有了不同的版本。
weblogic.jar里面啥打头的包都有!
为啥会出现ClassNotFoundException呢,后来我发现我自己把wljmxclient.jar依赖的wlclient.jar加入了我自己的classpath中(wljmxclient.jar的/META-INF/MANIFEST.MF文件中有这样一句话:Class-Path: wlclient.jar。因此只要wlclient.jar和wljmxclient.jar在同一个目录没有啥问题)。如果我自己把wlclient.jar加入classpath的话,由于wlclient.jar中的某些实现类又和weblogic.jar中的不一样,它依赖了其他很多jar包,因此就ClassNotFoundException,真让人郁闷!WebLogic的jar包看来是非常混乱的。
3.验证classpath中jar包的加载顺序
猜想在classpath前的jar包优先加载,由于classloader的加载机制,有同名的class就不会再次加载了,后面顺序的jar包即使有同名的class,也不会加载。因此做了个小实验,建立了3个project,projecta,projectb和projectc。projecta和projectb一模一样,projectc依赖projecta或者projectb。projecta如下
package com.baosight.samepackage;public class SameClass {public void sameMethod(){System.out.println("This is in project a!");}}
projectb如下:
package com.baosight.samepackage;public class SameClass {public void sameMethod(){System.out.println("This is in project b!");}}
projectc中
package com.baosight.whichproject;import com.baosight.samepackage.SameClass;public class TestClass {public static void main(String[] args){SameClass same = new SameClass();same.sameMethod();System.out.println(same.getClass().getClassLoader());}}
然后在classpath,同时加入projecta.jar和projectb.jar,如果projecta.jar在前,打印的就是
"This is in project a!反正就是谁在前就加载了谁。这下就非常清楚了。关于classloader加载的问题可以参考java classLoader 体系结构 。至此这个问题就告一段落了,由于WebLogic中不同jar包中相同类的不同实现导致了这些诡异的事情,折腾了我好几个小时。
- 使用JMX监控WebLogic因classpath中jar包顺序导致的一些诡异问题
- Hibernate的一个奇怪报错,原来是工程下.classpath文件中jar包的引用顺序导致的
- weblogic使用JMX监控应用程序内、外部的状况
- weblogic中jar包冲突问题的解决办法
- JAR包引用其它JAR包的classpath问题
- 使用jmx监控weblogic启用iiop协议
- 使用jmx监控weblogic启用iiop协议
- 通过JMX监控管理weblogic的运行
- 通过JMX监控管理weblogic的运行
- 通过JMX监控管理weblogic的运行
- 通过JMX获取weblogic的监控指标
- hadoop jar运行hbase相关jar包的classpath问题
- 解决eclipse因导入jar包太大导致Unable to execute dex: Java heap space Java heap space的问题
- loadrunner 监控 weblogic(JMX)
- WebLogic中jar包的加载次序
- jar包中读取.properties文件的顺序问题
- 记一次因软件安装包问题导致的错误
- linux shell java jar 使用依赖包时classpath的设置问题
- 二分查找算法(Binary Search)的实现
- 32位 与64位编译
- 浮现式设计目录
- 堆和栈的比较
- 5.10. Data Transfer with Backpressure
- 使用JMX监控WebLogic因classpath中jar包顺序导致的一些诡异问题
- ubuntu下android真机调试
- 上班族保护颈椎有诀窍
- gdb调试
- 解包和打包i9100固件factoryfs.img办法
- HTML框架应用的技巧
- C#类、接口、虚方法和抽象方法-抽象类和接口的相同点和区别
- 华为与小米赛跑-续!!华为四款新机上市
- C++中的多态和虚函数