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:
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;
@author
public class DontDoThis {
public static interface ThingMBean {
public String getFoo();
public void setFoo(String value);
}
public static class Thing implements ThingMBean, Serializable {
private String foo;
public Thing(String foo) {this.foo = foo;}
public String getFoo() {return foo;}
public void setFoo(String value) {foo = value;}
}
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();
}
public static ObjectInstance registerMBean(MBeanServerConnection mbsc,
ObjectName mbeanName, Object mbean, Class<?> mbeanInterface)
throws IOException, JMException {
return mbsc.createMBean(StandardMBean.class.getName(), mbeanName,
new Object[]{mbean, mbeanInterface},
new String[]{Object.class.getName(),Class.class.getName()});
}
public static void main(String[] args) throws Exception {
final JMXServiceURL serverURL = createServer();
final ThingMBean x = new Thing("I am a nice Thing!");
final ObjectName xName = new ObjectName("x:x=x");
final JMXConnector c = JMXConnectorFactory.connect(serverURL);
final MBeanServerConnection mbsc = c.getMBeanServerConnection();
registerMBean(mbsc,xName,x,ThingMBean.class);
final ThingMBean x2 = JMX.newMBeanProxy(mbsc, xName, ThingMBean.class);
x.setFoo("... but I have turned bad.");
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
分享到:
相关推荐
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 ...
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 ...
- 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 ...
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 ...
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 ...
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
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 ...
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 ...
> don't think it is the bottle neck here. I am running this on a P4 > 3.2Ghz machine, so even VB is quick. > > Here are the symptoms of my problem. The 245's TXE seems to go high > (signaling that the...
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 ...
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 ...
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 ...
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 ...
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 ...
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...
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 ...
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-...
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) ...