ejb@glassfish.java.net

Re: class-level annotation x internal annotation

From: Kenneth Saks <Kenneth.Saks_at_Sun.COM>
Date: Thu, 15 Feb 2007 17:27:05 -0500

haginow2001-devjavanet_at_yahoo.com wrote:

> 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)?
>
Yes. Unless the ejb-jar.xml has its metadata-complete attribute set to
true, any bean classes of session or message-driven beans it defines
must be processed for annotations. Please file an issue on IssueTracker
for this and include your simple example. Thanks.

 --ken

> 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.*/
>
>
>