Developing a new GBean

In this section, we will look at creating a new GBean and deploying the GBean to the server. Remember that a GBean is the basic unit in Geronimo that may provide a service or is used to wrap services deployed in the kernel. We will now develop a GBean, and in the process, we will look at various aspects of the GBean, such as the attributes, references, operations, constructor, interfaces, lifecycle management, dependencies, and so on.

A GBean Java class typically implements a service interface and exposes the operations from the service interface or provides lifecycle operations such as start or stop to initialize and shutdown the service. A GBean can use lifecycle management by implementing the GBeanLifecycle interface. The GBean is configured by attributes and references to other GBeans. Irrespective of what the Java class defines, the GBean is only identified by the structure defined by the GBean's metadata GBeanInfo. The Java class defining a GBean should make the GBeanInfo available through a static method getGBeanInfo(). The following is a typical structure of a Java class that defines a GBean:

public class MySampleGBean implements MySampleInterface, GBeanLifecycle {
...
public MySampleGBean(...) {
....
}
...
/* Lifecycle methods */
public void doStart() throws Exception {
...
}
public void doStop() throws Exception {
...
}
public void doFail() {
...
}
public static final GBeanInfo GBEAN_INFO;
static {
GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic ("GBean", MySampleGBean.class);
// Initialize the GBean structure here
...
GBEAN_INFO = infoFactory.getBeanInfo();
}
public static GBeanInfo getGBeanInfo() {
return GBEAN_INFO;
}
}


The static block at the bottom of the listing is used to initialize the GBeanInfo for the GBean. We use the GBeanInfoBuilder helper class to create the GBeanInfo.

GBean attributes

Attributes are used to configure the GBean. Each attribute must have a name and a type. Optionally, an attribute can be persistent, which means that the attribute's value will be saved and applied each time the GBean is loaded. Moreover, an attribute can be manageable, which means that the attribute's value can be overridden by using config.xml. Except for the four "magic" attributes (as we will see next), usually all attributes are persistent, and most attributes are manageable. The GBeanInfoBuilder.addAttribute() method can be used to add information about GBean attributes to the GBeanInfo. This method takes four parameters, as given below:

  • name— String value specifying the name of the attribute.

  • type— Class specifying the type of the attribute.

  • Persistent— Optional Boolean value specifying whether the attribute is persistent.

  • Manageable— Optional Boolean value specifying whether the attribute is manageable.

The following is an excerpt from the MySampleGBean class.

infoFactory.addAttribute("name", String.class, true, true);
infoFactory.addAttribute("name2", String.class, true, false);

This code defines a persistent and manageable attribute with name name of type String and a persistent but not manageable attribute with name name2 of type String.

A GBean can have zero or more attributes defined for it.

Magic attributes

Geronimo provides four special attributes that cannot be configured by a user. These attributes, referred to as magic attributes, must be designated as not persistent and non-manageable. The attribute details are as follows:

  • kernel: This attribute is of type Kernel. The value for this attribute is the Geronimo kernel in which the GBean is running.

  • objectName: This attribute is of type String. The value of this attribute is the JMX ObjectName that can be used to refer to this GBean component.

  • abstractName: This attribute is of type AbstractName. The value of this attribute is the unique name identifying this GBean instance.

  • classLoader: This attribute is of type ClassLoader. The value of this attribute is the class loader that is used for the current configuration.

The following is an excerpt from the MySampleGBean class:

infoFactory.addAttribute("kernel", Kernel.class, false);
infoFactory.addAttribute("objectName", String.class, false);
infoFactory.addAttribute("abstractName", AbstractName.class, false);
infoFactory.addAttribute("classLoader", ClassLoader.class, false);

This code defines the four magic attributes for the MySampleGBean class. The kernel attribute is used whenever you want to invoke certain kernel method implementations in your GBean. Geronimo will inject an instance of the currently-used kernel into that attribute. Similarly, usage of the abstractName and objectName attributes ensures that these are available to the GBean. The classLoader attribute is used when we need to gain access to the configuration's class loader.

GBean references

A GBean can reference other GBeans running in the kernel. A GBean reference has a name and a type. A reference can be either single valued or multiple valued. In the case of multiple valued references, the reference will be made to multiple GBeans of the same type. The GBeanInfoBuilder.addReference() method can be used to add GBean references to GBeanInfo. The parameters to this method are as follows:

  • name— A string value specifying the name of the reference.

  • type— A class representing the type of the reference. In the case of multiple valued references, the corresponding argument in the constructor or getter/setter methods will have the type Collection, and the type of the element in the collection is specified by this type parameter.

  • namingType— A string representing the J2EE type of the reference.

The following is an excerpt from the MySampleGBean class:

infoFactory.addReference("ServerInfo", ServerInfo.class);

This code defines a single valued GBean reference with name ServerInfo of type ServerInfo.

A GBean can have zero or more references defined for it.

GBean operations

A GBean can make zero or more service operations available. The GBeanInfoBuilder.addOperation() method can be used to add GBean operations to GBeanInfo. The parameters for this method are as follows:

  • name— A string value specifying the name of the operation.

  • parameterTypes— An optional array of class objects specifying the parameter types of the operation.

  • returnType— An optional string value specifying the return type of the operation.

The following is an excerpt from the MySampleGBean class:

infoFactory.addOperation("myMethod1", "java.lang.String");

This code defines a GBean operation with the name myMethod1, with no arguments, and the return type String.

GBean constructor

A GBean can have a constructor configured by using the GBeanInfoBuilder.setConstructor() method. The parameter to this method is as follows:

  • parameterNames— An array of strings containing the names of attributes and references that form the parameters of the constructor.

The following is an excerpt from the MySampleGBean class:

