JNDI lookup and EJB invocation from a remote client

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

JNDI lookup and EJB invocation from a remote client

Jaikiran Pai
Now that we have some kind of stability on the EJB remote client API and
its implementation (ofcourse on our individual git branches), I was
looking around to see how easy/seamless the JNDI interaction from a
remote client is going to be from a user point of view. So I've got this
testcase (which runs as a remote client) which does lookup of a SLSB via
the ejb: jndi naming scheme that we have introduced:

@RunWith(Arquillian.class)
@RunAsClient
public class RemoteEJBJNDIAccessTestCase {

...
     private Context initialContext;

     @Before
     public void beforeTest() throws Exception {
         final Properties initCtxProps = new Properties();
         initCtxProps.put(Context.URL_PKG_PREFIXES,
"org.jboss.ejb.client.naming");
         this.initialContext = new InitialContext(initCtxProps);
     }

... // trimmed some code which creates and deploys the deployment via
Arquillian @Deployment

...

     @Test
     public void testSLSBInvocation() throws Exception {
         final String distinctName = "";
         final EchoRemote echoRemote = (EchoRemote)
this.initialContext.lookup("ejb:" + APP_NAME + "/" + MODULE_NAME + "/" +
distinctName + "/" + EchoBean.class.getSimpleName() + "!" +
EchoRemote.class.getName());
         Assert.assertNotNull("Received a null proxy", echoRemote);
         final String message = "Hello world from a really remote client
via a proxy from JNDI";
         final String echo = echoRemote.echo(message);
         Assert.assertEquals("Unexpected echo message", message, echo);
     }
}

So the test first looks a up proxy using ejb:<...blah> and then invokes
on that bean proxy. The invocation on the proxy fails with:

java.lang.IllegalStateException: No EJB client context is set for this
thread
     at
org.jboss.ejb.client.EJBClientContext.requireCurrent(EJBClientContext.java:150)
     at
org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:77)
     at $Proxy18.echo(Unknown Source)
     at
org.jboss.as.testsuite.integration.ejb.remote.client.api.RemoteEJBJNDIAccessTestCase.testSLSBInvocation(RemoteEJBJNDIAccessTestCase.java:79)

That's expected because we haven't configured any EJBClientContext for
this invoking thread.

So the questions I had was:

1) Do we want the JNDI invocations to be really seamless (i.e. the above
code to functional)? I'm very much in favour of letting the users invoke
via JNDI without any explicit use of EJB client API in their code. I
don't see a point of using JNDI as well as EJB client API to get it to work.

2) My idea of making this work was to use the Context.PROVIDER_URL as
our remote receiver uri. So the jndi.properties or even the properties
passed to the InitialContext could contain (comma separated list)
something like remote://localhost:9999 (just an example) to point to the
remote EJB connector. The EJBNamingContext would then be smart enough to
first setup a (remoting) EJB receiver during context creation and then
setup a EJB client context on the invoking thread, when the proxy is
invoked (this would require the lookup to return a wrapper over the
invocation handler to intercept the calls on the proxy and just do a
EJBClientContext.setCurrent(...) before passing on the control to the
EJBInvocationHandler).

#2 is all impl details and actually has numerous issues with it:

     a) It assumes that it would be OK to setup the remoting connection
ourselves and not mandate the user to provide one (we could actually
allow users to pass configurations for the connection). David has
mentioned that it wouldn't be a good idea creating the connection
ourselves. But that was in the context of pure native EJB client API
design. Does it make sense to somehow relax that require in this JNDI case?

     b) The Context.PROVIDER_URL used in the jndi.properties or the
properties being passed to the InitialContext apply to the entire
context and aren't anything specific to EJB invocations. i.e. the user
could use that context to do lookup/invocations on non-EJB objects bound
to JNDI. I'm not sure how non-EJB JNDI lookup outside of the server VM
is being implemented/planned, so using that EJB specific(?) remoting
connector info (remote://<localhost:ejb-remote-connector-port>) in the
jndi.properties isn't probably a good idea.


So how do we go about this?

-Jaikiran

_______________________________________________
jboss-as7-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/jboss-as7-dev
Reply | Threaded
Open this post in threaded view
|

Re: JNDI lookup and EJB invocation from a remote client

David Lloyd-2
On 10/06/2011 08:33 AM, Jaikiran Pai wrote:
> Now that we have some kind of stability on the EJB remote client API and
> its implementation (ofcourse on our individual git branches), I was
> looking around to see how easy/seamless the JNDI interaction from a
> remote client is going to be from a user point of view. So I've got this
> testcase (which runs as a remote client) which does lookup of a SLSB via
> the ejb: jndi naming scheme that we have introduced:
 > [..example showing no-client exception..]
> That's expected because we haven't configured any EJBClientContext for
> this invoking thread.
>
> So the questions I had was:
>
> 1) Do we want the JNDI invocations to be really seamless (i.e. the above
> code to functional)? I'm very much in favour of letting the users invoke
> via JNDI without any explicit use of EJB client API in their code. I
> don't see a point of using JNDI as well as EJB client API to get it to work.

