Custom
MBeans in Appserver 9.0: Design Document
Table of
Contents
1
Introduction
Custom MBeans are a new feature
for Appserver 9.0. At some point in time, MBeans are expected to become a part
of J2EE standard deployment, but this feature is to be implemented in Appserver
9.0 as a proprietary extension. This work is expected to be leveraged by self
management rules infrastructure for this release. In general, the goal is to be
able to create and delete MBeans in Appserver runtime and modify their meta-data
properties (attributes) dynamically and listen to the notifications emitted by
them. As this is something that we are doing for the first time for appserver,
there are a few restrictions on the MBean code that can be loaded and run dynamically
by the appserver.
2
General Design Principles
In the simplest form, an
MBean is a standard MBean that has a management interface and its implementation.
A user writes a simple Java Source file that has got a bunch of attributes that
can be set according to needs. Appserver receives both the interface and implementation
code for the MBean and registers it in the available MBeanServer, with an ObjectName
that it formulates. The MBean is then available for management. User code for
instance, can listen for JMX notifications remotely or modify the attributes
of this MBean by connecting to the DAS's JMX Connector Server in a secure manner.
It is important to note that the attributes of the MBean are persisted as properties
so that they are available across restarts of the (target) server.
To keep it simple and align
it with potential inclusion in J2EE 6.0, defining, transmitting an archive containing
the MBean classes is not a design goal. Here is a typical use case:
- User defines an MBean
class (and optionally, an interface). It is made part of server's classpath.
- User starts the server.
- User uses the create-mbean
command to create the MBean. The default target is domain. The other targets
are a standalone server instance and a cluster. When created in the domain,
the MBean will be available at runtime in DAS. When created in a cluster,
an MBean definition will be available in the domain and MBean instance will
be available in the MBeanServer in each and every server instance constituting
the cluster.
Another important design
goal is to be able to quickly deploy a single MBean class without having to
restart the server instance. This meshes well with the self-management initiative.
2.1 Deployment/Undeployment/Redeployment/Creating-Deleting
References to Custom MBeans/Listing of MBeans
2.1.1 Deployment
"Deployment"
is the first-time creation of an MBean definition in server's configuration
and registration of corresponding MBean instance in target MBeanServer.
Since we are treating an
MBean similar to an Enterprise Application, from a runtime perspective, the
MBean definition along with an application-reference is what matters. This is
what happens during the deployment of a custom MBean: User provides an implementation
class-name of the MBean. This is the only required option. If the MBean could
be registered, the ObjectName of the MBean would be: user:type=<class-name>.
The following is true for the deployment of MBeans:
- The MBean implementation
and interface class must be available to the server. This implies that
it is a part of application server classpath or the bits are manually copied
to a particular loacation (prior to creation of MBean) as documented in the
classloader section.
- The ObjectName with
which the MBean is registered is selected. Here is the ObjectName
Selection Algorithm.
- All the checks are performed
regarding the validity of the given MBean class
so that it could be registered as an MBean in the MBeanServer.
- The attributes provided
are validated. This is optional. If the user ends up providing the initial
values of the MBean attributes correctly, they are marked for persistence.
The detailed validation is performed as described in the validation
section.
- A configuration element
is created. The contents of the configuration element are as follows:
- An mbean
subelement is created in the applications
element in the domain.xml. Attributes of this (xml-element) are as follows:
| name |
name
the unique identifier in the entire applications element. |
| object-type |
type
of the mbean. It will be always be "user" in case
of user-defined mbean. In case of a few built-in custom-mbeans, the
type will be "system-admin". A user never
creates an MBean of object-type other than "user". |
| object-name |
the
object-name determined by this algorithm. |
| impl-class-name |
the
fully qualified name of the Java class implementing mbean interface. |
| enabled |
flag
indicating whether the mbean is enabled. This means that on startup,
this MBean will be registered in the MBeanServer, if the object-type
is "user". More on this in the loading
section. By default this is set to "enabled".
User could set it false later if s/he intends not to register this
MBean during startup. |
- In PE of appserver,
the valid target is only the domain or DAS. Thus in this case, an implicit
application-reference
is created for the definition created above. Note that this is because PE
user is agnostic of creating any references (e.g. using create-application-ref
command).
- In EE of appserver,
the valid target can be the domain, a standalone server instance or a cluster.
Thus, in EE an explicit target needs to be specified. All the rules about
cluster and standalone server instance deployment for an enterprise application
/module hold good here.
- Once the configuration
is done, a notification is sent to the runtime system (the DAS, individual
server instances if they are running) to register the MBean instance
in MBeanServer.
- The runtime system attempts
to load and register the MBean. If it can not do so, a log message is generated,
but the entire operation is not aborted.
- The attributes that
are specified in the initialization (optional operation) are then applied
using multiple setAttribute calls on the MBeanServer. Any errors reported
are not considered fatal. User should take care of read-only attributes and
consequences of setting these attributes.
The situation is a little
different, when the MBean class is not part of server-classpath at the server
startup and user needs to "deploy" a new custom MBean class dynamically.
This introduces the need of a custom class loader(s) and it is discussed in
this section.
2.1.2 Undeployment of
Custom MBeans
"Undeployment"
of an MBean means deregistration of the MBean instance from the target server(s)
(i.e. its MBeanServer) and removal of the MBean definition from the configuration.
For deregistration to succeed, the MBean should be enabled (and the target server
should be running). Following things happen when the custom MBean is undeployed:
- Like enterprise applications,
it is confirmed that the MBean can be removed from the given target like domain,
instance and cluster. In a nutshell, following rules apply:
- An MBean may be
deleted if it is present in the specified target.
- An MBean may not
be deleted from the domain, if it has got references in other targets.
In order to delete the MBean from a domain, users need to make sure that
no references exist. This is mostly true for EE. In PE, deletion of MBean
should always succeed, if 1. is true.
- Unlike enterprise applications,
no cleanup is performed on the disk for the MBean Classes/interfaces that
user has manually copied. If the MBean classes are loaded from server's system
classpath, this is obviously true.
2.1.3 Redeployment of
Custom MBeans
"Redeployment"
of Custom MBeans means changing the implementation of the MBean interface. It
is expected (but not enforced) that the MBeanInfo does not change while modifying
the implementation. It is to be noted that this is automatic once the new bits
of the MBean implementation class are provided.
Here is how a redeployment
works:
- User copies the new
bits of an already deployed MBean to a specific location
on the domain's file system.
- Server monitors this
file system for any changes at a regular interval.
- When there is a change
in the file system, the server confirms if any of the MBean implementation
classes changed. In case a change is detected in any of the MBeans, a notification
is such that:
- The current instance
of the MBean is unregistered, if it is enabled.
- The current class
and corresponding class-loader is nuked.
- A new class-loader
loads the new bits of the same class (name).
- The MBean instance
is registered in the MBeanServer. This instance corresponds to the new
implementation of the MBean class. Note that this
This necessitates the use
of one or more class-loaders. Note that if an MBean with
a particular name exists, then an attempt to recreate it will fail.
2.1.4 Creating Application
Reference for a Custom MBean
This operation is available
only in appserver EE.
Creating an application
reference to an already deployed MBean from a server or cluster results in changing
the cluster/server configuration and making sure that the MBean instance is
available in the target MBeanServer, if the server instance is running.
In order for this to happen,
the class-bits are made available using the synchronization
process. Here is what happens during the application reference creation:
- An MBean definition
should exist for this operation to succeed. The configuration is changed for
all the server instances in the given cluster.
- A notification is sent
to the server instances. The existing notification types are reused.
- Upon receiving the notification,
the listener synchronizes the MBean-class bits and attempts to register the
MBean in MBeanServer. The initialization of the attributes follows.
2.1.5 Deleting Application
Reference for a Custom MBean
This is reverse of creating
a reference. The operation is available only in appsever EE.
Deleting an application
reference results in changing the server/cluster configuration and making sure
that the MBean instance is deregistered from the target MBeanServer, if the
server is running. No class-bits are cleaned up. The MBean definition in the
configuration is not removed.
2.1.6
Listing Custom MBeans
Listing of MBeans results
in producing a list of MBean definitions along with other information of interest.
This is specific to a target.
Following is output that
can be seen for each MBean entry:
- class-name of the MBean
- name of the MBean if
specified while creating it
- object-name of the MBean
- object-type of the MBean
- a boolean indicating
whether the MBean is enabled
In general the format is
left to implementation and no client code should depend on this output. It is
not an exposed interface.
Here
is the summary of various scenarios for deployment and undeployment
The following table shows
the changes to the configuration and changes to the runtime.
| Use Case |
Before
Operation |
Config
After Operation |
Runtime
After Operation |
|
Deploy
an MBean "foo" to the domain
[Note that
currently we have an enabled flag on both a mbean level and an application-ref
level, which is not required. We are going to use the attribute enabled
only on the mbean-definition, i.e. the one in <mbean> element].
|
<domain>
<applications>
...
</applications>
...
<servers>
<server name="server">
<!-- identifies the DAS -->
</server>
</servers>
</domain> |
<domain>
<applications>
... <mbean name="foo" object-type="user"
enabled="true".../>
</applications>
...
<servers>
<server name="server">
<!-- identifies the DAS -->
... <application-ref ref="foo"/>
</server>
</servers>
</domain>
|
The MBean
must be available in the DAS's runtime in the default MBeanServer.
The MBean
is enabled. Note that this needs all the validation
checks to pass, otherwise the deployment fails.
|
| Deploy
an MBean "foo" to a standalone server instance "s1"
using the "target" option on CLI/GUI. |
<domain>
<applications>
...
</applications>
...
<servers>
<server name="server">
<!-- identifies the DAS -->
</server>
<server name="s1">
</server>
</servers>
</domain>
|
<domain>
<applications>
..<mbean name="foo" object-type="user"
enabled="true".../>
</applications>
...
<servers>
<server name="server">
<!-- identifies the DAS -->
</server>
<server name="s1">
..<application-ref ref="foo"/>
</server>
</servers>
</domain>
|
The
MBean must be available in the server instance "s1" if it is running.
It is registered in default MBeanServer. |
|
Deploy
an MBean "foo" to a cluster "c1", that has two server
instances, "s1", "s2".
[Note that
we take a "server-centric" view even though the target is a
"cluster" because the runtime matters here. Runtime has chosen
that a server looks at its own configuration and does not pay attention
to whether it is a part of cluster or not. Thus a server, while starting
up, only looks at application-ref's that are in its own definition].
|
<domain>
<applications>
...
</applications>
...
<servers>
<server name="server">
<!-- identifies the DAS -->
</server>
<server name="s1"> ...</server>
<server name="s2"> ...</server>
</servers>
<clusters>
<cluster name="s1s2" config-ref="s1s2-config"...
>
.. <server-ref>s1</server-ref>
.. <server-ref>s2</server-ref>
</cluster>
</clusters>
</domain>
|
<domain>
<applications>
..<mbean name="foo" object-type="user
enabled="true" .../>
</applications>
..
<servers>
<server name="server">
<!-- identifies the DAS -->
</server>
<server name="s1">
.. <application-ref ref="foo"/>
</server>
<server name="s2">
.. <application-ref ref="foo"/>
</server>
</servers>
<clusters>
<cluster name="s1s2" config-ref="s1s2-config"...
>
.. <server-ref>s1</server-ref>
.. <server-ref>s2</server-ref>
</cluster>
</clusters>
</domain> |
If the
server instances are running, they will be informed of the mbean-definition
creation and then they will try to load the mbeans. The order of registration
in individual instances is arbitrary.
If the
instances are not running, the MBeans will be available only after they
start up.
|
|
Undeploy
an MBean from the domain
- allowed
only if there are no references other than that from the DAS.
|
<domain>
<applications>
..<mbean name="foo" object-type="user
enabled="true" .../>
</applications>
..
<servers>
<server name="server">
<!-- identifies the DAS -->
.. <application-ref ref="foo"/>
</server>
</servers>
</domain>
Not
allowed:
<domain>
<applications>
..<mbean name="foo" object-type="user
enabled="true" .../>
</applications>
..
<servers>
<server name="server">
<!-- identifies the DAS -->
.. <application-ref ref="foo"/>
</server>
<server name="s1">
.. <application-ref ref="foo"/>
</server>
<!-- This prevents it from getting undeployed from domain -->
</servers>
</domain>
|
<domain>
<applications>
...
</applications>
...
<servers>
<server name="server">
<!-- identifies the DAS -->
</server>
<server name="s1">
</server>
</servers>
</domain> |
Unregisters
the MBean from DAS' MBeanServer. |
|
Undeploy
an MBean from a standalone server instance
- Not
allowed in PE. In PE, it has to be undeployed from the domain.
- In EE,
it just results in removing the reference to the non-DAS server instance.
If the target server is DAS, the action results in undeployment, only
if it is not referenced from other instances.
|
-undeploy
from "s1"
<domain>
<applications>
..<mbean name="foo" object-type="user"
enabled="true".../>
</applications>
...
<servers>
<server name="server">
<!-- identifies the DAS -->
..<application-ref ref="foo"/>
</server>
<server name="s1">
..<application-ref ref="foo"/>
</server>
</servers>
</domain>
|
-undeploy
from "s1"
<domain>
<applications>
..<mbean name="foo" object-type="user"
enabled="true".../>
</applications>
...
<servers>
<server name="server">
<!-- identifies the DAS -->
..<application-ref ref="foo"/>
</server>
<server name="s1">
</server>
</servers>
</domain>
|
The
MBean would get deregistered from the server. |
|
Create
an Application Reference to an already deployed MBean from a standalone
server instance
- Available
only in EE.
- Fails
if the MBean with given name does not exist.
|
<domain>
<applications>
..<mbean name="foo" object-type="user
enabled="true" .../>
</applications>
..
<servers>
<server name="server">
<!-- identifies the DAS -->
..
</server>
<server name="s1"/>
</server>
</servers>
</domain>
|
<domain>
<applications>
..<mbean name="foo" object-type="user
enabled="true" .../>
</applications>
..
<servers>
<server name="server">
<!-- identifies the DAS -->
..
</server>
<server name="s1"/>
<application-ref ref="foo"/>
</server>
</servers>
</domain> |
- If the server
is running, the MBean will be registered in the target MBeanServer.
- If the server
is not running, MBean would be available only upon starting the server.
|
|
Create
an Application Reference to an already deployed MBean from a cluster
- Available
only in EE.
- Fails
if the MBean with given name does not exist.
- Adds
application-ref's to the servers that the cluster is composed of.
|
<domain>
<applications>
..<mbean name="foo" object-type="user
enabled="true" .../>
</applications>
..
<servers>
<server name="server">
<!-- identifies the DAS -->
</server>
<server name="s1">
</server>
<server name="s2">
</server>
</servers>
<clusters>
<cluster name="s1s2" config-ref="s1s2-config"...
>
.. <server-ref>s1</server-ref>
.. <server-ref>s2</server-ref>
</cluster>
</clusters>
</domain> |
<domain>
<applications>
..<mbean name="foo" object-type="user
enabled="true" .../>
</applications>
..
<servers>
<server name="server">
<!-- identifies the DAS -->
</server>
<server name="s1">
.. <application-ref ref="foo"/>
..
</server>
<server name="s2">
.. <application-ref ref="foo"/>
..
</server>
</servers>
<clusters>
<cluster name="s1s2" config-ref="s1s2-config"...
>
.. <server-ref>s1</server-ref>
.. <server-ref>s2</server-ref>
</cluster>
</clusters>
</domain>
|
|
|
Delete
an Application Reference from a server instance
|
Opposite
of create-app-ref-from-server-instance.
When last
reference is removed, undeployment occurs.
|
|
|
|
Delete
an Application Reference from a server instance
|
Opposite
of create-app-ref-from-cluster
When last
reference is removed, undeployment occurs.
|
|
|
2.2
Loading Custom MBeans at Server Startup and Redeployment/Enablement
Loading of an MBean implies
its registration in the target server at its startup. This is what happens when
the server starts up:
- During the onReady()
of AdminService, an attempt is made to register the MBeans.
- An MBean is registered
in the MBeanServer, if following is true:
- The MBean is configured
"enabled".
- The MBean has an
object-type "user" and is not referenced by any management-rule
in the server configuration. Thus all such MBeans only are loaded
aggressively. All the other MBeans are loaded lazily.
- The registered MBeans
are initialized with the properties that are provided in the configuration.
- Any MBean that has object-type
as "system-all" is considered part of management-rule (which
is either built-in or user-defined) and hence it is not registered up-front.
Such an MBean would be registered as a call-back from management-rule-enablement/loading.
When an MBean is disabled
or its application-reference is removed from a server instance, following things
happen:
- The MBean is deregistered
from the MBeanServer. The default behavior of the MBeanServerDelegate is to
emit an MBeanUnregistered Notification that anyone can listen to.
2.25
Validation of MBeans (Classes, interfaces, attribute values etc.)
Unlike Enterprise Applications/modules,
MBeans do not have a runtime descriptor. This means that the MBean-code
itself is the way to configure the runtime behavior of the MBean. This leads
to the following design/implementation choice:
- The ObjectName is formulated
using the selection algorithm. Invalid ObjectName implies
failure to create the MBean.
- An MBean is validated
by registering a dummy instance in the MBeanServer available in the DAS. If
this registration goes through, along with the initialization using the provided
attributes, the MBean is considered valid-for-creation. The dummy instance
is deregistered upon return. Creation of MBean fails, if this step fails.
2.3 Deployed
MBeans on the Server File System
The deployed MBeans are
stored at the following location in the domain:
[domain-root]
|----| applications
|--------| j2ee-applications
|--------| j2ee-modules
|--------| mbeans
|------------| Foo.class
|------------| FooMBean.class
|------------| ADynamicMBean.class
...
The server instance reflects
the same file system after synchronization of the bits at the remote server
location.
2.4 ClassLoader
for Custom MBeans
In essense, this is "loading"
the user code dynamically by the appserver processes. The loading follows following
contract:
- The Java classes stored
in the mbeans folder on the disk, are loaded by
exactly one instance of a class-loader called MBeanClassLoader. This is the
initiating class loader for all the MBeans. The System Class
Loader is the parent of this class loader in that the MBeanClassLoader delegates
to the former. When asked for the "MBean Class", MBeanClassLoader
is guaranteed to return the class.
- Only findClass() method
is implemented that finds the class bits from the disk.
- The System Class Loader
is the defining class loader for all the MBeans.
- All the distinct MBeans
(that have distinct implementation classes) are loaded by a single instance
of the MBeanClassLoader. The MBeanClassLoader is expected not to retain any
handle to the class bits on the disk.
- When a server instance
is running and an already loaded MBean class is changed on the disk (detected
by a timestamp-identifier-thread), a new instance of MBeanClassLoader comes
into being. This new instance is the initiating class loader of the new version
of the same class. Thus, two versions of a class with a given complete
package name are never loaded by the same class-loader. The class
now going out of scope, corresponding MBean and the class-loader instance
that loaded the class would eventually get garbage-collected.

2.4.1
Loading and unloading of Custom MBean Classes
2.4.2
Synchronization of Class-bits
2.5 Dynamic Configuration
2.6
ObjectNames of Custom MBeans
- If the user has specified
a valid
ObjectName, it is used. The ObjectName must be unique. The domain name
specified as part of the ObjectName must be "user". The ObjectName
specified by user may not be a pattern.
- If the user has not
specified the ObjectName and the MBean class does not implement the MBeanRegistration
interface, the ObjectName will be defaulted to user:impl-class-name=<class-name>.
This should be unique. Thus, in this case another MBean with the same class
will have a conflict.
- If the user has specified
the ObjectName and MBean class implements the MBeanRegistration interface,
an error is reported, if the two ways of getting ObjectName do not yield the
same ObjectName. This is mainly to take care of this MBeanServer
behavior.
- If the user has not
specified the ObjectName and MBean class implements the MBeanRegistration
interface, the ObjectName would come from the preRegister method implementation.
This method should return the intended ObjectName.
- If a class-name and
name is provided along with no other means to specify ObjectName (explicit
ObjectName, implementation of MBeanRegistration interface), then the ObjectName
would be: user:impl-class-name=<class-name>,name=<name>,server=<target>.
This is useful when creating multiple instances of the same MBean class
and to leverage the built-in cascading functionality. Thus, when such an MBean
is registered in a server instance "server1", it could have an ObjectName
"user:class-name=Foo,name=bar,server=server1". Note that
this is used only when the user does not specify the ObjectName in any manner.
(Implementation note: System Properties could be used to tokenize the ObjectName
while persisting it to domain.xml). [Note that this is still
under consideration].
2.6.1 MBeanServer to
Register Custom MBeans
Custom MBeans are registered
in the MBeanServer returned by com.sun.enterprise.admin.server.common.MBeanServerFactory.
For Appserver 9.0, this is the same as the PlatformMBeanServer.
2.7 Cascading Considerations
2.8 Self Management Rules
Using Custom MBeans
2.9 Security Policy Changes
There are various permissions
related to MBeans and MBeanServer. The permission that MBeanServer needs, to
load a particular MBean from a particular location is called javax.management.MBeanTrustPermission.
Thus the security policy of the server needs to be modified to include the following
grant block:
This will allow the DAS
and any other server instance to load the mbeans from the designated location.
3
Interfaces and Classes
4
MBean Configuration and its Dynamic Nature
5 User
Interface
5.1 CLI
This section describes
the asadmin commands that will be used to create/delete/list the custom MBeans.
These are remote-only commands.
5.1.1 create-mbean
This command creates and
registers the custom MBean. If the target MBeanServer is not running, MBean
is not registered.
create-mbean [DAS Connection
Options] [--name name] [--object-name object-name] [--target=server] [--attributes
[name=value:]*] implementation-class-name
| Option/Operand |
Comment |
| name |
It identifies a custom
MBean by name. Defaults to the MBean's implementation class name. |
| object-name |
User specified ObjectName.
User must ensure that this ObjectName is not already taken. ObjectName will
not be formulated by the server if specified explicitly. Defaults to "user:type=class-name".
(Details) |
| target |
The target for the
MBean. Identifies the server instance. Defaults to DAS. |
| attributes |
Specifies the names
and values of the attributes for the initialization of the MBean. |
| implementation-class-name |
Fully qualified name
for the MBean implementation. Should either reside in the archive
provided or the server class-path. |
5.1.2 delete-mbean
Deregisters the MBean identified
by this name and deletes its configuration. If the server is not running, only
the configuration is deleted.
delete-mbean [DAS Connection
Options] [--target=server] name
| Option/Operand |
Comment |
| name |
Specifies
the name of the MBean. |
| target |
Specifies
target server. Defaults to DAS. If there are multiple references to an MBean
in various servers, only one specific reference is deleted. When the last
reference is deleted, the MBean definition is deleted from the domain. |
5.1.3 list-mbeans
Lists the MBean definitions
and other relevant information.
list-custom-mbeans [DAS
Connection Options] target[=server]
| Option/Operand |
Comment |
| target |
The target
cluster/instance where the MBeans are registered. |
The output of this command
is displayed as described here.
5.2 GUI
6 Workspace
Considerations
7
Limitations
8
Future Work
9 Bibliography
1 Introduction
2 General
Design Principles
3 Interfaces
and Classes
4 Configuration
and Dynamicity of MBean Configuration
5 User
Interface
6 Workspace
Considerations
7 Limitations
8 Future
Work
9 Bibliography
FootNotes:
- MBeanServer
Behavior regarding Object Names
- If an MBean implements
MBeanRegistration interface, then the ObjectName returned by its preRegister
method (unless null) overrides the ObjectName passed in
the registerMBean/createMBean call on the MBeanServer. If the preRegister
method returns null, then the parameter passed to registerMBean/createMBean
is used.
$Author: kedar $
$Id: custom-mbeans-design-document.html,v 1.6 2005/05/27 10:19:27 kedar Exp
$