You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomee.apache.org by David Blevins <da...@visi.com> on 2010/08/28 22:55:21 UTC

Re: @AccessTimeout annotation

On Aug 27, 2010, at 9:19 PM, Jarek Gawor wrote:

> Just wanted to double check that the @AccessTimeout annotations are
> supposed to be processed in exactly the same way as the @Lock
> annotations. The spec does talk about how the @Lock annotations are
> supposed to be processed but doesn't say much about the
> @AccessTimeout. So I just wanted to confirm that.

Right.  Basically the processing of @Lock, @AccessTimeout and @Asynchronous is identical to @TransactionAttribute and the security related annotations such as @RolesAllowed.

Probably a good time to document this stuff on the website as it can get a little confusing.  So here's a slightly longer answer :)

 - - - - - - - - - - - - - - - 

@AccessTimeout(0)
public class Color {
    public void color(){}

    @AccessTimeout(10)
    public void colour(){}
}

@AccessTimeout(-1)
public class Red extends Color {
    public void red(){}
}

public class Crimson extends Red {
    public void crimson(){}
}

The effective @AccessTimeouts for these methods end up as:

  color()   = 0
  colour()  = 10 
  red()     = -1
  crimson() = unspecified

In our case, unspecified means we take the AccessTimeout that means we default to checking:

 1. deploymentInfo AccessTimeout property
 2. container AccessTimeout property

At least that's how the StatelessContainer honors AccessTimeout.  All the containers should be identical in first preferring the bean AccessTimeout if specified and then defaulting to the container default.

 - - - - - - - - - - - - - - - 

Same applies to @Lock

@Lock(WRITE)
public class Color {
    public void color(){}

    @Lock(READ)
    public void colour(){}
}

@Lock(READ)
public class Red extends Color {
    public void red(){}
}

public class Crimson extends Red {
    public void crimson(){}
}

The effective @Lock for these methods end up as:

  color()   = WRITE
  colour()  = READ
  red()     = READ
  crimson() = unspecified

This time with the caveat that there is a specification defined default for @Lock of WRITE, so crimson() will be an @Lock(WRITE) method.  On this note, we could be clever on how we enforce the default if we wanted some additional consistency with @AccessTimeout (and @StatefulTimeout) and let the default be set in the bean or container config.  So we could add a 'Lock' property check like we do the others:

  1. deploymentInfo Lock property
  2. container Lock property

 - - - - - - - - - - - - - - - 

The hard part of all this is the xml overrides as the xml itself doesn't have the same fidelity to the specific class as the annotation does; i.e. you can't specify the class which would allow you to target an override.  And since we process all annotations into xml, we had to add extra class information to the JAXB tree and use that to give one set of metadata precedence over the other.  It's difficult because generally speaking more specific metadata wins over more generic.  Using the example from the spec:

        1.
        <method>
        <ejb-name>EJBNAME</ejb-name>
        <method-name>*</method-name>
        </method>
        
        This style is used to refer to all the methods of the
        specified enterprise bean's business, home, component, 
        and/or web service endpoint interfaces.
        
        2.
        <method>
        <ejb-name>EJBNAME</ejb-name>
        <method-name>METHOD</method-name>
        </method>
        
        This style is used to refer to the specified method of
        the specified enterprise bean. If there are multiple
        methods with the same overloaded name, the element of
        this style refers to all the methods with the overloaded
        name.
        
        3.
        <method>
        <ejb-name>EJBNAME</ejb-name>
        <method-name>METHOD</method-name>
        <method-params>
        	  <method-param>PARAM-1</method-param>
        	  <method-param>PARAM-2</method-param>
        	  ...
        	  <method-param>PARAM-n</method-param>
        </method-params>
        </method>


        This style is used to refer to a single method within a
        set of methods with an overloaded name.


This is great, but the metadata that comes from annotations is always specific yet should loose to the xml metadata.  

I don't recall the exact details of the compromises we make to get these to balance out, but it basically hinges on the 'className' metadata we added to the JAXB tree as @XmlTransient as that data will only be present if the metadata was generated by us from the annotation.

I do recall it being an incredible pain to balance and still make the TCK happy.  Coverage in this area is spotty and as a result our code was very inconsistent with itself.  The code that processed @TransactionAttribute data was handing overrides differently than the code that processed @RolesAllowed and similar.  When I put the processing code in for @Lock is when we did the rebalancing and made everything consistent.  As it turned out the final xml metadata for @Lock ended up differently than the original version.

 - - - - - - - - - - - - - - - 

And of course the @Asynchronous annotation is applicable to the method and the class and has the same semantics.


public class Color {
    public void color(){}

    @Asynchronous
    public void colour(){}
}

@Asynchronous
public class Red extends Color {
    public void red(){}
}

public class Crimson extends Red {
    public void crimson(){}
}

The effective @Lock for these methods end up as:

  color()   = unspecified
  colour()  = asynchronous
  red()     = asynchronous
  crimson() = unspecified

Obviously unspecified means synchronous and there's no reason to consult any bean/container metadata -- just doesn't apply.  But the overriding rules are exactly the same as well.

Ideally, we could get some consistently functioning code for method/class applicable metadata and funnel all these sources through it.  The TransactionAttribute processing code is abstracted to support additional kinds of metadata, but that code also has the additional semantics of things that are found in the <assembly-descriptor> which is sort of the old way to compose metadata on beans and pulls in the "method interface" which is a needless complication.  No future annotations added to EJB will be using that, so maybe we want to not use it.  But definitely I hope we can stay on the consistent path.


-David


Re: @AccessTimeout annotation

Posted by David Blevins <da...@visi.com>.
On Aug 28, 2010, at 1:55 PM, David Blevins wrote:

> Ideally, we could get some consistently functioning code for method/class applicable metadata and funnel all these sources through it.  The TransactionAttribute processing code is abstracted to support additional kinds of metadata, but that code also has the additional semantics of things that are found in the <assembly-descriptor> which is sort of the old way to compose metadata on beans and pulls in the "method interface" which is a needless complication.  No future annotations added to EJB will be using that, so maybe we want to not use it.  But definitely I hope we can stay on the consistent path.

Cool.  Saw the commit.

What approach did you end up taking?


-David