ejb@glassfish.java.net

Re: class-level annotation x internal annotation

From: <haginow2001-devjavanet_at_yahoo.com>
Date: Thu, 15 Feb 2007 13:42:26 -0800 (PST)

Ken, Regarding your comment on annotation processing on bean classes: I've looked through the EJB 3.0 and JaveEE 5 specs a couple of times, but I haven't found anything which says that annotation processing is not supported on bean classes which are not explicitly annotated as a bean (e.g. using @Stateless). That makes me believe that it should be possible to mix annotations and deployment descriptor entries for any bean, whether annotated as bean or simply defined as a bean through a deployment descriptor entry. Wouldn't you agree on that (even if it is an advanced use case)? Chris ----- Original Message ---- From: Kenneth Saks <Kenneth.Saks_at_Sun.COM> To: ejb_at_glassfish.dev.java.net Sent: Thursday, February 15, 2007 1:29:01 PM Subject: Re: class-level annotation x internal annotation Christianne Carvalho wrote: Hi all. Although annotations hugely simplify the ejb codification, for project specific needs, in some cases our ejbs are also being defined in ejb-jar. For messagedriven beans we noticed two points that don't seem to be working proper. 1) As soon as you have the @MessageDriven class-level annotation, seems that it ignores the entry in the deployment descriptor (which is wrong according to the EJB 3.0 specs). If I remove it, everything works fine. Hi Christianne, A bean defined via @MessageDriven is associated to a <message-driven> entry in ejb-jar.xml is by its ejb-name. When using @MessageDriven, the ejb-name of the bean you're defining is either the value of the name() attribute or defaults to unqualified class name. In your example, that would be MyConsumer. Unless there's a <message-driven> entry in ejb-jar.xml with <ejb-name>MyConsumer</ejb-name>, the <message-driven> entries that are there are considered different than the bean you defined via @MessageDriven. Another thing to note is that the use of @MessageDriven is intended for the common and simpler case where there is only one MessageDriven bean defined for a given bean class. The ejb-jar.xml always technically allowed the definition of more than EJB component that happened to use the same bean class but that is considered an advanced case that doesn't mesh well with the use of the component-defining annotation. 2) So, to solve that we defined those beans only in ejb-jar instead of using the class-level annotations (@MessageDriven or @Stateless). When we do that we noticed that for those ejbs, we cannot add JavaEE annotations for dependencies (e.g. @EJB or @Resource). Seems that GF doesn't parse any annotations unless there is a class-level annotation. Should these two items be happening this way? Follows example: What I'm doing is that I have a single mdb class that I want to listen to several queues. I initially tried like this: You would be better off having a unique bean class for each message-bean. If there is a lot of common behavior across them you can refactor it into a common super-class. That way, each leaf message-bean class can use @MessageDriven and you can avoid ejb-jar.xml. Super-classes are required to be processed for environment annotations. class: @MessageDriven public MyConsumer { @EJB ProcessorBean processor ; (...) } ejb-jar: <message-driven> <ejb-name>PrimaryConsumerEJB</ejb-name> <mapped-name>jms/primaryQueue</mapped-name> <ejb-class>com.mdb.MyConsumer</ejb-class> </message-driven> <message-driven> <ejb-name>SecondaryConsumerEJB</ejb-name> <mapped-name>jms/secondaryQueue</mapped-name> <ejb-class>com.mdb.MyConsumer</ejb-class> </message-driven> However it only worked when I did like this: class: public MyConsumer { MyProcessor processor ; (...) } ejb-jar: <message-driven> <ejb-name>PrimaryConsumerEJB</ejb-name> <mapped-name>jms/primaryQueue</mapped-name> <ejb-class>com.mdb.MyConsumer</ejb-class> <ejb-ref> <ejb-ref-name>ProcessorEJB</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <remote>com.slb.MyProcessor</remote> <ejb-link>MyProcessorEJB</ejb-link> <injection-target> <injection-target-class>com.mdb.MyConsumer</injection-target-class> <injection-target-name>processor</injection-target-name> </injection-target> </ejb-ref> </message-driven> <message-driven> <ejb-name>SecondaryConsumerEJB</ejb-name> <mapped-name>jms/secondaryQueue</mapped-name> <ejb-class>com.mdb.MyConsumer</ejb-class> <ejb-ref> <ejb-ref-name>ProcessorEJB</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <remote>com.slb.MyProcessor</remote> <ejb-link>MyProcessorEJB</ejb-link> <injection-target> <injection-target-class>com.mdb.MyConsumer</injection-target-class> <injection-target-name>processor</injection-target-name> </injection-target> </ejb-ref> </message-driven> Thanks. Christianne Carvalho mHave Software, Ltda.