EJB3 customizing/extending question
I have an EJB module with some stateless session beans in it. They all are quite obviously currently deployed.
I started down the road on the following thought experiment, which I'm fairly convinced is invalid, but thought I'd ask.
Suppose I "buy" that fabled EJB jar that you're supposed to be able to purchase from so-called component vendors. And suppose I want, for whatever reason, to treat that ejb-jar file as much like a black box as possible.
Now suppose that it ships with a WombatBean in it, whose ejb-name is WombatBean, and whose ejb-class is com.foo.WombatBeanImpl. Suppose I want to add an additional couple of attributes--semantically--to it, without cracking open the ejb-jar.
Could I:
* Write an EJB that extends WombatBeanImpl--suppose it's com.ljn.WombatBeanExtension--and pack it up in itsown ejb-jar file
* Somehow convince the EJB container to map the ejb-name of WombatBean to "point" at com.ljn.WombatBeanExtension, such that com.foo.WombatBeanImpl is always "shadowed"?
I understand that I could sort of accomplish this and say that for all applications I know about I could go play games with ejb-refs and the like and point them all at my bean instead of theirs, but I guess I wanted to do this "underneath" the ejb-name they're all referencing.
Does this make any sense? Am I waaaay off base here?
Thanks,
Laird
P. S. If I can do this, but it's appserver-dependent, I'd appreciate those answers too. I'm using EJB3/JavaEE5 on Glassfish b32.
[1558 byte] By [
ljnelsona] at [2007-11-26 16:16:31]

