Suppose I have a class like this:
@Stateless
@Local({ X.class })
public class XBean implements X {
@EJB // name() attribute should by spec default to "foo.XBean/y", but see below
private Y y; // Y is @Local
}
And elsewhere I have:
@Stateless
@Local({ Y.class })
public class YBean implements Y {}
@Stateless
@Local({ Y.class })
public class UnwantedYBean implements Y {}
Suppose now I want (in an XML descriptor, using the minimal amount of XML) to override or explicitly specify what gets placed in the y
field in XBean
.
This construct (in a META-INF/ejb-jar.xml
file, of course) surprisingly (to me) does not work in GlassFish 3.1.2.2:
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>XBean</ejb-name>
<ejb-local-ref>
<ejb-ref-name>foo.XBean/y</ejb-ref-name>
<ejb-link>YBean</ejb-link>
</ejb-local-ref>
</session>
</enterprise-beans>
</ejb-jar>
I'd like to focus this question on the ejb-jar.xml
snippet above, not on any container bugs or anything like that. Specifically: is the above snippet the correct and the smallest possible way to override what EJB gets injected into my XBean.y
field?
Some notes:
Others have suggested that I need to put an
<injection-target>
stanza in there. Why would that be? The injection target is already specified by virtue of my using the@EJB
annotation. I don't wish to override where the injection occurs, only what actually gets injected.The EJB specification author herself also said that the
<ejb-ref-name>
should be simplyy
, notfoo.XBean/y
. This is despite the fact that the specification says (section 16.5.1.3):
The ejb-ref-name element specifies the EJB reference name: its value is the environment entry name used in the enterprise bean code [emphasis mine].
There is nowhere in the EJB specification that says what the default value of the
name
attribute is for the@EJB
annotation (!), but we can infer that it is also the environment entry name.The spec gives an example in section 16.5.1.1:
package com.acme.example;
@Stateless public class ExampleBean implements Example {
...
@EJB private ShoppingCart myCart;
...
}
...which is exactly equal to mine, and then says in the same section (this is as close as we'll get to discovering what the default value for @EJB
's name
attribute is):
The enterprise bean reference will have the name
java:comp/env/com.acme.example.ExampleBean/myCart
in the referencing bean’s naming context, whereExampleBean
is the name of the class of the referencing bean andcom.acme.example
its package.
The "naming context" in that sentence is the java:comp/env/
part, so everything else is the name, so the default value of an unadorned @EJB
annotation's name
attribute is classname/fieldName
. I don't see how this could be otherwise. This is also backed up by the table present in the GlassFish EJB FAQ.
Bottom line: what is wrong with my XML stanza cited above? Why does it not cause a proxied instance of YBean
to be injected into my XBean
's @EJB
-annotated private Y y
field?