infoFactory.setConstructor(new String[] {"kernel", "objectName", "abstractName", "classLoader", "name"});

This code defines a GBean constructor with five parameters, which are all GBean attributes.

If no GBean constructor is defined, then the Java class must have a public no-argument constructor defined.

GBean interface

A GBean can have zero or more service interfaces defined by using the GBeanInfoBuilder.addInterface() method. The parameters to this method are as follows:

  • intf— The Java interface that should be added as the GBean interface.

  • persistentAttributes— An optional array of strings specifying persistent attributes.

  • manageableAttributes— An optional array of strings specifying manageable attributes.

The following is an excerpt from MySampleGBean:

infoFactory.addInterface(MySampleInterface.class);

This code adds MySampleInterface as a GBean interface in MySampleGBean.

Adding an interface as the GBean interface allows the querying of the kernel for GBeans using the interface.

GBeanLifecycle

A GBean can use lifecycle management support by implementing the GBeanLifecycle interface. The methods in this interface are as follows:

  • doStart()— This method is called when the GBean is started. Any module dependencies, GBean dependencies, and any GBeans in the references will have been started already.

  • doStop()— This method is called when the GBean is stopped.

  • doFail()— This method is called when the GBean can not be started due to an exception in doStart().

Sample GBean MySampleGBean

Create a Maven project by using the following command:

mvn archetype:create -DgroupId=packtsamples -DartifactId=gbean-sample

This will create a directory gbean-sample with pom.xml. Change the pom.xml as given below, to add dependencies such as geronimo-kernel and geronimo-system JARs, as our GBean uses classes from these Geronimo modules:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>packt-samples</groupId>
<artifactId>gbean-sample</artifactId>
<packaging>jar</packaging>
<version>1.0</version>
<name>gbean-sample</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.apache.geronimo.framework</groupId>
<artifactId>geronimo-kernel</artifactId>
<version>2.1.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.geronimo.framework</groupId>
<artifactId>geronimo-system</artifactId>
<version>2.1.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

Run the following command to create Eclipse project artifacts:

mvn -Peclipse eclipse:eclipse

Import the project into an Eclipse workspace by using the option File | Import | Import Existing Projects into Workspace.

Create a Java interface named packtsamples.MySampleInterface. This interface definition is given below:

package packtsamples;
public interface MySampleInterface {
String myMethod1();
}

Create a Java class named packtsamples.MySampleGBean. The class definition is given below:

package packtsamples;
...
public class MySampleGBean implements MySampleInterface, GBeanLifecycle {
private Kernel kernel;
private String objectName;
private AbstractName abstractName;
private ClassLoader classLoader;
private String name;
private String name2;
private ServerInfo serverInfo;
public MySampleGBean(Kernel kernel, String objectName, AbstractName abstractName, ClassLoader classLoader, String name) {
this.kernel = kernel;
this.objectName = objectName;
this.abstractName = abstractName;
this.classLoader = classLoader;
this.name = name;
System.out.println("kernel = "+kernel);
System.out.println("objectName = "+objectName);
System.out.println("abstractName = "+abstractName);
System.out.println("classLoader = "+classLoader);
System.out.println("name = "+name);
}
public void setServerInfo(ServerInfo serverInfo) {
this.serverInfo = serverInfo;
System.out.println("serverInfo = "+serverInfo);
}
public String myMethod1() {
StringBuffer out = new StringBuffer(this.getClass() .getSimpleName()+"["+name+"].myMethod1()
");
out.append("server version = "+serverInfo.getVersion()+"
");
out.append("server build date = "+serverInfo.getBuildDate() +"
");
out.append("server build time = "+serverInfo.getBuildTime() +"
");
out.append("server copyright = "+serverInfo.getCopyright()+"
");
out.append("server base directory = "+serverInfo.getBaseDirectory()+"
");
out.append("server current base directory = "+serverInfo.getCurrentBaseDirectory());
System.out.println(out.toString());
return out.toString();
}
public void setName(String name) {
this.name = name;
}
public void setName2(String name2) {
this.name2 = name2;
}
public void doFail() {
System.out.println(this.getClass().getSimpleName()+ "["+name+"] Failed.............");
}
public void doStart() throws Exception {
System.out.println(this.getClass().getSimpleName()+ "["+name+"] Started............");
}
public void doStop() throws Exception {
System.out.println(this.getClass().getSimpleName()+ "["+name+"] Stopped............");
}
GBeanSample GBean MySampleGBeanpublic static final GBeanInfo GBEAN_INFO;
static {
GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic ("GBean", MySampleGBean.class);
// Initialize the GBean structure here
infoFactory.addAttribute("kernel", Kernel.class, false);
infoFactory.addAttribute("objectName", String.class, false);
infoFactory.addAttribute("abstractName", AbstractName.class, false);
infoFactory.addAttribute("classLoader", ClassLoader.class, false);
infoFactory.addAttribute("name", String.class, true, true);
infoFactory.addAttribute("name2", String.class, true, false);
infoFactory.addReference("ServerInfo", ServerInfo.class);
infoFactory.setConstructor(new String[] {"kernel", "objectName", "abstractName", "classLoader", "name"});
infoFactory.addOperation("myMethod1", "java.lang.String");
infoFactory.addInterface(MySampleInterface.class);
GBEAN_INFO = infoFactory.getBeanInfo();
}
public static GBeanInfo getGBeanInfo() {
return GBEAN_INFO;
}
}

Build the module by using the following command:

mvn install

This will create the module JAR file gbean-sample-1.0.jar under the target directory. This JAR contains the GBean definition class of MySampleGBean. In the next section, we will see how we can create instances of this GBean.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset