|
Java™ Platform Standard Ed. 7 DRAFT ea-b76 |
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||
java.lang.Objectjavax.management.ClientContext
public class ClientContext extends Object
Methods to communicate a client context to MBeans. A context is
a Map<String, String> that is provided by the client and
that an MBean can consult using the getContext() method.
The context is set on a per-thread basis and can be consulted by any
code that the target MBean calls within the thread.
One common usage of client context is to communicate the client's
Locale to MBeans. For example, if an MBean has a String attribute
LastProblemDescription, the value of that attribute could be
a description of the last problem encountered by the MBean, translated
into the client's locale. Different clients accessing this attribute
from different locales would each see the appropriate version for their
locale.
The locale case is sufficiently important that it has a special
shorthand, the getLocale() method. This method calls
and converts the
resultant String into a Locale object.getContext().get(LOCALE_KEY)
Here is what an MBean with a localized LastProblemDescription
attribute might look like:
public class LocaleSensitive implements LocaleSensitiveMBean {
...
public String getLastProblemDescription() {
Locale loc = ClientContext.getLocale();
ResourceBundle rb = ResourceBundle.getBundle("MyResources", loc);
String resourceKey = getLastProblemResourceKey();
return rb.getString(resourceKey);
}
...
}
Here is how a client can communicate its locale to the target MBean:
JMXConnector connector = JMXConnectorFactory.connect(url);
MBeanServerConnection connection = connector.getMBeanServerConnection();
MBeanServerConnection localizedConnection =
ClientContext.withLocale(connection, Locale.getDefault());
String problem = localizedConnection.getAttribute(
objectName, "LastProblemDescription");
In the more general case where the client wants to communicate context
other than the locale, it can use withContext instead of withLocale, and the target
MBean can retrieve the context using getContext().
The various with* methods, for example withLocale,
transmit the context of each request by encoding it in the ObjectName of
the request. For example, if a client creates a connection in the
French locale like this...
MBeanServerConnection mbsc = ...;
Locale french = new Locale("fr");
MBeanServerConnection localizedConnection = ClientContext.withLocale(mbsc, french);
...or, equivalently, like this...
MBeanServerConnection localizedConnection =
ClientContext.withContext(mbsc, "jmx.locale", "fr");
...then the context associates "jmx.locale" with "fr"
and a request such as
localizedConnection.getAttribute("java.lang:type=Runtime", "Name")
is translated into
mbsc.getAttribute("jmx.context//jmx.locale=fr//java.lang:Runtime", "Name").
A special namespace jmx.context//
extracts the context from the string jmx.locale=fr and establishes
it in the thread that will do
getAttribute("java.lang:Runtime", "Name").
The details of how contexts are encoded into ObjectNames are explained
in the encode method.
The namespace jmx.context// just mentioned is only needed by
remote clients, since local clients can set the context directly using
doWithContext. Accordingly, this namespace is not
present by default in the MBeanServer. Instead, it is
simulated by the standard RMI connector using a special
MBeanServerForwarder. If you are using this connector, you do not
need to do anything special. Other connectors may or may not simulate this
namespace in the same way. If the connector server returns true from the
method supportsSystemMBeanServerForwarder then it does simulate the namespace.
If you are using another connector, or if you want to be able to use the
with* methods locally, then you can install the MBeanServerForwarder yourself as described in the method newContextForwarder.
| Modifier and Type | Field and Description |
|---|---|
static String |
LOCALE_KEY
The context key for the client locale. |
static String |
NAMESPACE
The namespace that implements contexts, "jmx.context". |
| Modifier and Type | Method and Description | |
|---|---|---|
static
|
doWithContext(Map<String,String> context,
Callable<T> task)
Execute the given task with the client context set to
the given Map. |
|
static String |
encode(Map<String,String> context)
Returns an encoded context prefix for ObjectNames. |
|
static Map<String,String> |
getContext()
Get the client context associated with the current thread. |
|
static Locale |
getLocale()
Get the client locale associated with the current thread. |
|
static MBeanServerForwarder |
newContextForwarder(MBeanServer nextMBS,
MBeanServer loopMBS)
Create a new MBeanServerForwarder that applies the context
received from a client to the current thread. |
|
static MBeanServerForwarder |
newLocalizeMBeanInfoForwarder(MBeanServer mbs)
Create a new MBeanServerForwarder that localizes
descriptions in MBeanInfo instances returned by
getMBeanInfo. |
|
static MBeanServerConnection |
withContext(MBeanServerConnection mbsc,
String key,
String value)
Return an MBeanServerConnection object that is equivalent to the given MBeanServerConnection object except that operations on MBeans run with the given key bound to the given value in their thread context. |
|
static MBeanServer |
withContext(MBeanServer mbs,
String key,
String value)
Return an MBeanServer object that is equivalent to the given MBeanServer object except that operations on MBeans run with the given key bound to the given value in their thread context. |
|
static MBeanServerConnection |
withDynamicContext(MBeanServerConnection mbsc)
Returns an MBeanServerConnection object that is equivalent to the given MBeanServerConnection object except that remote operations on MBeans run with the context that has been established by the client using doWithContext. |
|
static MBeanServerConnection |
withLocale(MBeanServerConnection mbsc,
Locale locale)
Return an MBeanServerConnection object that is equivalent to the given MBeanServerConnection object except that operations on MBeans run with the given Locale in their thread context. |
|
static MBeanServer |
withLocale(MBeanServer mbs,
Locale locale)
Return an MBeanServer object that is equivalent to the given MBeanServer object except that operations on MBeans run with the given Locale in their thread context. |
| Methods inherited from class java.lang.Object |
|---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
| Field Detail |
|---|
public static final String LOCALE_KEY
The context key for the client locale. The string associated with
this key is an encoded locale such as en_US which could be
returned by Locale.toString().
public static final String NAMESPACE
The namespace that implements contexts, "jmx.context".
| Method Detail |
|---|
public static Map<String,String> getContext()
Get the client context associated with the current thread.
public static Locale getLocale()
Get the client locale associated with the current thread. If the client context includes the "jmx.locale" key then the returned value is the Locale encoded in that key. Otherwise the returned value is the default locale.
public static <T> T doWithContext(Map<String,String> context,
Callable<T> task)
throws Exception
Execute the given task with the client context set to
the given Map. This Map will be the result of getContext()
within the task.
The task may include nested calls to doWithContext.
The value returned by getContext() at any point is the Map
provided to the most recent doWithContext (in the current thread)
that has not yet returned.
The getContext() method returns the same value immediately
after a call to this method as immediately before. In other words,
doWithContext only affects the context during the execution of
the task.
As an example, suppose you want to get an attribute with whatever context has already been set, plus the locale set to "fr". You could write this:
Map<String, String>context = newHashMap<String, String>(ClientContext.getContext()); context.put(ClientContext.LOCALE_KEY, "fr"); String lastProblemDescription = ClientContext.doWithContext(context, newCallable<String>() { public String call() { return (String) mbeanServer.getAttribute(mbean, "LastProblemDescription"); } });
T - the type of value that the task will return. This type
parameter is usually inferred from the type of the task
parameter. For example, if task is a Callable<String>
then T is String. If the task does not return a value,
use a Callable<Void> and return null from its
call method.context - the context to use while executing task.task - the task to run with the key=value
binding.task.call().IllegalArgumentException - if either parameter is null, or
if any key in context is null or empty, or if any value
in context is null.Exception - If task.call() throws an
exception, doWithContext throws the same exception.
public static MBeanServer withLocale(MBeanServer mbs,
Locale locale)
Return an MBeanServer object that is equivalent to the given MBeanServer object except that operations on MBeans run with the given Locale in their thread context. Note that this will only work if the given MBeanServer supports contexts, as described above.
This method is equivalent to withContext(mbs, "jmx.locale",
locale.toString()).
IllegalArgumentException - if either parameter is null, or if
mbs does not support contexts. In the second case only,
the cause of the IllegalArgumentException will be an InstanceNotFoundException.
public static MBeanServerConnection withLocale(MBeanServerConnection mbsc,
Locale locale)
Return an MBeanServerConnection object that is equivalent to the given MBeanServerConnection object except that operations on MBeans run with the given Locale in their thread context. Note that this will only work if the given MBeanServerConnection supports contexts, as described above.
This method is equivalent to withContext(mbs, "jmx.locale",
locale.toString()).
IllegalArgumentException - if either parameter is null, or if
the communication with mbsc fails, or if mbsc does not
support contexts. If the communication with mbsc fails, the
cause of this exception will be an
IOException. If mbsc does not support contexts, the
cause will be an InstanceNotFoundException.
public static MBeanServer withContext(MBeanServer mbs,
String key,
String value)
Return an MBeanServer object that is equivalent to the given MBeanServer object except that operations on MBeans run with the given key bound to the given value in their thread context. Note that this will only work if the given MBeanServer supports contexts, as described above.
mbs - the original MBeanServer.key - the key to bind in the context of MBean operations
in the returned MBeanServer object.value - the value to bind to the key in the context of MBean
operations in the returned MBeanServer object.IllegalArgumentException - if any parameter is null, or
if key is the empty string, or if mbs does not support
contexts. In the last case only, the cause of the IllegalArgumentException will be an InstanceNotFoundException.
public static MBeanServerConnection withContext(MBeanServerConnection mbsc,
String key,
String value)
Return an MBeanServerConnection object that is equivalent to the given MBeanServerConnection object except that operations on MBeans run with the given key bound to the given value in their thread context. Note that this will only work if the given MBeanServerConnection supports contexts, as described above.
mbsc - the original MBeanServerConnection.key - the key to bind in the context of MBean operations
in the returned MBeanServerConnection object.value - the value to bind to the key in the context of MBean
operations in the returned MBeanServerConnection object.IllegalArgumentException - if any parameter is null, or
if key is the empty string, or if the communication with mbsc fails, or if mbsc does not support contexts. If
the communication with mbsc fails, the cause of this exception will be an IOException. If mbsc does not support contexts, the cause will
be an InstanceNotFoundException.public static MBeanServerConnection withDynamicContext(MBeanServerConnection mbsc)
Returns an MBeanServerConnection object that is equivalent to the
given MBeanServerConnection object except that remote operations on
MBeans run with the context that has been established by the client
using doWithContext. Note that this will
only work if the remote system supports contexts, as described above.
For example, suppose the remote system does support contexts, and you
have created a JMXConnector like this:
JMXServiceURL url = ...; JMXConnector client = JMXConnectorFactory.connect(url); MBeanServerConnection mbsc = client.getMBeanServerConnection(); mbsc = ClientContext.withDynamicContext(mbsc);
Then if you do this...
MBeanInfo mbi = ClientContext.doWithContext(
Collections.singletonMap(ClientContext.LOCALE_KEY, "fr"),
new Callable<MBeanInfo>() {
public MBeanInfo call() {
return mbsc.getMBeanInfo(objectName);
}
});
...then the context with the locale set to "fr" will be in place
when the getMBeanInfo is executed on the remote MBean Server.
mbsc - the original MBeanServerConnection.IllegalArgumentException - if the mbsc parameter is null,
or if the communication with mbsc fails, or if mbsc
does not support contexts. If the communication with mbsc
fails, the cause of this exception
will be an IOException. If mbsc does not support
contexts, the cause will be an InstanceNotFoundException.public static String encode(Map<String,String> context)
Returns an encoded context prefix for ObjectNames.
If the given context is empty, "" is returned.
Otherwise, this method returns a string of the form
"jmx.context//key=value;key=value;...".
For example, if the context has keys "jmx.locale"
and "xid" with respective values "fr"
and "1234", this method will return
"jmx.context//jmx.locale=fr;xid=1234" or
"jmx.context//xid=1234;jmx.locale=fr".
Each key and each value in the encoded string is subject to
encoding as if by the method URLEncoder.encode(String, String)
with a character encoding of "UTF-8", but with the additional
encoding of any * character as "%2A". This ensures
that keys and values can contain any character. Without encoding,
characters such as = and : would pose problems.
context - the context to encode.IllegalArgumentException - if the context parameter
is null or if it contains a null key or value.
public static MBeanServerForwarder newContextForwarder(MBeanServer nextMBS,
MBeanServer loopMBS)
Create a new MBeanServerForwarder that applies the context
received from a client to the current thread. A client using
one of the various with* methods (for example withContext) will
encode that context into the ObjectName of each
MBeanServer request. The object returned by this method
decodes the context from that ObjectName and applies it
as described for doWithContext while performing
the MBeanServer request using the ObjectName without
the encoded context.
This forwarder can be used in a number of ways:
To add context decoding to a local MBeanServer, you can
write:
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); // for example
mbs = ClientContext.newContextForwarder(mbs, null);
To add context decoding to a connector server:
JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(...);
MBeanServer nextMBS = cs.getMBeanServer();
MBeanServerForwarder mbsf = ClientContext.newContextForwarder(nextMBS, null);
cs.setMBeanServerForwarder(mbsf);
For connectors, such as the standard RMI connector, that support
a system chain of MBeanServerForwarders, this forwarder will
be installed in that chain by default. See
JMXConnectorServer.CONTEXT_FORWARDER.
nextMBS - the next MBeanServer in the chain of
forwarders, which might be another MBeanServerForwarder or
a plain MBeanServer. This is the object to which MBeanServer requests that do not include a context are sent. It
will be the value of getMBeanServer() on the returned object, and can be changed with setMBeanServer. It can be null but
must be set to a non-null value before any MBeanServer requests
arrive.loopMBS - the MBeanServer to which requests that contain
an encoded context should be sent once the context has been decoded.
For example, if the request is getAttribute("jmx.context//jmx.locale=fr//java.lang:type=Runtime",
"Name"), then the context of the thread
executing that request will have "jmx.locale" set to "fr"
while executing loopMBS.getAttribute("java.lang:type=Runtime",
"Name"). If this parameter is null, then these requests will be
sent to the newly-created MBeanServerForwarder. Usually
the parameter will either be null or will be the result of getSystemMBeanServerForwarder() for the connector server in which
this forwarder will be installed.MBeanServerForwarder that decodes client context
from ObjectNames.public static MBeanServerForwarder newLocalizeMBeanInfoForwarder(MBeanServer mbs)
Create a new MBeanServerForwarder that localizes
descriptions in MBeanInfo instances returned by
getMBeanInfo. The MBeanServerForwarder returned by this method passes all MBeanServer methods through unchanged to the supplied object, mbs, with the exception of getMBeanInfo. To handle getMBeanInfo(objectName), it calls mbs.getMBeanInfo(objectName)
to get an MBeanInfo, mbi; it calls mbs.getClassLoaderFor(objectName) to
get a ClassLoader, cl; and it calls getLocale() to get a Locale, locale. The order
of these three calls is not specified. Then the result is mbi.localizeDescriptions(locale, loader).
This forwarder can be used in a number of ways:
To add description localization to a local MBeanServer, you
can write:
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); // for example
mbs = ClientContext.newLocalizeMBeanInfoForwarder(mbs);
To add description localization to a connector server, you will need to add both a context forwarder and a localization forwarder, for example like this:
JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(...);
MBeanServer nextMBS = cs.getMBeanServer();
MBeanServerForwarder localizeMBSF =
ClientContext.newLocalizeMBeanInfoForwarder(nextMBS);
MBeanServerForwarder contextMBSF =
ClientContext.newContextForwarder(localizeMBSF, null);
cs.setMBeanServerForwarder(contextMBSF);
Notice that the context forwarder must run before the localization
forwarder, so that the locale is correctly established when the latter
runs. So the nextMBS parameter of the context forwarder must
be the localization forwarder, and not vice versa.
For connectors, such as the standard RMI connector, that support
a system chain of MBeanServerForwarders, the context forwarder and
the localization forwarder will be installed in that chain, in the right
order, if you include
LOCALIZE_MBEAN_INFO_FORWARDER in the environment Map with
the value "true", for example like this:
MBeanServer mbs = ...;
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://...");
Map<String, Object> env = new HashMap<String, Object>();
env.put(JMXConnectorServer.LOCALIZE_MBEAN_INFO_FORWARDER, "true");
JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(
url, env, mbs);
mbs - the next MBeanServer in the chain of
forwarders, which might be another MBeanServerForwarder
or a plain MBeanServer. It will be the value of
getMBeanServer()
on the returned object, and can be changed with setMBeanServer. It can be null but
must be set to a non-null value before any MBeanServer requests
arrive.MBeanServerForwarder that localizes descriptions
in the result of getMBeanInfo.
|
Java™ Platform Standard Ed. 7 DRAFT ea-b76 |
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||
Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. Use is subject to license terms.