You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomee.apache.org by exabrial <ex...@gmail.com> on 2012/07/02 02:11:14 UTC

Re: Using @EJB/@Inject to lookup on remote interface running on separate standalone OpenEJB server

Hey sorry to wake a dead 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>

I'm willing to write this with a little bit of direction... What interface
or base class would  "org.apache.openejb.xxx.OpenEJBExternalJndiLink" to
implement/extend to get it to show up in the local JNDI tree? Is there an
example I could look at?

--
View this message in context: http://openejb.979440.n4.nabble.com/Using-EJB-Inject-to-lookup-on-remote-interface-running-on-separate-standalone-OpenEJB-server-tp4655814p4655941.html
Sent from the OpenEJB User mailing list archive at Nabble.com.

Re: Using @EJB/@Inject to lookup on remote interface running on separate standalone OpenEJB server

Posted by David Blevins <da...@gmail.com>.
On Jul 2, 2012, at 4:57 PM, Romain Manni-Bucau wrote:

> cant it be done with mapped name?

Yes, it can.  A repost of that in case it was missed.  This works in the released code:

You can set the MappedName for the @EJB ref via the web.xml of JSF app rather than in code.

   @EJB(name="orange")
   private Orange orange;

Then in the web.xml you can override that exact reference like so:

   <ejb-ref>
       <ejb-ref-name>orange</ejb-ref-name>
       <mapped-name>jndi:ext://shoe/OrangeBeanRemote</mapped-name>
   </ejb-ref>


-David


Re: Using @EJB/@Inject to lookup on remote interface running on separate standalone OpenEJB server

Posted by Romain Manni-Bucau <rm...@gmail.com>.
cant it be done with mapped name?

- Romain


2012/7/3 David Blevins <da...@gmail.com>

>
> 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
>
>

Re: Using @EJB/@Inject to lookup on remote interface running on separate standalone OpenEJB server

Posted by exabrial <ex...@gmail.com>.
Thinking about doing this, as I would get a lot of use from it....


David Blevins-2 wrote
> 
> 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>
> 

So that would involve implementing a container... and hooking that into the
config portion of openejb... I have a good idea of where that stuff is in
ConfigurationFactory.


David Blevins-2 wrote
> 
> add them into the mix when we run our "find the matching EJB for this @EJB
> ref" logic
> 
I can't find this stuff though. 


David Blevins-2 wrote
> 
> 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. 
> 
You lost me here. Were you thinking this goes into the frontend app? Or the
server's classlib?

Thanks!


--
View this message in context: http://openejb.979440.n4.nabble.com/Using-EJB-Inject-to-lookup-on-remote-interface-running-on-separate-standalone-OpenEJB-server-tp4655814p4655982.html
Sent from the OpenEJB User mailing list archive at Nabble.com.

Re: Using @EJB/@Inject to lookup on remote interface running on separate standalone OpenEJB server

Posted by David Blevins <da...@gmail.com>.
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