tomee-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Blevins <david.blev...@gmail.com>
Subject Re: Using @EJB/@Inject to lookup on remote interface running on separate standalone OpenEJB server
Date Mon, 02 Jul 2012 23:54:55 GMT

On Jul 1, 2012, at 5:11 PM, exabrial wrote:

> Hey sorry to wake a dead thread...

Preferred actually.  Saves the time of having to dig for the old thread.

> but I just thought of something: Does
> OpenEJB has a jndi-link feature?
> 
> I don't think it does, but I know GlassFish and Resin can do it....
> http://www.caucho.com/resin-3.0/config/env.xtp#jndi-link
> 
> Would writing a custom ObjectFactory be the correct way to do this?
> 
> In my frontend JSF application, in a servlet, say I had:
> 
> @EJB
> MyService myService;
> 
> If I wanted to link that EJB to an external context, I would put something
> in TomEE.xml like this:
> 
> 	<JndiProvider id="shoe" type="javax.naming.InitialContext">
> 		java.naming.provider.url = ejbd://localhost:3201
> 		java.naming.factory.initial =
> org.apache.openejb.client.RemoteInitialContextFactory
> 	</JndiProvider>
> 
> 	<Resource id="MyService"
> type="org.apache.openejb.xxx.OpenEJBExternalJndiLink">
> 		externalContext = "shoe"
> 		externalName="MyDeploymentId/MyService.Remote"
> 	</JndiProvider>

Ignoring the <Resource> part for a moment, the best fit would likely be something that
allows you to describe the external EJB.

The trick is when you use `@EJB` like shown above, the matching EJB is resolved by type. 
The pseudo <Resource> declaration doesn't have the type `MyService` in it anywhere and
therefore wouldn't work.  You'd be stuck matching by string (id) and then what I mention before
about needing to change all your `@EJB` references to use `name` as in `@EJB(name="MyService")`
would still apply.

So something that allows you to say, "I have an EJB of type X that you can lookup via Y jndi
name using Z <JndiProvider>" would be the most terse and common-case solution.

Being able to optionally specify the "ejb-name" so you could also match with `@EJB(beanName="fooService")`
would be nice.  The `beanName` attribute is used as a tie-breaker when there is more than
one bean that could satisfy an `@EJB` ref by type (e.g. say you have two beans that implement
the same @Remote interface, `@EJB` will no longer work unless you specify `beanName`.

Theoretically that could look something like:

  <ExternalEjb>
    <interface>org.superbiz.MyService</interface>
    <interface>org.superbiz.Foo</interface>
    <bean-name>fooService</bean-name>
    <jndi-name>FooService.Remote</jndi-name>
    <jndi-provider>shoe</jndi-provider>
  </ExternalEjb>

Not crazy about the ExternalEjb element name, but that's the basic idea.  To recap:

  - @EJB is resolved by either `type` or `beanName`
  - if we can provide a way to tie either a type or a bean-name to an external ejb, we're
good.

So what we'd do is take these ExternalEjb refs and add them into the mix when we run our "find
the matching EJB for this @EJB ref" logic.

Since we allow you to declare the actual server info in <JndiProvider>, you could potentially
do all this in code if we were to create an equivalent annotation.  Maybe something like:

    public @interface ExternalEjb {
        Class[] interfaces() default {};
        String beanName() default "";
        String jndiName() default "";
        String jndiProvider() default "";
    }

We could maybe allow you to specify that on a class or something.  Or perhaps even more clever:

    @ExternalEjb(jndiName = "FooService.Remote", jndiProvider = "shoe")
    public abstract class FooService implements MyService, Foo {}

At this point you have far less XML to maintain and having 1 to 100+ of these external ejbs
would be pretty easy as you'd only need to keep a single `<JndiProvider id="shoe">`
entry up-to-date.

Thoughts?


-David


Mime
View raw message