# 1
An ejb session bean class cannot extend from another ejb session bean class. For the usecase you described, you can try using composition rather than inheritance, having anther session calling the original bean and do something else.-cheng
# 2
Hi,
I'm pretty sure you are allowed to extend the EJB you bought and provide your own properties with appropriate annotations. So, everything you wrote is valid and doable.
I should've been checked it out yourself, but I thought I wouldn't spoil the game and leave the final confirmation to you.
Jacek
# 3
Thanks, Jacek; the main question I had was how to "override", I guess, an ejb-name entry. If the purchased bean has an ejb-name of Wombat, and I deploy my extension ejb in an ejb-jar and assign that ejb an ejb-name of Wombat...I'm not sure this is legal. I'll try it out, of course, and it will work or not, but I'm more interested in: SHOULD it work? Is it allowed to work?
Thanks for your help.
# 4
ejb-name is only guaranteed to be unique within the scope of an ejb-jar, so by definition if the other
ejb is in a different ejb-jar the ejb-names would not clash.
Regarding the issue of sub-classing,
it's not that you can't use implementation inheritance, where one of the super-classes happens
to be the bean class of an EJB component.The point is that there is no special notion of
*component* inheritance for beans.In other words, just because you write a class FooBean
whose parent is a bean class with an @Stateless annotation doesn't make FooBean an EJB.
FooBean would need its own component-defining annotation or an entry in an ejb-jar.xml that
declares it as a bean.In addition, some of the ejb meta-data in the super-class would not
apply to FooBean, such as its metadata for declaring which local/remote interfaces it exposes.
There is a lot of complexity in defining rules for processing of the ejb annotations
to support full component inheritance so the spec decided to limit this support to keep
things simpler.
--ken
# 5
> ejb-name is only guaranteed to be unique within the
> scope of an ejb-jar, so by definition if the other
> ejb is in a different ejb-jar the ejb-names would not
> clash.
Yes, understood fully.
> Regarding the issue of sub-classing,
> it's not that you can't use implementation
> inheritance, where one of the super-classes happens
> to be the bean class of an EJB component.The point
> is that there is no special notion of
> *component* inheritance for beans.In other words,
> just because you write a class FooBean
> whose parent is a bean class with an @Stateless
> annotation doesn't make FooBean an EJB.
Also fully understood. I'm talking about an ejb-jar, however, with a @Stateless session bean in it, deployed under a given ejb-name. Then I'm also talking about another ejb-jar, with a class in it that inherits from said @Stateless session bean, that is also annotated as a @Stateless session bean. I'm hoping that the second @Stateless session bean--the overrider--will "trump" the first.
> FooBean would need its own component-defining
> annotation or an entry in an ejb-jar.xml that
> declares it as a bean.
Yes, and now I'm talking about FooExtension, that is itself also annotated as a @Stateless session bean, but that extends from the first one, and has the same ejb-name as the first, thus, for all intents and purposes, "silently replacing" the first.
Do my clarifications make sense? Is the question still meaningful?
Thanks,
Laird
# 6
Hi,
As far as I understood the EJB3 spec, you may override annotations (or their default values) in subclasses that happen to be EJBs, too. Other non-overriden values (the default ones and these from annotations) are inherited. Doesn't it apply to remote and local interfaces? Could you point me to the place where it's described in the spec? I'd expect that the EJB subclass inherits the interfaces and their scope.
Jacek
# 7
Hi Laird,
> Also fully understood. I'm talking about an ejb-jar,
> however, with a @Stateless session bean in it,
> deployed under a given ejb-name. Then I'm also
> talking about another ejb-jar, with a class in
> it that inherits from said @Stateless session bean,
> that is also annotated as a @Stateless session
> bean. I'm hoping that the second @Stateless session
> bean--the overrider--will "trump" the first.
Unfortunately not. There is no hiding of the initial bean.
Every class that contains @Stateless defines a
a separate EJB component.
>
> Yes, and now I'm talking about FooExtension, that is
> itself also annotated as a @Stateless session bean,
> but that extends from the first one, and has the same
> ejb-name as the first, thus, for all intents and
> purposes, "silently replacing" the first.
>
> Do my clarifications make sense? Is the question
> still meaningful?
I understand what you'd like to do but there's no real support for it.
If there are two different classes in the same ejb-jar that
both declare the same ejb-name via component-defining
annotations, it's not a valid app.It would be the same as
having two different <session> elements in the ejb-jar with the
same <ejb-name>.
The closest you can get to overriding the behavior of a particular
bean that was declared using @Stateless would be to use
ejb-jar.xml and define an entry with the same ejb-name. If you
want to *completely* redefine the bean you would need to
set metadata-complete=true at the ejb-jar.xml level. However,
that means no annotations will be processed for the entire ejb-jar.
The alternative is to use standard overriding. However, this is
really intended for application assembly meta-data such as method-permissions
and environment contents, not for structural information such
as the bean-class itself.
--ken
>
> Thanks,
> Laird
# 8
> I understand what you'd like to do but there's no
> real support for it.
> If there are two different classes in the same
> ejb-jar that
> both declare the same ejb-name via component-defining
>
> annotations, it's not a valid app.
Does it matter that the classes I'm talking about would be in two different ejb-jars?
Laird
# 9
> Does it matter that the classes I'm talking about
> would be in two different ejb-jars?
Yes, as we were saying earlier, the ejb-name is only unique within an ejb-jar.
If you're in a separate ejb-jar you can define anything you want with
that ejb-name. There's no prescribed relationship to the other one.
However, it won't hide the other ejb and there's a lot of
bean-defining metadata you'll have to replicate.The super-class will
only really be used for implementation inheritance and for processing some kinds
of annotations.
# 10
Hi Jacek,
This could certainly be a lot clearer in the specs, but the way it works is that
the semantics of annotations in super-classes differ depending on the
annotation type.The structural EJB annotations such as @Local, @RemoteHome,
@Stateless, etc. are only defined on the bean class. There is no requirement
that super-classes be processed for those annotations.The EJB spec and
Java EE spec do require super-class processing for other annotations such
as the environment annotations(@EJB, @Resource) and a lot of the method-level
meta-data such as transaction attributes.Unless the spec specifically says
that super-classes are processed for a particular annotation it's not done.
You can find an example in the transaction chapter of the core spec, 13.3.7.1,
where it lists the special rules for processing of transaction annotations
in super-classes.
--ken