JConsole背后

阅读更多
最近做监控相关的事情,要把本地的所有JAVA应用管理起来,但这些应用的JDK1.4的,有1.5的,1.6的,而且在JDK1.5之前的应用提供的MBeanServer并不是PlatformMBeanServer,这就导致监控时获取堆的信息,线程,Runtime等一些属性的时候没法获取。本打算改造运行在JDK1.4上跑的应用,使其使用PlatFormMBeanServer,但JDK1.4好像并没有提供获取PlatFormMBeanServer的方式,大致想到了以下几个思路:
1.升级JDK,但可能会影响原来应用,因为JDK1.4的时候一些语法像enum这些都还不是关键字。
2.如果可以升级JDK,下面的几点才可以实现:
  2.1 改造原应用,获取PlatFormMBeanServer,这样应用的监控数据和java.lang的监控数据就都可以获取
  2.2 利用JDK attach 的方式,根据本地的vmid获取其jmxUrl,再获取属性,这个需要JDK1.6了。

JDK中部分Attach的代码:
 // load the management agent into the target VM
    private void loadManagementAgent() throws IOException {
        VirtualMachine vm = null;
        String name = String.valueOf(vmid);
        try {
            vm = VirtualMachine.attach(name);
        } catch (AttachNotSupportedException x) {
            IOException ioe = new IOException(x.getMessage());
            ioe.initCause(x);
            throw ioe;
        }

        String home = vm.getSystemProperties().getProperty("java.home");

        // Normally in ${java.home}/jre/lib/management-agent.jar but might
        // be in ${java.home}/lib in build environments.

        String agent = home + File.separator + "jre" + File.separator +
                           "lib" + File.separator + "management-agent.jar";
        File f = new File(agent);
        if (!f.exists()) {
            agent = home + File.separator +  "lib" + File.separator +
                        "management-agent.jar";
            f = new File(agent);
            if (!f.exists()) {
                throw new IOException("Management agent not found");
            }
        }

        agent = f.getCanonicalPath();
        try {
            vm.loadAgent(agent, "com.sun.management.jmxremote");
        } catch (AgentLoadException x) {
            IOException ioe = new IOException(x.getMessage());
            ioe.initCause(x);
            throw ioe;
        } catch (AgentInitializationException x) {
            IOException ioe = new IOException(x.getMessage());
            ioe.initCause(x);
            throw ioe;
        }

        // get the connector address
        Properties agentProps = vm.getAgentProperties();
        address = (String) agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP);

        vm.detach();
    }

 InputStream execute(String cmd, Object ... args)
        throws AgentLoadException, IOException
    {
        assert args.length <= 3;        // includes null

        // create a pipe using a random name
        int r = (new Random()).nextInt();
        String pipename = "\\\\.\\pipe\\javatool" + r;
        long hPipe = createPipe(pipename);

        // check if we are detached - in theory it's possible that detach is invoked
        // after this check but before we enqueue the command.
        if (hProcess == -1) {
            closePipe(hPipe);
            throw new IOException("Detached from target VM");
        }

        try {
            // enqueue the command to the process
            enqueue(hProcess, stub, cmd, pipename, args);

            // wait for command to complete - process will connect with the
            // com

你可能感兴趣的:(JConsole背后)