views:

48

answers:

2

I have an asynchronous method in my EJB singleton that's called from another method in the same class. I already know that I can't call the asynchronous method directly, I have to obtain an EJB proxy. The problem is, I don't want the asynchronous method to be visible outside the class; but when I make it private, it's not executed asynchronously. (I'm using Glassfish v3.)

The javadocs don't say anything about the required access level. So should this be considered a bug in Glassfish?

+1  A: 

method annotation cannot be used in private methods. When Glassfish is compiling your EJB it will basically convert your annotation into a piece of code that will surround your code in a proxy. If your method is private it will bypass the proxy Glassfish created... So, in your case I suggest to create a new EJB with your asynchronous method in inject it in your current EJB

Plínio Pantaleão
OK, but *why*? You're saying that the proxy object will only have proxies for public methods. Is this actually required by the Java EE spec, or is it just a Glassfish implementation detail?
Mike Baranczak
Its only a Glassfish implementation, but look at waht Javadoc says " Used to mark a method as an asynchronous method or to designate all business methods of a class or interface as asynchronous."business methods are methods that can be used by others. private methods dont come in.
Plínio Pantaleão
It is required by the EE spec that only public methods can be used. There would otherwise be no way for a container to create a proxy for a private method unless AOP/weaving. The fact that you're attempting to call a private method means that you're not properly calling business methods, you're just calling local methods.
bkail
+1  A: 

That's a very interesting bit of feedback. I can see the value in what you are trying to do. Try marking your bean as an @LocalBean and annotating your @Asynchronous method as protected.

As @LocalBean support is basically done via subclassing the bean class (dynamically or statically), it isn't really possible for the container to override the private method. But I can certainly see your use case. If the protected method approach doesn't work, we can probably add this as an enhancement to EJB.next.

Would still give access to other beans in the same package, but it's at least less public. I've often wished Java had an 'only subclasses' scope. I've almost never used protected and thought, "great, now everyone in my package can access this too."

David Blevins
Marking it protected won't really accomplish what I want, but thanks for the suggestion. This might be a good addition for the next version of EJB; failing that, it'd be nice if the documentation simply explained that this sort of thing won't work. And I agree about the "subclass-only scope" idea.
Mike Baranczak