2016-05-08 11 views
2

リモートJVMを監視するJMXクライアントを実装しようとしています。メインメソッドからmbeanserver接続を取得し、メモリー使用量を検索するスレッドに渡します。問題は私がこれを行うときに「クライアントが閉じられた」というエラーが出ることです。しかし、スレッドなしでプログラムを実行すると、完全に機能します。マルチスレッドJMXクライアント

public class ESBMonitor { 
    private static TreeSet<ObjectName> mbeansNames = null; 

    public static void main(String[] args) throws IOException { 
     RemoteConnector.defaultConnector(); 
     MBeanServerConnection remote = RemoteConnector.getRemote(); 
     //MemoryExtractor.getMemoryInfo(); 
     MemoryExtractor memoryExtractor = new MemoryExtractor(); 
     memoryExtractor.start(); 
     RemoteConnector.closeConnection(); 
    } 
} 



public class RemoteConnector { 

private static MBeanServerConnection remote = null; 
private static JMXConnector connector = null; 
private static final Logger logger= LogManager.getLogger(RemoteConnector.class); 

public static void defaultConnector() { 
    try { 
     JMXServiceURL target = new JMXServiceURL 
       ("service:jmx:rmi://localhost:11111/jndi/rmi://localhost:9999/jmxrmi"); 
     //for passing credentials for password 
     Map<String, String[]> env = new HashMap<String, String[]>(); 
     String[] credentials = {"admin", "admin"}; 
     env.put(JMXConnector.CREDENTIALS, credentials); 

     connector = JMXConnectorFactory.connect(target, env); 
     remote = connector.getMBeanServerConnection(); 
     logger.info("MbeanServer connection obtained"); 

    } catch (MalformedURLException e) { 
     logger.error(e.getStackTrace()); 
    } catch (IOException e) { 
     logger.error(e.getStackTrace()); 
    } 
} 

public static MBeanServerConnection getRemote() { 
    return remote; 
} 



public static synchronized Object getMbeanAttribute(ObjectName bean, String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException, InstanceNotFoundException, IOException { 
    return remote.getAttribute(bean,attribute); 
} 


} 




public class MemoryExtractor extends Thread{ 

final static Logger logger = Logger.getLogger(MemoryExtractor.class); 
private static MBeanInfo memoryInfo; 
private static ObjectName bean = null; 
private static double MEMORY = 0.05; 
private static long TIMEOUT = 3000; 

public static void getMemoryInfo() { 
    try { 
     bean = new ObjectName("java.lang:type=Memory"); 
     checkWarningUsage(); 

    } catch (MalformedObjectNameException e) { 
     logger.error("MemoryExtractor.java:25 " + e.getMessage()); 
    } 
} 

public static boolean checkWarningUsage() { 
     try { 
      logger.info("MemoryExtractor.java:46 Acessing memory details"); 
      CompositeData memoryUsage = (CompositeData) RemoteConnector.getMbeanAttribute(bean,"HeapMemoryUsage"); 


     } catch (Exception e) { 
      logger.error("MemoryExtractor.java:58 " + e.getMessage()); 
     } 
    return false; 
} 

public void run(){ 
    while (true){ 
     getMemoryInfo(); 
    } 
} 
} 

私は同期しても問題はありません。

スタックトレース

java.io.IOException: The client has been closed. 
at com.sun.jmx.remote.internal.ClientCommunicatorAdmin.restart(ClientCommunicatorAdmin.java:94) 
at com.sun.jmx.remote.internal.ClientCommunicatorAdmin.gotIOException(ClientCommunicatorAdmin.java:54) 
at javax.management.remote.rmi.RMIConnector$RMIClientCommunicatorAdmin.gotIOException(RMIConnector.java:1474) 
at javax.management.remote.rmi.RMIConnector$RemoteMBeanServerConnection.getAttribute(RMIConnector.java:910) 
at org.wso2.connector.RemoteConnector.getMbeanAttribute(RemoteConnector.java:55) 
at org.wso2.jvmDetails.MemoryExtractor.checkWarningUsage(MemoryExtractor.java:47) 
at org.wso2.jvmDetails.MemoryExtractor.run(MemoryExtractor.java:79) 
+0

コードのサイズを小さくすることはできますか?たぶん動作していない部分だけを置くことがあります。 – Troncador

+0

CompositeData memoryUsage =(CompositeData)RemoteConnector.getMbeanAttribute(Bean、 "HeapMemoryUsage"); これは動作しない部分です – Dina

+0

コードをきちんと整理し、問題の行だけを入れなければなりません。一般的に誰も生のコードを読んでほしくない、それは多くの努力です。少なくとも私の場合、私は助けたいと思っていますが、作家が読みやすいように努力している場合にのみ – Troncador

答えて

2

あなたのRemoteConnectorクラスのstaticとしてのJMXConnectorへの参照をキャッシュしているので、これまで唯一つの接続があります。最初のスレッドがそのシングルトン接続を閉じるとすぐに、他のスレッドが何かを呼び出そうとすると、その時点ですでに接続を閉じているために失敗します。

複数のスレッドを使用する場合は、すべてのスレッドが終了したときに接続を閉じるか、スレッドごとに1つの接続を終了する必要があります。

+1

本当に助けていただきありがとうございます。本当にありがとう@AIBlueそれは私が作った本当にダムの間違いだった。 – Dina

関連する問題