JMXのローカルコネクタアドレスを取得する
現在起動されている全てのVMのJMXローカルコネクタアドレスを取得する処理を、汎用的に使うために簡単な関数にした。
static final String CONNECTOR_ADDRESS = "com.sun.management.jmxremote.localConnectorAddress"; public static String[] getJMXLocalConnectorAddresses() throws IOException { List<String> addresses = new ArrayList<String>(); for (VirtualMachineDescriptor desc : VirtualMachine.list()) { try { VirtualMachine vm = VirtualMachine.attach(desc.id()); String connectorAddress; try { //ローカルコネクタアドレスが格納されているプロパティを取得 connectorAddress = vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS); //コネクタアドレスが空の場合、エージェントのロードを試みる(まだロードされていない可能性がある) if (connectorAddress == null) { try { String agent = vm.getSystemProperties().getProperty("java.home") + File.separator + "lib" + File.separator + "management-agent.jar"; vm.loadAgent(agent); //起動したエージェントからローカルコネクタアドレスを取得 connectorAddress = vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS); } catch (AgentLoadExeption e) { connectorAddress = null; } catch (AgentInitializationException e) { connectorAddress = null; } } } finally { vm.detach(); } if ( !connectorAddress.isEmpty() ) { addresses.add(connectorAddress); } } catch (AttachNotSupportedException e) { continue; } } return addresses.toArray(new String[]{}); }
それにしても長い...もっとすっきり書けないものか。
にしても、これでやっと
・サーバアプリケーションは起動後、サーバソケットをリスン状態にしてポートを番号をMXBeanに公開する
・クライアントアプリケーションは現在起動されている任意のVMからMXBean(への参照)を取得する
・サーバが起動されていない(MXBeanが一つも見つからない)のであればサーバアプリケーションを起動する
・公開されているコードベースとポートを使って任意のサーバに接続して通信を開始する
という、プチ自律なプロセス間通信を実現できるようになった訳だ。
JMX(MXBean)は同一PC上に限れば作るのも管理するのも、難しくないのでいろいろと応用が効きそうである。