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.



Reply via email to