tomee-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Blevins <david.blev...@visi.com>
Subject Re: How to embed a server into openejb standard alone server
Date Thu, 12 Jun 2008 06:36:39 GMT

On Jun 11, 2008, at 12:17 AM, xianzheng wrote:

>
> Hi David,
> Thanks for your reply.
> I think i might need the second option. Cause what my legacy server  
> does is
> a kind of RPC invokation. So I need to embed it into openejb so that  
> it
> could accept requests and map requests to specific session ejbs.
> If I understand correctly, i need to code up a container wrapper for  
> it. Do
> you happen to know where I could find some references in order to do  
> such
> things?

If you've got a network protocol you'll definitely need to implement a  
ServerService [1].  We can get you going on that and worry about the  
rest as you come to it.

You basically implement that interface and then include a properties  
file in your jar in the path:
   META-INF/org.apache.openejb.server.ServerService/myprotocol

Where "myprotocol" is a properties file that looks like so:

   server      = org.superbiz.foo.MyServerServiceImplementation
   bind        = 127.0.0.1
   port        = 4204
   disabled    = false
   threads     = 200

You need only drop that jar into the <openejb.home>/lib directory and  
it will start up on boot.  We'll even take the contents of  
"myprotocol" and create a <openejb.home>/conf/myprotocol.properties  
file automatically so that it can easily be configured.  You'll even  
be able to do properties overrides on the command line and via system  
properties, such as:

  ./bin/openejb start -Dmyprotocol.port=4567 - 
Dmyprotocol.only_from=127.0.0.1

The above would bind your protocol to prot 4567 and only allow people  
on the localhost to connect to it.  (the "only_from" supports a ton of  
options, getting good docs for it is definitely on the todo list)

A simple MyServerServiceImplementation might look like this:

public class MyServerServiceImplementation implements  
org.apache.openejb.server.ServerService {

     public void service(Socket socket) throws IOException {
         InputStream in = socket.getInputStream();
         OutputStream out = socket.getOutputStream();

         try {
             service(in, out);
         } finally {
             try {
                 if (socket != null) socket.close();
             } catch (Throwable t) {
                 // log something
             }
         }
     }

     public void service(InputStream in, OutputStream out) throws  
IOException {
         // DO YOUR STUFF HERE
         // alternatively you can use the service(Socket socket)  
method instead
     }

     //
     // The following aren't required in most situations
     //

     public void init(Properties props) throws Exception {
     }

     public void start() throws ServiceException {
     }

     public void stop() throws ServiceException {
     }

     public String getName() {
         return "myprotocol";
     }

     public int getPort() {
         return 0;
     }

     public String getIP() {
         return "";
     }
}


For some good code to browse, just about every module under this path  
is a ServerService of one kind or another.  Some invoke beans like the  
openejb-ejbd, some are adapters for third party protocols like openejb- 
hsql, openejb-derbynet and openejb-activemq, some are non-ejb  
protocols like openejb-http and openejb-telnet.

   http://svn.apache.org/repos/asf/openejb/tags/openejb-3.0/server/

On the object invoking front there are a couple internal concepts to  
understand.  Every ejb in the system has an DeploymentInfo object  
associated with it.  These can be located by DeploymentId, which by  
default will be the same as the ejb-name of the ejb.  A Container will  
hold several DeploymentInfo objects.  A Container looks a lot like  
plain reflection, it has an invoke() method that looks as follows:

     public Object invoke(Object deployID, Class callInterface, Method  
callMethod, Object [] args, Object primKey) throws OpenEJBException;

INVOKING, OPTION #1

The "to the metal" way to invoke is to get references to a container  
and invoke it as as follows:

import org.apache.openejb.DeploymentInfo;
import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.spi.ContainerSystem;
....
   String deploymentId = ..// get this from your protocol somewhere
   Object instanceId = ..// null for stateless beans, will be a  
container created value for stateful
   Object[] args = ..// get this from your protocol somewhere
   Method method = ..// the method you want to invoke

   ContainerSystem containerSystem =  
SystemInstance.get().getComponent(ContainerSystem.class);
   DeploymentInfo deploymentInfo =  
