Date: 2004-12-20T20:03:04
   Editor: SrinathPerera <[EMAIL PROTECTED]>
   Wiki: Apache Geronimo Wiki
   Page: GBeansArticle1
   URL: http://wiki.apache.org/geronimo/GBeansArticle1

   no comment

New Page:

'''Content'''
[[TableOfContents]]

= Geronimo GBean Architecture =
== Abstract ==

“The Geronimo, Apache J2EE Container is build on top of a Kernel that does know 
nothing about J2EE. The Kernel is essentially a framework for the Components 
called GBeans and that framework supports Inversion of Control, IOC. The 
Article explains the theoretical aspects, GBean Life Cycle, GBean States and 
Dependency Injection with few examples and explains how to write a Simple 
GBean.” 

== Introduction ==

Consider a platform like Linux or Windows which has a Operating System core 
that provides the system calls and set of application that run on top of the 
those system calls. Geronimo is built on top of a similar core which knows 
nothing about the J2EE and that core, Geronimo Kernel is essentially a 
framework for components called GBeans. 
Any Complex System can be modeled as set of components that hold states, set of 
  relationships among them and how each component reacts for certain events. 
What Geronimo Kernel does is provide a framework for the GBeans with following 
Services.

 1. GBeans can hold states either persistent or non-persistent 
 1. Relationships among the GBeans can be defined with them
 1. GBeans can contains logic that defines how the GBeans react to the events 
that occurred

        Almost Everything in Geronimo is a GBean, Containers, Connectors, 
adapters, application so on. GBeans generated a Mesh of component as Explained 
by the following figure. 


        J2EE Container comprised of two types of Citizens, the first class 
citizens like Web Container, EJB Containers who provides the core services, And 
the second class citizens which are the applications deployed in the first 
class citizens like EJBs and Servlets.
        The architecture of the Geronimo can be explained in terms of GBeans 
behaviors. All the time the Geronimo is set of running GBeans, and each First 
class Citizen is a set of GBeans that are related and they are loaded via the 
plans which are essentially a XML serialization of GBeans. When the plans are 
loaded and started the GBeans that included in the plans will be started and in 
simple words the EJB Containers or the Web Container will be started. 
        The applications that run in a J2EE Container are explained by the 
Deployment Descriptors and the Java Classes that are packed as a j2ee 
application archive. Geronimo Deployer parses those archives that explains the 
J2EE application and constructs GBeans out of them. When those constructed 
GBeans are started the j2ee application is deployed and available inside the 
J2EE Container. Those GBeans can be serialized and stored and as a result once 
an application is converted to GBean and added to the Geronimo it will be 
available even after the server is restarted. 

== GBeans in a Conceptual point of View ==

The concepts that provide the base for the GBeans have much longer history in 
the sense that the Geronimo Kernel is an inversion of Control, IOC framework 
where the  IOC is also known as the dependency injection. 
The essence of IOC or the dependency injection is to create a loosely coupled 
architecture where the dependencies among components are managed by the 
framework. When a component has a dependency on other component the IOC 
framework will find the correct component and make it available to the first 
component. The dependency injection name comes from the fact that the framework 
automatically injects the dependencies to the component. 
Most simple form of IOC or the Dependency injection is to by system wide known 
values. For an instance let us assume this is Web Service that is to deployed 
inside Axis, do not worry about Axis but just assume that the Axis will load 
the following class and called the doit() method. 

{{{
public class WS{
        public WS(MesageContext msgctx){

        }

        public void doit(){
        }
}

}}}

But Axis has something call MesageContext that has all the configuration 
information. In order to give a reference of Message Context to the WS class 
Axis can say “if you have a Constructor like XX(MessageContext) or you have a 
method like setMessageContext(MessageContext msgctx) I will inject the 
MessageContext to you”


This is the simplest form of dependency injection the framework look at the 
class and find out that the class expected a  MessageContext to be inject it 
in. Or in other words the IOC framework inspect our components for certain 
patterns in methods, Parameters and the Constructors that when the pattern is 
found provides a Service to the Component, in the example we consider the 
service is giving a reference to the message Context. 

To get a better understanding about the use of the IOC one should look at the 
methods that were used to develop the system with decoupled components. The 
decoupling of the system is all about the interaction among the components. 

 1. Interfaces and Header files together with Factories provide decoupling of 
the system with minimal amount of coding.
 1. The property files together with the, interfaces and factories (e.g. 
loading of the different implementations of JNDI using the property files.) 
make it possible to decouple with out recompilation of the code.
 1. Registry Service together with lookups separate the service information 
