On Mar 15, 2008, at 9:58 PM, David Blevins wrote:

A user pointed out a couple days ago that we weren't supporting inheritance of business interfaces, which we totally should be. I thought since we were delayed on the 3.0 release that I would get this fixed.

Our support for ejb inheritance in general has been pretty weak so I've cooked up a simple test case like the following:
http://svn.apache.org/repos/asf/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/config/InheritenceTest.java

I have part of this implemented. Still lacking the code that can properly handle very layered tx attributes and security permissions. Will need some great test cases for that as well.

Hopefully I can get at least the tx side of things completed tomorrow. If I'm very lucky, I might be able to find a way to knock out both with one stone.

-David


In the process of trying to get that implemented with the code the way we have it structured now (i.e. translating annotations to xml, respecting overriding rules, and dealing only with xml thereafter), it occurred to me the subject of how xml and annotations relate to inheritance and overriding was unclear at best.

I finally wrapped my head around the subject and realized the spec is incomplete in this regard. Below is a chunk of text I sent to the EJB 3.1 EG which I thought I'd share with everyone so we can all become experts in this particular area of EJB. Obviously, the discussion that ensues on the Expert Group I cannot share, so don't ask for updates -- you'll have to wait for public spec reviews like everyone else :)

As far as OpenEJB is concerned what I detailed in Point 1 is simply more specific than than what is already in the spec and we can actually implement now without breaking compliance. We can add and use the proposed <class> element of <method> internally, marking it as @XmlTransient so it can't be read or written. It will allow us to implement the inheritance rules already in the spec without having to have separate rules for annotations versus xml. Should it become part of the spec some day, we can yank the @XmlTransient flag and the feature will instantly be available to users to use in their ejb-jar.xml.

A very detailed heads up, and of course thoughts are welcome.

-David


- - - - - - -
Point 1: There is no equivalent ability in the xml to respect inheritance.
- - - - - - -

Here's the transaction example from section 13.3.7.1:

  @TransactionAttribute(SUPPORTS)
  public class SomeClass {
      public void aMethod () {...}
      public void bMethod () {...}
      ...
  }
  @Stateless public class ABean extends SomeClass implements A {
      public void aMethod () {...}
      @TransactionAttribute(REQUIRES_NEW)
      public void cMethod () {...}
      ...
  }

  Assuming aMethod, bMethod, cMethod are methods of interface A, their
transaction attributes are REQUIRED, SUPPORTS, and REQUIRES_NEW respectively.

Given an xml override like the following, I would expect the transaction attributes of aMethod, bMethod and cMethod to change to MANDATORY, MANDATORY, and REQUIRES_NEW respectively.

  <container-transaction>
      <trans-attribute>Mandatory</trans-attribute>
      <method>
          <ejb-name>ABean</ejb-name>
          <method-name>*</method-name>
      </method>
  </container-transaction>

There is no ability to override/specify the transaction attribute of SomeClass class specifically, leaving ABean untouched. Yes, one could add individual method xml overrides for every single method of SomeClass, but that is brittle; easy to add or remove and forget to update the xml and making sure you've covered every method could be a very manual, time consuming, and error prone process.

The same applies to security constraints.

We should consider adding a <class> element to <method> so a given class in the inheritance chain could be targeted, such as:

  <container-transaction>
      <trans-attribute>Mandatory</trans-attribute>
      <method>
          <ejb-name>ABean</ejb-name>
          <class>SomeClass</class>
          <method-name>*</method-name>
      </method>
  </container-transaction>

Which would change the transaction attributes of aMethod, bMethod and cMethod to change to REQUIRED, MANDATORY, and REQUIRES_NEW respectively.


- - - - - - -
Point 2: There is no ability in annotations to disregard inheritance.
- - - - - - -

Given the same example above with ABean subclassing from SomeClass, via xml we have the ability to set the base transaction attribute for both in one swoop as follows:

  <container-transaction>
      <trans-attribute>Mandatory</trans-attribute>
      <method>
          <ejb-name>ABean</ejb-name>
          <method-name>*</method-name>
      </method>
  </container-transaction>

There is no equivalent way to do the same via annotations on just the ABean class. Yes, it is possible to use java overriding in ABean class on each method of SomeClass, but this is also a bit brittle; it's easy for someone to add a method to SomeClass and forget to revisit every subclass of SomeClass and add the required override which again is error prone and time consuming.

Again, the same applies to security annotations.

I'm not sure on a good name, but we could add another attribute to the transaction and security annotations that allow the user to state they'd like the annotation to apply to the annotated class and all ancestors as well which would achieve the same result as the above xml declaration.


Reply via email to