Anish
Anish

Reputation: 255

Facing issues while setting JVM properties for JMX remote management

When I export my JMX agent for remote management, and set the following parameters as VM arguments

-Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.ssl=false

It works fine as my JMX client is able to easily establish connection with the MBean at port 9999.

Now, I want to set these properties at run time via my configuration file. I tried setting it via System.setProperty("com.sun.management.jmxremote.port","9999"); and other properties similarly but to no avail. The JMX Agent doesn't get exposed for remote management in this way.

I even tried creating a registry on the port 9999 but still doesn't seem enough.

private void init() {
    try {
        LocateRegistry.createRegistry(9999);
        System.setProperty("com.sun.management.jmxremote", "true");
        System.setProperty("com.sun.management.jmxremote.authenticate", "false");
        System.setProperty("com.sun.management.jmxremote.port", "9999");
        System.setProperty("com.sun.management.jmxremote.ssl", "false");
    } catch (RemoteException e) {
        e.printStackTrace();
    }
}

I just don't understand why setting these properties via VM arguments works and not while setting the same properties programatically as I described above.

Upvotes: 1

Views: 2590

Answers (4)

rahul maindargi
rahul maindargi

Reputation: 5625

This is what works for me. I am assuming you already know how to right SimpleMXBean used in below example.

Reference Oracle JMX Tutorial. (See section Mimicking Out-of-the-Box Management Using the JMX Remote API.)

package sample;

import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.rmi.registry.LocateRegistry;
import java.util.HashMap;
import java.util.Map;

import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;

public class MBServerTest {
    public static void loadJMXAgent(int port, MBeanServer mbs) throws IOException  {
        LocateRegistry.createRegistry(port);
        System.out.println("Initialize the environment map");
        Map<String,Object> env = new HashMap<String,Object>();
        env.put("com.sun.management.jmxremote.authenticate", "false");
        env.put("com.sun.management.jmxremote.ssl", "false");
        System.out.println("Create an RMI connector server");
        JMXServiceURL url =
            new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:"+port+"/jmxrmi");
        JMXConnectorServer cs =
            JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);

        // Start the RMI connector server.
        //
        System.out.println("Start the RMI connector server");
        cs.start();

    }

    public static void main(String[] args) throws Exception {
        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
        loadJMXAgent(1199,mbs);

        SimpleStandard cache = new SimpleStandard();

        ObjectName name = new ObjectName(
                "org.javalobby.tnt.jmx:type=ApplicationCacheMBean");
        mbs.registerMBean(cache, name);
        imitateActivity(cache);
    }

    private static void imitateActivity(SimpleStandard cache) {
        while (true) {
            try {
                cache.cacheObject("hello");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }
        }
    }
}

Upvotes: 2

Murat Ayan
Murat Ayan

Reputation: 575

Try to set properties in a static block.

static {
    System.setProperty("com.sun.management.jmxremote.port", "9999");
    System.setProperty("com.sun.management.jmxremote.authenticate", "false");
    System.setProperty("com.sun.management.jmxremote.ssl", "false");
}

Upvotes: 0

Ralf
Ralf

Reputation: 6853

Just providing the property probably does not trigger the creation of an RMI connector on the port that you provided. If you want to enable remote monitoring at runtime then I think you also have to create the connector on the MBean server yourself.

Check out the chapter "Mimicking Out-of-the-Box Management" of the Oracle JMX tutorial. In particular this last bit of the sample code, which uses port 3000 for the RMI server. This is where you want to put the port of your choice:

LocateRegistry.createRegistry(3000); 
Map<String,Object> env = new HashMap<String,Object>();
env.put("com.sun.management.jmxremote.authenticate", "false");
env.put("com.sun.management.jmxremote.ssl", "false");
// Create an RMI connector server.
//
// specified in the JMXServiceURL the RMIServer stub will be
// registered in the RMI registry running in the local host on
// port 3000 with the name "jmxrmi". This is the same name the
// out-of-the-box management agent uses to register the RMIServer
// stub too.
//
System.out.println("Create an RMI connector server");
JMXServiceURL url =
    new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:3000/jmxrmi");
JMXConnectorServer cs =
    JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);

// Start the RMI connector server.
//
System.out.println("Start the RMI connector server");
cs.start();

Upvotes: 0

JB-
JB-

Reputation: 2670

Setting the system properties from your application is a bit too late. The JMX agent has already been loaded and initialized.

You can use a JMX configuration file to store the properties in one external file. While it does not allow you read the properties from one shared configuration file it enabled you at least externalize the settings into a different user properties file.

Upvotes: 0

Related Questions