from the caller by hiding them behind a name.
 1. IOC or the dependency injection allows the automatic injection of 
references as they become available.

        The Idea of IOC is to define all the relationships among the components 
in terms of the framework level configurations and each component is injected 
to the other components that refer the service when the first component is 
available. 
For an example let us consider the how a GBean G1 obtains a reference to a 
Configuration Store. The G1 is configured specifying the patterns of the 
reference it is expected. 

{{{
e.g. bean.setReferencePatterns(“configStore”,*:type=configStore,*”);
}}}

When a another GBean whose name match the pattern “*:type=configStore,*” is 
started it is automatically injected in to the G1. This is more like Aspect 
Oriented programming, AOP where the developer says to the framework what is 
need to be done rather than how to do it. 

        But this does not means that the IOC is the only way to create 
decoupled systems and all the four ways of doing is useful and used in 
practice. It is matter of choosing the right tool for the occasion and there 
are good examples as well as bad examples for each.


== GBean Life Cycle ==
GBean can be in any of the three states stored, loaded and running where the 
stored state it is saved in a configuration store or saved in a plan. When it 
is loaded the kernel mapped it to a name and knows about it. Each GBeans is a 
bind with a name at start up and that name is not persistent. This can be 
explained by an analogy, we can think about the GBean as a Java Class and the 
name as a variable name the where the compiler bind to the specific instance of 
the class. In the same way the class can have more than one instance   the same 
GBean can be loaded under more than one name and stored in number of places
. 

== State of GBeans ==
GBeans have two types of states, attributes and references. The references will 
be covered under the third part. The attributes are two types, persistent and 
non-persistence. The GBeans can be stored and restored using the inbuilt 
support. 
There are special types of magic attributes defined by the architecture; the 
values for the magic attributes loaded depend on the environment the GBean 
loaded on. For an example the magic attribute “kernel” refers to the Kernel and 
when it is specified at the constructor it is automatically injected to the 
class by the framework. Similarly the ClassLoader attributes inject the current 
class loader and the ObjectName attributes inject the current name the GBean 
started under. 
Complete list of all magic attributes can be found in the GBeanMBean class in 
the kernel.  The magic attributes can not be persistent as they are bound with 
the environment it is started. Note that in our first example of dependency 
injection where a Web Service is deployed to Axis, the MessageContext is a 
Magic attribute. 
GBean with one attribute val 1 will be look like this.

{{{
public class MyGBean implements GBeanLifecycle {
    private final String val;
    static {
        GBeanInfoBuilder infoFactory =  ...
        // attributes
        infoFactory.addAttribute("val", String.class, true);
        // operations
        infoFactory.addOperation("getBean1");
        infoFactory.setConstructor(new String[]{"val"});
        GBEAN_INFO = infoFactory.getBeanInfo();
    }

     public ConstructorInjectionGbean(String val )     {
        this.val = val;
    }
...
}
}}}

To starting Our GBean can be done with the following code. The GBean 
implementation is done on top of JMX and the GBeanMBean accepts GBean info and 
convert it in to an Mbean.

{{{
GBeanMBean gmb = new GBeanMBean(MyGBan.GBEAN_INFO);
gmb.setAttribute(“value”,”To be or not to be that is the queation”);
ObjectName myGbeanName = ObjectName.newInstance(“Geronimo.my:name=mine”);
kernel.loadGBean(myGbeanName,gmb);
kernel.startGBean(myGbeanName);
//dowork
kernel.stopGBean(myGbeanName);
kernel.unloadGBean(myGbeanName);
}}}

== Dependency Injection ==

There are two types of relationships 

1. Single references 
1. Reference Collections

===  Single references ===
The references are injected to a GBean in one of the two ways; the 
getter/setter injection and the constructor injection based on how the 
dependencies injected in to the java Class that use to implements the GBean. 
With the getter and setter injection framework injects the attributes/ 
references using the getter and setter methods where as in the constructor 
injection s injects the parameters as constructor parameters. The second 
approach is more preferable as with that the GBeans support so called good 
citizen pattern making sure that the GBean is in usable state once it is 
started. Geronimo supports both methods but moving towards the complete 
constructor injection. 

Following is a simple GBean that uses constructor injection.

