Thanks so much for your replies. I'll be filing the bug as requested.
Cheers
Christianne Carvalho
mHave Software, Ltda.
--------------------------------------------------------------------------------
From: Kenneth Saks [mailto:Kenneth.Saks_at_Sun.COM]
Sent: Thursday, February 15, 2007 8:27 PM
To: ejb_at_glassfish.dev.java.net
Subject: Re: class-level annotation x internal annotation
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.