Auf JBoss JMX-Service zugreifen

Finity

Grünschnabel
Hallo :),

ich versuche mich jetzt schon eine ganze Weile an dem folgenden Problem, komme aber einfach nicht weiter.

Und zwar möchte ich gerne von einem externen Java-Programm aus auf die MBeans von JBoss zugreifen. Ich möchte die MBeans also nicht per jmx-console auslesen, sondern von einem anderen Programm aus. Dabei versuche ich gerade testweise einfach mal die JMX-Methode isDeployed aufzurufen, die mir sagen soll, ob eine spezifische Webanwendung deployed wurde oder nicht.

Mein bisheriger Ansatz sieht dazu folgendermaßen aus:

Code:
    ... 
    private boolean isWebAppStarted(String appUrl) throws IOException, Exception {
        String processId = getProcessId("org.jboss.Main -c default");

        // Connect to the jvm of jboss (assuming no security)
        JMXConnector connector =JMXConnectorFactory.connect(getURLForPid(processId));

        // Get an MBeanServerConnection on the remote JVM.
        MBeanServerConnection remote = connector.getMBeanServerConnection();

        // Run an jmx-method to retrieve the state of the web-app
        // (Maybe we also have to ask for the state of the server itself?)
        Boolean running = (Boolean) remote.invoke(new ObjectName("jboss.system:service=MainDeployer"),
                                                  "isDeployed",
                                                  new Object[] { appUrl },
                                                  new String[] { String.class.getName() });
        connector.close();
        return running;
    }
   
    private static JMXServiceURL getURLForPid(String pid) throws Exception {
        // attach to the target application
        VirtualMachine vm = VirtualMachine.attach(pid);

        // get the connector address
        String connectorAddress = vm.getAgentProperties().getProperty("com.sun.management.jmxremote.localConnectorAddress");

        // no connector address, so we start the JMX agent
        if (connectorAddress == null) {
            String agent = vm.getSystemProperties().getProperty("java.home") + File.separator
                    + "lib" + File.separator + "management-agent.jar";
            vm.loadAgent(agent);

            // agent is started, get the connector address
            connectorAddress = vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS);
            assert connectorAddress != null;
        }

        return new JMXServiceURL(connectorAddress);
    }

    private static String getProcessId(String displayName) {
        // Retrieve a list of all java virtual machines started by the current
        // user
        List<VirtualMachineDescriptor> vmds = VirtualMachine.list();
        String retVal = null;

        // Search for the JVM with the passed display name and return it
        for (VirtualMachineDescriptor vmd : vmds) {
            if (vmd.displayName().equals(displayName)) {
                retVal = vmd.id();
                break;
            }

        }

        return retVal;
    }

Kurz zusammengefaßt mache ich also das Folgende: ich hole mir die JVM, in der der JBoss läuft, hänge dort die entsprechende Sun-Bibliothek an, um auf das JMX-Interface vom JBoss zuzugreifen und lese dann die entsprechenden Werte aus, die mich interessieren.

Das Ganze funktioniert auch, wenn der Application-Server (AS) das erste Mal gestartet wurde. Problematisch ist dabei aber das Laden des Agenten mit der "management-agent.jar": wird eine einzelne Web-Applikation innerhalb des AS neu gestartet, bekomme ich eine Exception der Art "Native Library ...\attach.dll already loaded in another classloader".

Tja, und jetzt bin ich mit meinem Latein am Ende. Aber vielleicht hat hier ja jemand einen Tipp für mich parat? Wäre echt super :).

Viele Grüße,

Fini
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück