`
liuyf8688
  • 浏览: 99773 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Don't Do This! But Here Is a Way.

阅读更多

Recently I was asked how to do "registerMBean" in a remote JVM, from a remote JMX client. The MBeanServerConnection doesn't expose any registerMBean method, and for good reasons.

When you create and register an MBean in a local MBeanServer, the MBeanServer keeps a local reference to the MBean you registered. The MBean you registered, and the MBean you access through the MBeanServer interface are thus the same object.

However, if you try to register an MBean in a remote MBeanServer, the MBean will have to be serialized, and recreated as a new object in the remote JVM. There will thus be two object: one in the local JVM (client side) - and a copy of it in the remote JVM server side. These two object are completely unrelated, and a modification in one of them will not affect the other in any way: they are two different copies...

This is the first reason why MBeanServerConnection doesn't have any "registerMBean" method: it would make you think that you register an object x, while in fact you're registering a distinct serialized clone.

The second reason is that an MBean usually reflect the state of an application resource. In most cases, the MBean will have a pointer to that resource. Very often, that resource will not be serializable. In that case, cloning the MBean to send it to other side will be at best impossible and at worst undesirable.

There are times however where you do need to create an MBean in a remote JVM. But the proper way to that is not to use registerMBean, but one of the createMBean methods exposed by MBeanServer. With createMBean there are no confusion possible: you create a new MBean in a remote JVM, and you can give it all the information it needs to initialize in its constructor.
If you ever need to create an MBean in a remote JVM, createMBean is thus definitely the way to go.

However, if after reading all of this you still want to do "registerMBean" from remote, here is a very simple trick that you can use. It works only with Standard MBeans and MXBeans - and won't work with DynamicMBeans. But I'll say it another time: don't do this before you really know what you're doing and all its implications!

Please don't do THIS:

/*
 * DontDoThis.java
 *
 * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * Created on Jul 25, 2007, 11:42:49 AM
 * 
 */

package dontdothis;

import java.io.IOException;
import java.io.Serializable;
import java.lang.management.ManagementFactory;
import javax.management.JMException;
import javax.management.JMX;
import javax.management.MBeanServer;
import javax.management.MBeanServerConnection;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.StandardMBean;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;

/**
 * This trick only works with standard MBean and MXBeans.
 * @author dfuchs
 */
public class DontDoThis {

    // A dummy interface for my dummy MBean
    public static interface ThingMBean {
        // Get A foo for my thing
        public String getFoo();
        // Set A foo for my thing
        public void setFoo(String value);
    }

    // A dummy implementation for my dummy MBean
    public static class Thing implements ThingMBean, Serializable {
         // Attribute : Foo
        private String foo;

        public Thing(String foo) {this.foo = foo;}
        // Get A foo gor my thing
        public String getFoo() {return foo;}
        // Set A foo gor my thing
         public void setFoo(String value) {foo = value;}
    }

    // Create a server... we're simulating a remote server
    // here by starting an RMI JMXConnectorServer...
    public static JMXServiceURL createServer() 
            throws IOException {         
        final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
        final JMXServiceURL jurl = new JMXServiceURL("rmi", null, 0);
        final JMXConnectorServer server =
                JMXConnectorServerFactory.newJMXConnectorServer(jurl, null, mbs);
        server.start();
        return server.getAddress();
    }
    
    // Here is the trick: instead of registering x directly, we wrap it
    // in an instance of javax.management.StandardMBean, and we use
    // createMBean to create the wrapper.
    //
    public static ObjectInstance registerMBean(MBeanServerConnection mbsc,
            ObjectName mbeanName, Object mbean, Class<?> mbeanInterface) 
            throws IOException, JMException {
        
        // create a Standard MBean,
        return mbsc.createMBean(StandardMBean.class.getName(), mbeanName,
                new Object[]{mbean, mbeanInterface}, 
                new String[]{Object.class.getName(),Class.class.getName()});
    }
    
    // Well: you've been warned: don't do this!
    public static void main(String[] args) throws Exception {
        
        final JMXServiceURL serverURL = createServer();

        // Instantiate the MBean we want to register
        final ThingMBean x = new Thing("I am a nice Thing!");
        final ObjectName xName = new ObjectName("x:x=x");
        
        // we're simulating a remote client by connecting to the server
        // through RMI
        final JMXConnector c = JMXConnectorFactory.connect(serverURL);
        final MBeanServerConnection mbsc = c.getMBeanServerConnection();
        
        // register MBean x in remote server.
        registerMBean(mbsc,xName,x,ThingMBean.class);

        // create a proxy to the registered MBean
        final ThingMBean x2 = JMX.newMBeanProxy(mbsc, xName, ThingMBean.class);

        // modify the original reference:
        x.setFoo("... but I have turned bad.");

        // x & the registered MBean are now 2 different objects!
        System.out.println(xName.toString() + " says: " + x2.getFoo());
        System.out.println("x says: " + x.getFoo());

        System.out.println("Now waiting for Enter: ");
        System.in.read();

    }
}

文章来源:http://blogs.sun.com/jmxetc/entry/do_not_do_this_but

分享到:
评论

相关推荐

    C# Game Programming Cookbook for Unity 3D - 2014

    1. Making Games the Modular Way 1 1.1 Important Programming Concepts.....................................2 1.1.1 Manager and Controller Scripts...............................2 1.1.2 Script ...

    Google C++ Style Guide(Google C++编程规范)高清PDF

    link ▶Don't use an #include when a forward declaration would suffice. When you include a header file you introduce a dependency that will cause your code to be recompiled whenever the header file ...

    英语口试快速应答语料库.doc

    - A: Don’t worry. Take it easy. 20. 抱怨等待: - Q: I’ve been waiting here for 20 minutes, but the bus hasn’t come yet. - A: Oh, that’s too bad. 21. 表扬与回应: - Q: You look wonderful in ...

    BobBuilder_app

    This format ensures a semi sorted key list, in that within a page the data is not sorted but pages are in sort order relative to each other. So a look-up for a key just compares the first keys in the ...

    au3反编译源码

    often this signature was modified or is used for a fake script that is just attached to distract & mislead a decompiler. When off it scans for the 'FILE' as encrypted text to find the start of a ...

    pgadmin3redux.zip

    I don't have a huge amount of time to put to this right now, but I still want to keep pgAdmin3 working since it's the best fast tool to use with PostgreSQL. © Tokavuh Technologies oy

    Web.Client.Programming.with.Perl.Automating.Tasks.on.the.Web.pdf

    fine--but there are many who don't like to get into a car without knowing what's under the hood. For those of you who desire a better technical understanding of the Web, this book demystifies the ...

    apktool documentation

    This retains the apk is nearly original format, but will make rebuild more than likely not work due to ignoring the changes that newer aapt requires After [d]ecode, there will be new folders ...

    pdiusb开发固件源码

    &gt; don't think it is the bottle neck here. I am running this on a P4 &gt; 3.2Ghz machine, so even VB is quick. &gt; &gt; Here are the symptoms of my problem. The 245's TXE seems to go high &gt; (signaling that the...

    iOS-2048-master

    However, I have a little bit of trouble when dealing with `NSOperationQueue` so I didn't do it this way. Now the AI only searches at the specified `-maximumSearchingDepth`. ## The Game Since it is ...

    Apress Beginning Ubuntu Linux 3rd Edition Jun 2008.part2

    But don’t think that this means Beginning Ubuntu Linux, Third Edition cuts corners. Wherever justified, this book spends time examining the topics you need to know in order to gain a complete and ...

    Apress Beginning Ubuntu Linux 3rd Edition Jun 2008.part1

    But don’t think that this means Beginning Ubuntu Linux, Third Edition cuts corners. Wherever justified, this book spends time examining the topics you need to know in order to gain a complete and ...

    Java邮件开发Fundamentals of the JavaMail API

    As a user of the JavaMail API, you usually don't need to worry about these formats. However, these formats do exist and are used by your programs. NNTP and others Because of the split of the ...

    painless_git.pdf

    The Painless series is designed around developers who have a lot to do. I take it as read that you're intelligent and don't want to spend your time reading tech books. Painless Git is designed to be ...

    微软内部资料-SQL性能优化5

    There is also a column for the first page of the table, but this is not guaranteed to be reliable. SQL Server can find all pages belonging to an index or table by examining the IAM pages. Sysindexes...

    Advanced Apple Debugging & Reverse Engineering v0.9.5

    You need a methodical way to figure out what went wrong in your LLDB script so you don’t pull your hair out. In this chapter, you’ll explore how to inspect your LLDB Python scripts using the Python ...

    counter hack reloaded

    We don't want this book to be merely a giant tome on your shelf Chapter 1. Introduction Page 4 Return to Table of Contents Chapter 1. Introduction Counter Hack Reloaded, Second Edition: A Step-by-...

    VclZip pro v3.10.1

    If you use Delphi 6, 7, or BCB 6, you don't have to worry about any of this as the normal TSTream is used by VCLZip and handles large file/stream sizes. ============ Version 2.23 (VCLZip Lite) ...

Global site tag (gtag.js) - Google Analytics