|
Hello CORBA -- An example of PocoCapsule/CORBA Copyright© 2006 by Pocomatic Software. All Rights Reserved. Sept. 26, 2006
A typical CORBA application development cycle consists of the following three phases:
This article demonstrates a full development cycle of a CORBA client-server application. This example is shipped with PocoCapsule/CORBA in examples/hello directory. Design/Define Object Interface In PocoCapsule/CORBA, objects (beans) are plain old CORBA objects. Therefore, developers do not need to learn and use CIDL, PIDL and those additional CORBA 3.0 IDL keywords introduced for CCM. Rather, they only need to know and use the plain old CORBA 1.0 or 2.0 IDL. This is a trivial part of CORBA technology and can easily be grasped by average business logic developers with C++ or Java background. In this example, we define the interface Greeting of our plain old CORBA object as follows: |
|
module sample {
interface Greeting {
string hello(in string s);
};
};
|
|
|
Our IDL interface definition is placed inside an IDL module. An IDL module is merely the name of a package or namespace. Therefore, the full name of our Greeting object interface class, referred to either in IDL or in Java, is sample.Greeting. Implementing Business Logic The second development phase is to implement the business logic of our Greeting object in a plain old CORBA object servant, namely the GreetingImpl POA servant class, as follows: |
|
public class GreetingImpl extends sample.GreetingPOA {
public String hello(String s) {
System.out.println("server received a " + s);
}
};
|
|
|
This is also an easy part of the CORBA to average business logic developers. The GreetingImpl servant class is extended from the server skeleton class, the sample.GreetingPOA. This skeleton class is generated from the Greeting.idl using ORB development tools. For example, using the idlj utility of Sun JDK (1.3 and up), the command to generate the client stub and the server skeleton of an IDL interface defined in the Greeting.idl is: |
|
% idlj -fall Greeting.idl |
|
|
As the generated stub and skeleton classes are binary compatible in all OMG compliant ORBs, therefore, they can be used without recompiling even if the application or the container switches to an ORB implemented by a different vendor. Deploying with XML descriptor The third phase is deployment. Unlike the previous two phases, deploying a CORBA server application in the plain old programmatic approach could be a challenge even for experienced system logic developers. PocoCapsule/CORBA allows developers to deploy a CORBA server descriptively and objectively. Namely, developers deploy a server by conceptually expressing what is the desired server structure, instead of coding or describing details of how to wire it up. This makes deployment significantly easy and less error-prone even for beginners. Namely, in PocoCapsule/CORBA, the easiest approach is also the right approach. For instance, to deploy the Greeting server in PocoCapsule/CORBA, the server structure can conceptually be described in the following XML descriptor: |
|
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE bean SYSTEM "http//www.pocomatic.com/dtd/poco-spring.dtd">
<beans>
<orb id="my-poco-orb">
<object uri="my-server">
<servants><bean class="GreetingImpl"/></servants>
</object>
</orb>
</beans>
|
|
|
This XML descriptor is very conceptual and intuitive. It describes:
The Container Server Now we are going to deploy our Greeting object to a container. In PocoCapsule and most IoC containers, the terminology of “container” merely refers to a bean factory object, which can be embedded in any Java application. In our case, we just embed this factory in a tiny Java main() function to construct a mini container server as follows: |
|
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import com.pocomatic.core.Capsule;
public class Server {
public static void main(String[[ args) {
try {
// Feed the PocoCapsule/CORBA schema into the runtime
Capsule.init("com/pocomatic/CORBA/schema/spring.prop");
Resource res = new FileSystemResource("server.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
factory.preInstantiateSingletons();
System.out.println("Server is ready, with URL:");
// print out all published URLs, and block the thread
factory.getBean("com.pocomatic.runner:my-poco-orb");
}
catch(Exception e) {
...
}
}
};
|
|
|
This mini container server is used by almost all PocoCapsule examples and can be used for real production applications as well. This mini container first initializes PocoCapsule, and then deploys a server, declared in server.xml, using Spring's XmlBeanFactory. At the end of the deployment process, the server instantiates a bean of id “com.pocomatic.runner:user-declared-orb-id” (in this example, the user declared orb id is “my-poco-orb”) by retrieving it from the factory (i.e. calling getBean() on the factory). The deployment description for this bean is automatically generated by the PocoCapsule/CORBA transform if the <orb> is declared without omitting the id attribute (as in our server.xml file). The constructor of this “runner” bean will print out all published URLs, and then, block the calling thread and run the request dispatching loop until ORB shutdown. As will be described in more detail, URLs are automatically published by PocoCapsule/CORBA if an <object> is declared with uri attribute. The value of this attribute will be used as the URI of the published URL. Playing the example To play this example, we first start the server. As said above, it will automatically print out the URL of the server object, with URI (“my-server”) specified in deployment descriptor: |
|
% java Server
Server is ready, with URL:
corbaloc::192.168.2.3:2809/my-server
|
|
|
The client invokes the hello() method of this server object by calling the method on its stub. This stub is a sample.Greeting java object, and can be obtained from the ORB based on the known server object URL as in the following code: |
|
orb = com.pocomatic.CORBA.ORB.init(null, null);
String url = "corbaloc::192.168.2.3:2809/my-server";
// destringify the url to an object stub
sample.Greeting stub = (sample.Greeting)
orb.string_to_reference(url, sample.Greeting.class);
// invoke the method on the stub
String rep = stub.hello("hello from client");
// print out what returned from the server
System.out.println("client receives " + rep);
|
|
|
Changing Server Structure/Configuration So far, this example has demonstrated the development cycle of a simple CORBA application. Before the end, let us look how to deploy a Greeting object with some variant and sophisticated settings. This would give us an idea of how easily one can reconfigure a CORBA server, as well as how to create a little non-trivial CORBA server in PocoCapsule/CORBA. Assume we want the server object to:
This structure can easily be described in the following deployment descriptor: |
|
<?xml version="1.0" encode="iso-8859-1"?>
<!DOCTYPE beans SYSTEM "http://www.pocomatic.com/dtd/poco-spring.dtd">
<beans>
<orb id="my-poco-orb">
<poa>
<policies>
<policy name="thread" value="single"/>
<policy name="lifespan" value="persistent"/>
</policies>
<object uri="my-server">
<servants><bean class="GreetingImpl"/></servants>
</object>
</poa>
</orb>
</beans>
|
|
|
Our Greeting object was previously declared to be activated on the (hidden) default object adapter (therefore, use default policies). Our new Greeting object declared above is to be activated on an object adapter (POA) created with the user specified thread and lifespan policies. This new server structure can be instantiated by simply restarting our server with the new deployment descriptor, without having to rebuild the server binary executable. More detailed descriptions of PocoCapsule/CORBA can be found in the PocoCapsule Developer Guide. The evaluation version of PocoCapsule/CORBA can be downloaded from Pocomatic Software. |
|