containerSystem.getDeploymentInfo(deploymentId);
   RpcContainer container = (RpcContainer)  
deploymentInfo.getContainer();

   Object result = container.invoke(deploymentId,  
method.getDeclaringClass(), method, args, instanceId);

   // serialize the result back to your client.
   // done

For several examples of the above code, check out the  
EjbRequestHandler [2] class.

INVOKING, OPTION #2

The above can be tricky when you start dealing with creating,  
removing, stateful bean identity, app and system exception handling  
and more so it can sometimes be far easier to just ignore all that and  
just deal with the proxy instance that you can get from the  
LocalInitialContextFactory.  Essentially the same thing but 100% plain  
reflection.

   String jndiName = ..// get this from your protocol somewhere
   Object[] args = ..// get this from your protocol somewhere
   Method method = ..// the method you want to invoke

   ContainerSystem containerSystem =  
SystemInstance.get().getComponent(ContainerSystem.class);
   Context ejbJndiContext = (Context)  
containerSystem.getJNDIContext().lookup("openejb/ejb"); // all ejbs  
live here

   Object beanReference = ejbJndiContext.lookup(jndiName);

   Object result = method.invoke(beanReference, args);

   // serialize the result back to your client.
   // done


-David

[1] http://svn.apache.org/repos/asf/openejb/tags/openejb-3.0/server/openejb-server/src/main/java/org/apache/openejb/server/ServerService.java
[2] http://svn.apache.org/repos/asf/openejb/tags/openejb-3.0/server/openejb-ejbd/src/main/java/org/apache/openejb/server/ejbd/EjbRequestHandler.java

> David Blevins wrote:
>>
>>
>> On Jun 10, 2008, at 8:50 PM, xianzheng wrote:
>>
>>>
>>> Hi all,
>>> I'm new to J2EE and OpenEJB.
>>> Just wondering, is there a way to embed an application server  
>>> which is
>>> written in JAVA in openejb? I guess, I'll have to write a container
>>> to wrap
>>> it around? If so, is there a guide to write such thing? As my
>>> understanding,
>>> JCA can only allows ejbs to connect to other servers rather than
>>> listening
>>> connections?
>>>
>>> I have a very old server application i wrote, which complies a non-
>>> standard
>>> communication protocol. So i'm thinking whether i could embed it  
>>> into
>>> openejb to listening to "old" request and benefit openejb's other  
>>> cool
>>> features.
>>
>> Hi Joe,
>>
>> Depending on what you want to do exactly there are likely many ways  
>> to
>> do it.
>>
>> It is possible to plug in new protocols into a standard OpenEJB
>> install and support custom clients.  It's very easy to drop something
>> in that listens on a socket and does "stuff".  OpenEJB will find it  
>> on
>> startup and hook it up as it does the other protocols.  The "stuff"  
>> is
>> where all the detail lies.  Reflectively invoking proxies on the
>> server side by looking them up from the local global JNDI
>> (LocalInitialContextFactory) is easy, whereas sending invocations
>> directly into the EJB Containers like the EJBd protocol does is
>> harder.  Can show you how to do that if it sounds like a route you
>> might want to take.  (you basically implement a specific interface
>> then include a special properties file in your jar and drop it into
>> openejb, pretty easy)
>>
>> If you have your own "component container" it is possible to add new
>> custom containers to a standard OpenEJB install.  This is a bit more
>> involved but not completely impossible.  The advantage here is that
>> any container can be invoked by any of the protocols plugged into
>> OpenEJB.
>>
>> Sounds like you want more the first option where you can add a new
>> protocol.  There are definitely options.  Couple rounds of "mutual
>> data exchange" (aka discussion) and I'm sure we can find a good game
>> plan :)
>>
>> -David
>>
>>
>>
>>
>>
>
> -- 
> View this message in context: http://www.nabble.com/How-to-embed-a-server-into-openejb-standard-alone-server-tp17769556p17771513.html
> Sent from the OpenEJB User mailing list archive at Nabble.com.
>
>


Mime
View raw message