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:

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 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:

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:

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:

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:

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

  • Available only in EE.

Opposite of create-app-ref-from-server-instance.

When last reference is removed, undeployment occurs.

   

Delete an Application Reference from a server instance

  • Available only in EE.

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:

  1. During the onReady() of AdminService, an attempt is made to register the MBeans.
  2. An MBean is registered in the MBeanServer, if following is true:
  3. The registered MBeans are initialized with the properties that are provided in the configuration.
  4. 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:

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:

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:

slightly outdated class-loader hierarchy for custom MBeans

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

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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:

 

grant codeBase "file:${com.sun.aas.instanceRoot}/applications/mbeans/-" {

javax.management.MBeanTrustPermission "register" ;

};

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:

  1. MBeanServer Behavior regarding Object Names

$Author: kedar $
$Id: custom-mbeans-design-document.html,v 1.6 2005/05/27 10:19:27 kedar Exp $