geronimo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Shawn Jiang <genspr...@gmail.com>
Subject Re: [CONF] Apache Geronimo v2.2: Developing and Deploying a Geronimo GBean (page edited)
Date Mon, 23 Mar 2009 08:02:39 GMT
If no objection,  I can create a JIRA and submit the sample project as a
patch.

On Mon, Mar 23, 2009 at 3:51 PM, Shawn Jiang <genspring@gmail.com> wrote:

> I'm wondering if we should put the GBean samples in this doc to a part of
> current geronimo samples.
>
>
> On Mon, Mar 23, 2009 at 3:45 PM, <confluence@apache.org> wrote:
>
>>    Page Edited : GMOxDOC22<http://cwiki.apache.org/confluence/display/GMOxDOC22>:
Developing
>> and Deploying a Geronimo GBean<http://cwiki.apache.org/confluence/display/GMOxDOC22/Developing+and+Deploying+a+Geronimo+GBean>
>>
>> Developing and Deploying a Geronimo GBean<http://cwiki.apache.org/confluence/display/GMOxDOC22/Developing+and+Deploying+a+Geronimo+GBean>has
been edited by Ying
>> Tang <http://cwiki.apache.org/confluence/display/~sophia> (Mar 23, 2009).
>>
>>
>> (View changes)<http://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=110931&originalVersion=23&revisedVersion=24>
>> Content:
>>
>> Geronimo is a system framework that can be used to build a variety of
>> tailored infrastructure services, with *GBean* providing it with a
>> loosely-coupled and configurable runtime environments. GBean is an
>> implementation of Inversion of Control (IoC), or the dependency injection,
>> which allows the automatic injection of references as they become available.
>> Geronimo Kernel and GBean Geronimo kernel
>>
>> The Geronimo kernel is a framework for kernel services, and controls the
>> basic server components with the following services:
>>
>>    - Component configuration
>>    - Component repository
>>    - Dependency management
>>    - Lifecycle management
>>
>> The basic server componenets, namely *security*, *logging*, *transactions
>> *, and *naming*, work with the kernel services to build Java EE server
>> components, such as Tomcat, Jetty, and OpenEJB. All these components,
>> cooperate with the kernel to support Java EE applications.
>> GBeans
>>
>> Almost everything in Geronimo is a GBean: containers, connectors,
>> adapters, applications and so on. A GBean is an atomic unit in Geronimo,
>> consisting of the implementation classes (.jar) and a *plan*.
>>
>> The *plan* is a configuration file through which a GBean relies on the
>> kernel for IoC and dependency injection at runtime. Dependencies on other
>> GBeans can be configured through the attributes and references in plans.
>> Geronimo's configuration builders construct GBeans out of these plans, group
>> them as *configurations*, and store them in the *configuration store*.
>>
>> A *configuration* is a logically coupled collection of one or more GBeans
>> and a classloader. The configurations are loaded with the server. The *configuration
>> store* is the standard Geronimo storage mechanism.
>>
>> Applications that run in a Java EE container, described by custom *deployment
>> descriptors* and Java classes, will be parsed and converted into GBeans
>> by the configuration builders of the Geronimo *Deployer*. These GBeans
>> are also stored in the configuration store.
>> GBean Lifecycle
>>
>> A GBean can be in any of the three states: stored, loaded, or running.
>>
>>    - Stored: The GBean exists in a plan, or configuration store.
>>    - Loaded: The GBean is mapped to a non-persistent name when loaded by
>>    the kernel, allowing multiple instances of the same GBean to exist.
>>    - Running: The GBean is in the running state, coordinating the
>>    application classes that it contains.
>>
>> To participate in the life cycle operations, GBeans implement a *
>> GBeanLifecycle* interface. This interface defines three methods,
>> doStart(), doStop() and doFail(). The doStart() method is used to start
>> the GBean, allocate resources, and implement the GBean operations. The
>> doStop() menthods stops the GBean and releases all resources. The
>> doFail() method is executed when the GBean fails to start, run or stop,
>> and is always used to report the failure and stop the GBean.
>>
>> package org.apache.geronimo.gbean;
>> public interface GBeanLifecycle{
>> void doStart() throws Exception;
>> void doStop() throws Exception;
>> void doFail();
>> }
>>
>>  If the optional interface GBeanLifecycle is implemented, the
>> implementation will get lifecycle callbacks from the kernel.
>> GBean methods
>>
>> The class for a GBean should implement specific methods to support each
>> feature of the GBean:
>>
>>    - *GBeanInfo*: A GBean has a method called getGBeanInfo() that returns
>>    an instance of the GBeanInfo class. GBeanInfo defines the methods that
>>    should be exposed to the other subsystems, exposes attributes and references
>>    so that they can be injected at runtime, and define information about the
>>    GBean so that it can be located later. The GBeanInfo object is constructed
>>    in a static initializer.
>>    - *Constructor*: The GBean constructor arguments should correspond to
>>    either attributes or references for the GBean. It is defined by the *
>>    setConstructor* method in GBeanInfo.
>>    - *Attributes*: An attribute should have a setter method, a getter
>>    method, or both. The *addAttribute* method in GBeanInfo should define
>>    the name of the attribute, its type and whether or not it's persistent, so
>>    that the attribute can be injected via the Geronimo kernel.
>>    - *Operations*: Any public method on the GBean that is not a getter or
>>    setter can be an operation. The operation methods should match the name and
>>    argument types listed by *addOperation* for the operations in the
>>    GBeanInfo.
>>    - *References*: A reference, like an attribute, is injected at
>>    runtime. However, a reference is another GBean rather than a String or an
>>    integer.
>>    - *Interfaces*: Adding a reference in GBeanInfo is a faster way of
>>    adding attributes or operations separately. All of the variables in the
>>    interface will be added as attributes and all of the methods will be added
>>    as operations.
>>
>> Developing a GBean
>>
>> For developing a GBean, you at least have to go through the following
>> steps:
>>
>>    1. Write a POJO class
>>    2. Adding the GBeanInfo part to expose attributes,methods, interfaces,
>>    and constructors
>>    3. Implement GbeanLifecycle inteface to use the Gbean Kernel lifecycle
>>    callback (*Optional*)
>>
>> A sample GBean
>>
>> The sample GBean SimpleServerGBean simply starts a socket on the Geronimo
>> server, and retrieves the name of the GBean and the socket port. The
>> following code snippet implements the Plain Old Java Object (POJO) section:
>> *SimpleServerGBean POJO*
>>
>> public class SimpleServerGBean implements GBeanLifecycle, InterfaceNamed{
>>
>>     private final String name;
>>     private int port;
>>
>>     private boolean started = false;
>>     private ServerSocket serversocket;
>>
>>     public SimpleServerGBean(String name, int port) {
>> 	this.name = name;
>> 	this.port = port;
>>     }
>>
>>     public String getName() {
>>
>>         return this.name;
>>     }
>>
>>     public boolean isStarted() {
>>
>> 	 return started;
>>     }
>>
>>     private void printConsoleLog(String log) {
>>
>> 	 System.out.println(" LOG : " + log);
>>     }
>>
>>  In the following code snippet, the GBean exposes its attributes,
>> operations, interfaces and constructor for the GBEAN_INFO static
>> initializer.
>> *SimpleServerGBean GBeanInfo*
>>
>> private static final GBeanInfo GBEAN_INFO;
>>
>>         static {
>> 	    GBeanInfoBuilder infoFactory = new GBeanInfoBuilder(
>> 	    SimpleServerGBean.class.getName(), SimpleServerGBean.class);
>>
>> 	    infoFactory.addAttribute("name", String.class, false);
>> 	    infoFactory.addAttribute("port", int.class, true);
>>
>> 	    infoFactory.addOperation("isStarted", "String");
>>
>> 	    infoFactory.addInterface(InterfaceNamed.class);
>>
>> 	    infoFactory.setConstructor(new String[] { "name", "port" });
>>
>> 	    GBEAN_INFO = infoFactory.getBeanInfo();
>>         }
>>
>>     public static GBeanInfo getGBeanInfo() {
>> 		return GBEAN_INFO;
>>     }
>>
>>  The SimpleServerGBean Gbean is simple to start up and shutdown. During
>> startup, it simply accepts an incoming socket connection requests, and sends
>> out the echo message. When being stopped, the GBean closes the resouces that
>> it consumes.
>> *SimpleServerGBean Lifecycle*
>>
>> public void doFail() {
>>
>>     started = false;
>>     printConsoleLog("GBean " + name + " failed");
>>
>>     }
>>
>>
>>
>>     public void doStart() throws Exception {
>>
>>         serversocket = new ServerSocket(port);
>> 	started = true;
>>
>>         Thread simpleServerThread = new Thread(new Runnable() {
>>
>> 	 Socket socket;
>> 	 InputStream is;
>> 	 OutputStream os;
>>
>> 	 public void run() {
>>
>> 	     while (started) {
>>   		 try {
>>   		     socket = serversocket.accept();
>>   		     is = socket.getInputStream();
>>   	             os = socket.getOutputStream();
>>
>>   		     BufferedReader bufferedReader = new BufferedReader(
>>   		     new InputStreamReader(is));
>>
>>   		     String responseMessage = "simpleServer response :"
>>   		         + bufferedReader.readLine();
>>
>>   		     os.write(responseMessage.getBytes());
>>
>>   		     bufferedReader.close();
>>   		     if (os != null) {
>>   		         os.close();
>>   		     }
>>   		     if (socket != null && !socket.isClosed()) {
>>   			 socket.close();
>>   		     }
>>
>> 		 } catch (Exception e) {
>> 		     //ingore
>> 		 }
>>              }
>>          }
>>     });
>>
>>         simpleServerThread.start();
>>
>> 	printConsoleLog("GBean " + name
>> 	    + " started and it's listening on port:" + port);
>>     }
>>
>>
>>
>>     public void doStop() throws Exception {
>>             started = false;
>> 	    serversocket.close();
>> 	    printConsoleLog("GBean " + name + " stopped");
>>     }
>>
>> }
>>
>>  For this sample, we still need a class to test the SimpleServerGBean.
>> This section creates a socket and sends a connection request to the
>> SimpleServerGBean. After the connection has been established, it sends out
>> messages and retrieves the echo message from the simpleServerGBean server
>> instance.
>>
>> package org.apache.geronimo.sample;
>> import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import
java.io.OutputStream;import java.net.InetSocketAddress;import java.net.Socket;
>> import org.junit.Ignore;import org.junit.Test;
>> public class SimpleServerTest {
>>
>>     @Test
>>     @Ignore
>>
>>         public void connectToSimpleServer() throws Exception {
>> 		
>>
>>         Socket socket = new Socket();
>>         socket.connect(new InetSocketAddress("127.0.0.1", 7777));
>> 		
>>         OutputStream os = socket.getOutputStream();
>>         String requestMessage = "Hello simple server";
>>         os.write(requestMessage.getBytes());
>>         os.write("\n".getBytes());
>>         os.flush();
>>
>>         InputStream is = socket.getInputStream();
>>         BufferedReader bufferReader = new BufferedReader(new InputStreamReader(is));
>>         String responseMessage = bufferReader.readLine();
>>         System.out.println(responseMessage);
>>
>>         socket.close();
>>     }	
>>
>> }
>>
>>  Before deploying your GBean, you still have to compile the GBean class
>> and build a proper .jar file. Maven <http://maven.apache.org/> is used to
>> build Geronimo, so it can be used to build your GBean project. You have to
>> write a pom.xml file. See Maven website <http://maven.apache.org/> for
>> more information about the file.
>> *pom.xml*
>>
>> <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>org.apache.geronimo.sample</groupId>
>>     <artifactId>simpleServer</artifactId>
>>     <packaging>jar</packaging>
>>     <version>1.0</version>
>>     <name>sample GBean as a simple server</name>
>>
>>
>>     <dependencies>
>>         <dependency>
>> 	    <groupId>org.apache.geronimo.framework</groupId>
>> 	    <artifactId>geronimo-kernel</artifactId>
>> 	    <version>2.1.3</version>
>> 	</dependency>
>>
>> 	<dependency>
>> 	    <groupId>junit</groupId>
>> 	    <artifactId>junit</artifactId>
>> 	    <version>4.1</version>
>> 	    <scope>test</scope>
>> 	</dependency>
>>     </dependencies>
>>
>>     <build>
>>         <plugins>
>>
>>             <plugin>
>> 	        <artifactId>maven-compiler-plugin</artifactId>
>> 		<configuration>
>> 		    <source>1.5</source>
>> 		    <target>1.5</target>
>> 		</configuration>
>> 	    </plugin>
>>
>>         </plugins>
>>     </build>
>> </project>
>>
>>  In the POM file above,
>>
>>    - The only dependency you need to develop a GBean is
>>
>>    <dependency>
>>            <groupId>org.apache.geronimo.framework</groupId>
>>            <artifactId>geronimo-kernel</artifactId>
>>    	<version>2.1.3</version>
>>        </dependency>
>>
>>     - We add following section to the POM only for the sake of the
>>    testing code.
>>
>>    <dependency>
>>            <groupId>junit</groupId>
>>    	<artifactId>junit</artifactId>
>>            <version>4.1</version>
>>            <scope>test</scope>
>>    	</dependency>
>>        </dependencies>
>>
>>        <build>
>>            <plugins>
>>                <plugin>
>>    	        <artifactId>maven-compiler-plugin</artifactId>
>>    		<configuration>
>>    		    <source>1.5</source>
>>    		    <target>1.5</target>
>>    		</configuration>
>>    	    </plugin>
>>            </plugins>
>>        </build>
>>
>>
>> Deploying a GBean
>>
>> Follow these steps to deploy your GBean to Geronimo.
>>
>>    1. Deploy the GBean package. There are two methods to deploy a GBean
>>    package to Geronimo.
>>       - Deploy the .jar to the server via the *JAR repository* portlet in
>>       Geronimo administrative console. For example, you can deploy the
>>       SimpleServerGBean with the following information:
>>          - *GroupId*: org.apache.geronimo.sample
>>          - *ArtifactId*: simpleServer
>>          - *Version*: 1.0
>>          - *Type*: jar
>>        - Mannually copy the jar file to the GERONIMO_HOME/repository with
>>       a path and package name rule.
>>          - Path : GroupId/ArtifactId/Version/ArtifactId-Version.Type
>>          - Sample:
>>          <GERONIMO_HOME>/repository/org/apache/geronimo/sample/simpleServer/1.0/simpleServer-1.0.jar
>>          *Note*: If the GBean depends on an external library, you have to
>>          deploy both .jars into the repository, and list both of them in the
>>          <dependencies> section of the deployment plan described below.
>>         2. The next step is to develop a GBean deployment plan. A
>>    deployment plan is to define a Geronimo *module* as an .xml file that
>>    includes the descriptions of one or more instances of exsiting GBeans.
>>    *simpleServer_deployment_plan.xml*
>>
>>    <?xml version="1.0" encoding="UTF-8"?><module xmlns="http://geronimo.apache.org/xml/ns/deployment-1.2">
>>        <environment>
>>            <moduleId>
>>    	    <groupId>org.apache.geronimo.sample</groupId>
>>    	        <artifactId>simpleServerModule</artifactId>
>>    		<version>1.0</version>
>>    		<type>car</type>
>>    	</moduleId>
>>
>>    	<dependencies>
>>    	    <dependency>
>>    	        <groupId>org.apache.geronimo.sample</groupId>
>>    		<artifactId>simpleServer</artifactId>
>>    		<version>1.0</version>
>>    	    </dependency>
>>    	</dependencies>
>>
>>    	<hidden-classes />
>>
>>    	<non-overridable-classes />
>>
>>        </environment>
>>
>>        <gbean name="echoserver" class="org.apache.geronimo.sample.SimpleServerGBean">
>>            <attribute name="port">7777</attribute>
>>    	 <attribute name="name">simpleServer</attribute>
>>        </gbean></module>
>>
>>     Let's briefly go through this plan.
>>     - The *<moduleId>* element is used to provide the configuration name
>>       for the module as deployed in the Geronimo server. It contains elements for
>>       the *groupId*, *artifactId*, *version* and *type*. Module IDs are
>>       normally printed with slashes between the four components, such as
>>       GroupID/ArtifactID/Version/Type. In this example, The module ID
>>       will be org.apache.geronimo.sample/simpleServer/1.0/car.
>>       - The *<dependencies>* element is used to provide the
>>       configurations on which the module is dependent upon. In this example, the
>>       module is dependent on org.apache.geronimo.sample/simpleServer/1.0.
>>     3. Deploy the deployment plan to the server. There are two methods to
>>    deploy a GBean Module with a plan to Geronimo.
>>       - Using the *Deploy New* portlet in the administrative console.
>>       - Using the deployer<http://cwiki.apache.org/confluence/display/GMOxDOC22/deploy#deploy-Deploy>tools
or
>>       GShell<http://cwiki.apache.org/confluence/display/GMOxDOC22/Deploying+an+Application+to+a+Server+Instance+in+GShell>command.
>>     4. If success, you can visit http://localhost:7777 and will get an
>>    echo from the server.
>>
>> *Note*: If a GBean implementation (possibly a .jar) already exisits in
>> the Geronimo server, you only need to develop a deployment plan and deploy
>> it to the server for the GBean instance to work.
>> Referencing other GBeans
>>
>> Other GBeans can be used in a GBean by injecting *Reference* methods. For
>> instance, the GBean *SimpleServerGBean* now makes use of another GBean
>> named *EchoMessageGBean* with its POJO class and GBeanInfo implemented
>> like the following:
>> *EchoMessageGBean*
>>
>> package org.apache.geronimo.sample;
>> import org.apache.geronimo.gbean.GBeanInfo;import org.apache.geronimo.gbean.GBeanInfoBuilder;
>> public class EchoMessageGBean implements EchoMessageInterface {
>>     private final String msg;
>>
>>     public EchoMessageGBean(String name) {
>>         this.msg = name;
>>     }
>>
>>     private static final GBeanInfo GBEAN_INFO;
>>
>>     static {
>>         GBeanInfoBuilder infoFactory = new GBeanInfoBuilder(
>> 				EchoMessageGBean.class);
>>
>>         infoFactory.addAttribute("msg", String.class, false);
>>
>>         infoFactory.addInterface(EchoMessageInterface.class);
>>
>> 	infoFactory.setConstructor(new String[] { "msg" });
>>
>> 	GBEAN_INFO = infoFactory.getBeanInfo();
>>     }
>>
>>     public static GBeanInfo getGBeanInfo() {
>>         return GBEAN_INFO;
>>     }
>>
>>     public String getEchoMessage() {
>> 	return msg;
>>     }
>> }
>>
>>  This EchoMessageGBean does not implement GbeanLifecycle for simplicity.
>> It only exposes an interface *EchoMessageInterface* which retrieves
>> predefined echo messages.
>>
>> To reference the *EchoMessageGBean* in SimpleServerGBean, the following
>> steps have to be taken:
>>
>>    1. SimpleServerGBean now has more private members and a different
>>    constructor: *Excerpt from SimpleServerGBean POJO*
>>
>>    private final String name;private int port;
>>
>>    /* A new private member */private EchoMessageInterface echo;
>>    private boolean started = false;private ServerSocket serversocket;
>>
>>    /* Constructor changed */public SimpleServerGBean(String name, int port, EchoMessageInterface
echomsg) {
>>        this.name = name;
>>        this.port = port;
>>        this.echo= echomsg;
>>    }
>>
>>     2. In doStart() of the SimpleServerGBean implementation, we now
>>    retrieves messages from EchoMessageGBean and reorganizes the reponse
>>    message: *Excerpt from SimpleServerGBean doStart()*
>>
>>    String appendMessage = echo.getEchoMessage();String responseMessage = appendMessage
+ bufferedReader.readLine();
>>
>>     3. Add a *Reference* method to GBeanInfo: *SimpleServerGBean
>>    GBeanInfo*
>>
>>    private static final GBeanInfo GBEAN_INFO;
>>
>>        static {
>>            GBeanInfoBuilder infoFactory = new GBeanInfoBuilder(
>>    		SimpleServerGBean.class.getName(), SimpleServerGBean.class);
>>
>>            infoFactory.addAttribute("name", String.class, false);
>>    	infoFactory.addAttribute("port", int.class, true);
>>    	infoFactory.addOperation("isStarted", "String");
>>    	infoFactory.addInterface(InterfaceNamed.class);
>>
>>            /* Add a reference */
>>    	infoFactory.addReference("echoMessenger",EchoMessageInterface.class);
>>
>>            /* A different constructor */
>>    	infoFactory.setConstructor(new String[] { "name", "port", "echoMessenger"});
>>
>>    	GBEAN_INFO = infoFactory.getBeanInfo();
>>        }
>>
>>     4. Correspondingly, the dployment plan for SimpleServerGBean has to
>>    be modified. *Excerpt from simpleServer_deployment_plan.xml*
>>
>>    <gbean name="echoserver" class="org.apache.geronimo.sample.SimpleServerGBean">
>>        <attribute name="port">7777</attribute>
>>        <attribute name="name">simpleServer</attribute>
>>        <reference name="echoMessenger">
>>            <name>msgAppender</name>
>>        </reference></gbean>
>>    	<gbean name="msgAppender" class="org.apache.geronimo.sample.EchoMessageGBean">
>>        <attribute name="msg">[Echo from server]:</attribute></gbean>
>>
>>     After we add the .jar file to the server, and deploy the plan, the
>>    test class which initiates a socket on port 7777 will get a reponse message
>>    from the server.
>>
>>    [Echo from server]: Hello simple server
>>
>>
>> The GBean SimpleServerGBean can reference different instances of
>> EchoMessageGBean. For instance, the SimpleServerGBean listens on port 7778
>> instead, and gets messages from the instance *msgAppender2*.
>> *Excerpt from simpleServer_deployment_plan2.xml*
>>
>> <gbean name="echoserver" class="org.apache.geronimo.sample.SimpleServerGBean">
>>     <attribute name="port">7778</attribute>
>>     <attribute name="name">simpleServer</attribute>
>>     <reference name="echoMessenger">
>>
>>         <!-- Reference another instance of EchoMessageGBean -->
>>         <name>msgAppender2</name>
>>     </reference></gbean>
>> <gbean name="msgAppender" class="org.apache.geronimo.sample.EchoMessageGBean">
>>     <attribute name="msg">[Echo from server]:</attribute>
>> <!--Another instance of EchoMessageGBean --><gbean name="msgAppender2" class="org.apache.geronimo.sample.EchoMessageGBean">
>>     <attribute name="msg">[Echo from server 2]:</attribute></gbean>
>>
>>  When we deploy this plan (The .jar file does not have to be changed),
>> the test class which starts a socket on port 7778 will gets the reponse from
>> server 2.
>>
>> [Echo from server 2]: Hello simple server
>>
>> Geronimo Bootstrap
>>
>> When Geronimo starts, the <GERONIMO_HOME>/bin/server.jar is executed with
>> org.apache.geronimo.cli.daemon.DaemonCLI as the main class. This will
>> boot the Geronimo kernel, and load initial GBeans from module
>> j2ee-system-2.1.3.car into the kenel.
>>
>>    Powered by Atlassian Confluence<http://www.atlassian.com/software/confluence/default.jsp?clicked=footer>(Version:
2.2.9 Build:#527 Sep 07, 2006) - Bug/feature
>> request <http://jira.atlassian.com/secure/BrowseProject.jspa?id=10470>
>>
>> Unsubscribe or edit your notifications preferences<http://cwiki.apache.org/confluence/users/viewnotifications.action>
>>
>>
>
>
> --
> Shawn
>



-- 
Shawn

Mime
View raw message