-
1. Re: Using request scope with remote EJB
nickarls Jan 23, 2010 12:14 PM (in response to swiegersf.francois.swiegers.gmail.com)Tried @Inject for the EJB?
-
2. Re: Using request scope with remote EJB
swiegersf.francois.swiegers.gmail.com Jan 23, 2010 2:06 PM (in response to swiegersf.francois.swiegers.gmail.com)Hi Nicklas
Thanks for the swift response.
Do you mean I must add the @Inject annotation on the client side? If I do that, I get the same error. Here is my code:
public class Main { @Inject @EJB private static InjectorService remoteEjb; public static void main(String[] args) { System.out.println(remoteEjb.doSomething()); System.out.println(remoteEjb.doSomething()); } }
If I remove the @EJB annotation and make it an instance variable, then it simply stays NULL, as if CDI is ignoring the @Inject annotation on my client.
I am of course quite a newbie with CDI, so I may in fact completely miss what you've suggested ...
-
3. Re: Using request scope with remote EJB
swiegersf.francois.swiegers.gmail.com Jan 23, 2010 2:50 PM (in response to swiegersf.francois.swiegers.gmail.com)OK, after some further reading I conclude that my NullPointerException is due to the fact that my client is not running under a CDI context.
-
4. Re: Using request scope with remote EJB
swiegersf.francois.swiegers.gmail.com Jan 24, 2010 9:48 AM (in response to swiegersf.francois.swiegers.gmail.com)I can get the desired behaviour by implementing a custom scope using this tutorial.
However, this is clumsy, as this scope really just behaves like a RequestScoped service would if it was invoked from a servlet container via the EJB's local interface.
Surely the normal request scope context must be available when doing a standard remote EJB invocation?
I don't think my problem is with the client either, because the client of the EJB should not be concerned with its CDI context.
My central question really is just: Is it a bug that Glassfish/Weld is not activating the request scope for remote EJB invocations, or is that how CDI specifies it?
-
5. Re: Using request scope with remote EJB
nickarls Jan 24, 2010 11:52 AM (in response to swiegersf.francois.swiegers.gmail.com)Yes the request scope is available when doing a remote EJB invocation but the request scope is a HTTP request, which is not available in SE (if the Weld SE extension doesn't do any mock magic, haven't checked).
-
6. Re: Using request scope with remote EJB
swiegersf.francois.swiegers.gmail.com Jan 24, 2010 1:29 PM (in response to swiegersf.francois.swiegers.gmail.com)Thanks Nicklas,
I'm not using the SE extension - I'm using EJB's in Glassfish. I think the problem is that my EJB is invoked via RMI/IIOP, not the servlet layer, which means that there is no HTTP context to propagate to CDI.
I was hoping that Weld would activate the standard scopes outside of the servlet context, since the EJB context should provide the same semantics as an HTTP context.
-
7. Re: Using request scope with remote EJB
swiegersf.francois.swiegers.gmail.com Jan 24, 2010 2:56 PM (in response to swiegersf.francois.swiegers.gmail.com)I found the following interceptor in Weld:
org.jboss.weld.ejb.SessionBeanInterceptorIt seems to do exactly what I am looking for here. However, curiously, it does not seem to be active by default, and when I try to switch in on using beans.xml, Glassfish complains that the interceptor does not have the @Interceptor annotation.
I managed to get it working by copying the source code into my own interceptor. I also had to add weld-core.jar to my ejb classpath (for some reason Glassfish cannot load org.jboss.weld.context.beanstore.HashMapBeanStore, probably due to a dependency that is not present is the default distribution).
It does work and, regardless of the nasty interceptor binding I have to add to my EJB, is a far better way to deal with this than defining a custom scope.
However, I still feel that a CDI implementation should provide standard context activation outside of a servlet context, because the Java EE spec does not require access to EJB's to go through a servlet layer.
I suppose doing a similar interceptor-style solution for session and conversation scope could be more tricky as you would have to access the EJB context, which is probably not as standards-driven as the HTTP equivalents. I'll give it a bash over then next few days.
I appreciate the pointers, Nicklas (over a weekend, nothing less!).
-
8. Re: Using request scope with remote EJB
gavin.king Jan 24, 2010 8:04 PM (in response to swiegersf.francois.swiegers.gmail.com)Your description of your problem is all a bit muddled, making it very difficult to understand what it really is that you're missing. But let me give it a shot:
(1) The combination @Inject @EJB is always wrong. I've no idea what you were trying to do with that, but it doesn't mean anything at all.
(2) CDI does not support the use of @Inject on static fields or methods.
(3) You can't use @Inject to inject a reference to a remote EJB, unless you define the resource using @Produces @EJB (see spec section 3.5).
(4) You can not, in general, use Java EE features like @Inject and @EJB in a main() method, unless you are in a Java EE application client jar, or have something special like the Weld Java SE extension. Even if you are using an application client jar, the CDI spec does not require that the container support CDI (spec 12.1), and I doubt that GlassFish does support this.
So you need to find a better way to get a reference to the remote EJB. Once you have this remote EJB reference, you can indeed inject @RequestScoped beans into it (see spec 6.7.1). Your problem does not have much to do with the lack of a context on the client, because CDI contexts are not propagated across remote calls (spec 6.7).
-
9. Re: Using request scope with remote EJB
gavin.king Jan 24, 2010 8:05 PM (in response to swiegersf.francois.swiegers.gmail.com)What I'm trying to say is that just about the whole of this thread appears to be riddled with misunderstanding.
-
10. Re: Using request scope with remote EJB
swiegersf.francois.swiegers.gmail.com Jan 25, 2010 7:28 AM (in response to swiegersf.francois.swiegers.gmail.com)
What I'm trying to say is that just about the whole of this thread appears to be riddled with misunderstanding.Yep, I'll take responsibility for that - I am obviously quite a newbie here, so some of these concepts are still taking shape in my mind, so my questions may not be clear. I'll try to fix that now.
First some background: I develop and support an enterprise application that makes extensive use of rich application clients (not RIA, but SWT on the desktop) that invoke EJB's using RMI/IIOP directly. This is not a web application, so we don't make use of any servlet/HTTP based technology - we call the RMI interface directly. My task at the moment is to determine the effort required to bring this app up to Java EE 6 standards, including adopting the excellent CDI approach over our current Guice implementation.
My question is not about the client side of the application at all - I simply included that snippet so that someone with better knowledge can replicate my situation if he/she so chooses. I should have added that it runs inside the Glassfish client container though.
What I want to do is use the standard scopes of CDI (request, session, conversation and application) on my server side EJB's, without going through a servlet engine, but using RMI/IIOP directly.
As you point out (6.7.1), it should work regardless of whether the activation goes through the servlet layer or via RMI. However, as my first example shows, this does not seem to work out of the box with the current Glassfish release, either because:
- Its a bug in Weld/Glassfish
- I'm doing something stupid
- CDI is not required to support RMI activations unless you go through a servlet layer first
In case 1 or 2 I'm not really concerned (but please tell me if I'm doing something stupid!) :)
If it is case 3, then I want the community's opinion on whether RMI/IIOP is still a viable protocol if we want to adopt CDI on the server using the standard scope types.
Thanks for the time, I hope that clears things up a bit.
-
11. Re: Using request scope with remote EJB
swiegersf.francois.swiegers.gmail.com Jan 25, 2010 8:28 AM (in response to swiegersf.francois.swiegers.gmail.com)
As you point out (6.7.1), it should workJust to correct, you said the request scope should work, not necessarily the session or conversation scopes.
-
12. Re: Using request scope with remote EJB
gavin.king Jan 26, 2010 2:32 AM (in response to swiegersf.francois.swiegers.gmail.com)Well, 3 is certainly not true, according to the spec.
-
13. Re: Using request scope with remote EJB
swiegersf.francois.swiegers.gmail.com Jan 26, 2010 6:02 AM (in response to swiegersf.francois.swiegers.gmail.com)Thanks
If I want my RMI server to also support SessionScoped and ConversationScoped contexts (these, as far as I can see, is not required to be supported outside of the servlet context), what are my practical options for doing this?
- Implement a custom scope
- Use an interceptor to activate the scope
Neither of these approaches are perfect (but I think 2 is better than 1), is there another way that I'm unaware of?
-
14. Re: Using request scope with remote EJB
pmuir Jan 26, 2010 3:09 PM (in response to swiegersf.francois.swiegers.gmail.com)This is a bug in GlassFish, they need to register org.jboss.weld.ejb.SessionBeanInterceptor as an EJB interceptor in any app which has CDI enabled (as documented in A.2 of the Weld ref guide). Please raise an issue in the GlassFish issue tracker.