{{{
public class MyGBean implements GBeanLifecycle {
    private final String GBean1 bean1;
    static {
        GBeanInfoBuilder infoFactory =  ...
        // attributes
        infoFactory.addReferance("Bean1", GBean1.class, true); ---------(A)
        // operations
        infoFactory.setConstructor(new String[]{"Bean1"}); -------------(B)
        GBEAN_INFO = infoFactory.getBeanInfo();
    }

     public ConstructorInjectionGbean(GBean1bean1 )     {-----------(C)
        this.bean1 = bean1;
    }
...
}
}}}

Here the Line (A) said that there is a reference to the GBean1 and line (B) 
registered the matching constructor (C). In the Following code the developer 
specified the reference instance of GBean1 and start GBeans.

{{{
ObjectName GBean1= ObjectName.newInstance(“Geronimo.my:name=gb1”);
... //start the GBEan 1
GBeanMBean gmb = new GBeanMBean(MyGBan.GBEAN_INFO);
gmb.setReferencePatterns(“GBean1”, GBean1Name);

ObjectName myGbeanName = ObjectName.newInstance(“Geronimo.my:name=mine”);
kernel.loadGBean(myGbeanName,gmb);
kernel.startGBean(myGbeanName);
//dowork
}}}

When the MyGBean is started an instance of GBeean1 is injected via the 
constructor.

=== Reference Collections ===
Only difference when the Reference collection come in to play is replacing the 
GBean1 references in the above example with Collection and when specifying the 
name of the referenced GBean it is specified as a pattern with * and?

{{{
bean.setRefercePatterns(“Geronimo.my:*”);
}}}

The code asks the framework to make available all the GBeans with the Domain 
name “Geronimo.my:”. When a GBean that whose matches the patterns is started it 
is automatically injected to the referee GBean. 

Logic in GBeans
GBeans leave the handling of the logic more or less in the form of usual java 
code and the Methods in the GBean class can be register to the GBean by adding 
a         

{{{
infoFactory.addOperation("doit",
new Object[]{val1,val2},new String[]{
val1.getClass().getName(),
val2.getClass().getName()}); --------- (A)
}}}

Kernel supports kernel.invoke(“objectName”,“methodName”,.. )  Using which one 
can call any method in any other GBean. But use of this is discouraged and 
accepted way to do it is to register reference pattern and obtain the instance 
of the other GBean injected in and code simple java style on the code. 

E.g. Say GBean G1 need to call the doit() on GBean G2 the crude way to do it is 
to  

{{{
kernel.invoke(“G2Name”,“doit”);
}}}

Correct way to do it is write G1 like 

{{{
class G1 implements GBeanLifCycle{
        ...
private final G2 g2;
    
    static {
        GBeanInfoBuilder infoFactory = new GBeanInfoBuilder("G1",
                G1.class);
        infoFactory.addReference("G2",G2.class); --------- (A)
         infoFactory.addConstructer("G2"); ---------------- (B)
 GBEAN_INFO = infoFactory.getBeanInfo();
    }
    public ConstructorInjectionGbean(G1 g2 )     {
        this.g2 = g2;
   }
    public void doG1Work(){
g2.doit();
    }
}

}}}

At line (A) defining there is a reference to G2 and at line (B) adding a 
constructor that inject the G2 and G1 obtain a reference to the G2. Then   
logic is implemented using simple java code. 
GBeans have interfaces that make the GBean implements a given method. By making 
the GBean class implements the a interface and putting a entry 
infoFactory.addInterface(“interfaceName”) will automatically add the all the 
methods in the interface to the GBean and the getters and setter will be mapped 
to the attributes. 

== Sample Code  ==
You can find few Sample GBeans and few Test Cases that demonstrate their use 
from [http://apache.org/~hemapani/docs/gbeans-sample.zip]. To run the test case 
you need maven installed in your machine. 

== Summary ==
The GBean architecture knows nothing about J2EE and a General framework for the 
developed loosely coupled System with IOC. It can be used outside Geronimo and 
can have potential to be the generic Architecture for loosely coupled Systems. 
This article explains the concepts and how to use the GBeans.

== References ==

[1] The Article, A Brief Introduction to IoC by Sam Newman, 02/10/2004

[2] Inversion of Control Containers and the Dependency Injection pattern, by 
Martin Fowler, http://www.martinfowler.com/articles/injection.html

[3] IoC Overview, Web Work dashboard 
http://wiki.opensymphony.com/display/WW/IoC+Overview

[4] Article Dependency Inversion Principle, 
http://www.objectmentor.com/resources/articles/dip.pdf

[5] Interview with Dian Sundstrom, at Server Side 
http://www.theserverside.com/talks/videos/DainSundstrom/dsl/q01.html

[6] Geronimo Kernel Module http://geronimo.apache.org


Reply via email to