To track it, I entered an issue in deployment category:
https://glassfish.dev.java.net/issues/show_bug.cgi?id=931
with the additional comments:
The root cause is in
annotation-framework/src/java/com/sun/enterprise/deployment/annotation/impl/ComponentDefinition.java:
private void initializeMethods() {
for (Class cl: classes) {
for (Method method : cl.getDeclaredMethods()) {
MethodKey mk = new MethodKey(method);
if(methodMap.containsKey(mk)) {
methodMap.get(mk));
}
methodMap.put(mk, method);
}
}
}
For EchoBean.class, getDeclaredMethods() contains both Object getMessage(); and
String getMessage(). Although no order is guaranteed, the Object one happens to
be after the String one. So the Object one will always overwrite the existing
binding for the String one in methodMap, since their MethodKey are the same.
Therefore, any annotations on String getMessage() are ignored.
I don't know why here we need a custom equals method for Method. For this
particular issue, we could modify MethodKey.equals() to distinguish return type.
Another options is to check methodMap.contains(methodKey) before overwriting
any existing bindings, and choose the method with the most specific return type.
I'd suggest we add this feature. JBoss supports this or will support this.
I also noticed while debugging this, ComponentDefinition.initializeMethods() is
called twice in a row, doing exactly the same thing. May be of interest.
Cheng
Kenneth Saks wrote:
> Cheng Fang wrote:
>
>> When I use such a business method in a simple ejb3 stateless session
>> bean, it works fine :-)
>>
>> @Remote
>> public interface EchoRemote {
>> void echo();
>> void echo2();
>> Object getMessage();
>> }
>> ------------------
>> @Stateless
>> public class EchoBean implements com.foo.ejb.EchoRemote {
>> ...
>>
>> public String getMessage() { //String, instead of Object, is
>> returned
>> return "A message from EchoBean";
>> }
>> }
>
>
> This isn't allowed for Home/LocalHome create() methods but I'm not sure
> whether the spec allows it for business methods. Linda?
>
>>
>>
>> When I apply a
>> @TransactionAttribute(TransactionAttributeType.MANDATORY) on this
>> business method, the annotation is ignored.
>> @TransactionAttribute(TransactionAttributeType.MANDATORY)
>> public String getMessage() { //String, instead of Object, is returned
>> return "A message from EchoBean";
>> }
>>
>> I expect a TransactionRequiredException or the like, since my web
>> client doesn't start transaction, but no exception occurred. The
>> generated ejb-jar.xml after deployment contains no transaction
>> attribute for any methods. So the default REQUIRED is always used.
>>
>> If I change the return type to Object, I got the expected exception.
>>
>> I suspect all method-level annotation on such methods are ignored,
>> though I haven't tested other annotations.
>> This looks like a bug, unless ejb spec has special restrictions on
>> covariant return type.
>>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: ejb-unsubscribe_at_glassfish.dev.java.net
> For additional commands, e-mail: ejb-help_at_glassfish.dev.java.net
>