I'm not really feeling like JNDI is a significant factor here.  The JNDI
API is only there for the purpose of making remote injection nicer in
the server, and to provide a consistent experience for those who want to
stick with JNDI on the client.

I think we should shoot for these goals:

A) A standalone client should be able to look up a proxy from JNDI
without configuring a client context (this already works).

B) The standalone client should not have to remember to establish a
client context.

But I think we should still NOT automatically establish connections -
especially via JNDI, as this is a weird fit (given that the JNDI scheme
is not actually provided by Remoting, it's just being used as a
side-channel to get the invocation connection up).

To implement (B) we probably should just change EJBClientContext to use
ContextSelector, and just have a single global client context in the
standalone case by default.  Users can switch to the thread-local
implementation if they want something more advanced.  Then on the server
we can switch to something more sophisticated like TCCL or something,
maybe eliminate having to have *yet another* interceptor in this path.

> 2) My idea of making this work was to use the Context.PROVIDER_URL as
> our remote receiver uri. So the jndi.properties or even the properties
> passed to the InitialContext could contain (comma separated list)
> something like remote://localhost:9999 (just an example) to point to the
> remote EJB connector. The EJBNamingContext would then be smart enough to
> first setup a (remoting) EJB receiver during context creation and then
> setup a EJB client context on the invoking thread, when the proxy is
> invoked (this would require the lookup to return a wrapper over the
> invocation handler to intercept the calls on the proxy and just do a
> EJBClientContext.setCurrent(...) before passing on the control to the
> EJBInvocationHandler).
>
> #2 is all impl details and actually has numerous issues with it:
>
>       a) It assumes that it would be OK to setup the remoting connection
> ourselves and not mandate the user to provide one (we could actually
> allow users to pass configurations for the connection). David has
> mentioned that it wouldn't be a good idea creating the connection
> ourselves. But that was in the context of pure native EJB client API
> design. Does it make sense to somehow relax that require in this JNDI case?

No because there's nobody to manage that connection.  Which might be
fine in certain cases but overall it's just asking for resource leaks
IMO (there's no real lifecycle on JNDI contexts, nor on the EJB client
context).  Also, only the most trivial authentication schemes will be
able to be utilized in this case.

>       b) The Context.PROVIDER_URL used in the jndi.properties or the
> properties being passed to the InitialContext apply to the entire
> context and aren't anything specific to EJB invocations. i.e. the user
> could use that context to do lookup/invocations on non-EJB objects bound
> to JNDI. I'm not sure how non-EJB JNDI lookup outside of the server VM
> is being implemented/planned, so using that EJB specific(?) remoting
> connector info (remote://<localhost:ejb-remote-connector-port>) in the
> jndi.properties isn't probably a good idea.

Yeah, that's also a good point.  There are many other JNDI schemes out
in the wild and we should stop assuming we're the only ones.

--
- DML
_______________________________________________
jboss-as7-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/jboss-as7-dev
Reply | Threaded
Open this post in threaded view
|

Re: JNDI lookup and EJB invocation from a remote client

Carlo de Wolf
On 10/19/2011 05:43 PM, David M. Lloyd wrote:

>>        b) The Context.PROVIDER_URL used in the jndi.properties or the
>> >  properties being passed to the InitialContext apply to the entire
>> >  context and aren't anything specific to EJB invocations. i.e. the user
>> >  could use that context to do lookup/invocations on non-EJB objects bound
>> >  to JNDI. I'm not sure how non-EJB JNDI lookup outside of the server VM
>> >  is being implemented/planned, so using that EJB specific(?) remoting
>> >  connector info (remote://<localhost:ejb-remote-connector-port>) in the
>> >  jndi.properties isn't probably a good idea.
> Yeah, that's also a good point.  There are many other JNDI schemes out
> in the wild and we should stop assuming we're the only ones.
I don't see how a property specified as org.jboss.ejb.client.<something>
interferes with anything but our own stuff. The ObjectFactory can just
pick that up from the environment.

As for other JNDI name, they can be simple LinkRefs into the ejb: context.
We could even bind an ObjectFactory that simulates EAP 5 bindings. That
would make migration a bit easier.

I showcased all these possibilities in the PoC.

I like the standalone global EJBClientContext. Forget about lifecycle in
standalone, it's just not there.

Carlo
_______________________________________________
jboss-as7-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/jboss-as7-dev