jsr366-experts@javaee-spec.java.net

[jsr366-experts] Re: Compatibility Problems with MR Resource Annotation Widening

From: Jason Greene <jason.greene_at_redhat.com>
Date: Fri, 20 Feb 2015 12:56:57 -0600

> On Feb 19, 2015, at 6:59 PM, Bill Shannon <bill.shannon_at_oracle.com> wrote:
>
> In order to tighten the spec and improve application portability, we're going
> to have to break some non-portable applications and some incompatible
> implementations. If you think we can never do that, it's going to be very
> hard to move the spec forward. And if every time we do that we have to add
> a "compatible with old incorrect behavior" flag, we won't be able to manage
> the complexity.

I’m not convinced it’s incorrect. The spec states in EE 5.2.5:

"Resource annotations may appear on any of the classes listed above, or on any superclass of any class listed above. A resource annotation on any class in the inheritance hierarchy defines a resource needed by the application component.”

The table referenced defines whats a component and what is not. So from the user’s perspective what they are doing is correct and should be portable.

So perhaps some examples (note I put question marks below because the MR language doesn’t actually define which namespaces our bound for these new non-component classes):

Example 1:

Base.class in ear/lib, defines @Resource(name = “myresource”)
A.class (an EJB) extends Base in ejb1.jar
B.class (an EJB) extends Base in ejb1.jar

Before MR, we have two bindings:
  A has a comp entry for “myresource"
  B has a comp entry for “myresource"

After MR, we have three? bindings:
  A has a comp entry for “myresource"
  B has a comp entry for “myresource”
  Base creates java:app/env/myresource?

Example 2:

Base.class (not a component) in ejb1.jar, @Resource(name = “myresource”)
A.class (an EJB) extends Base in ejb1.jar

Before MR we have one binding:
  A has a comp entry for “myresource”

After MR we have two? bindings:
  A has a comp entry for “myresource”
  Base creates java:module/env/myresource?

Example 3:

Base.class (not a component) in ejb1.jar,
     @Resource(name = “java:module/env/myresource”, sharable=false)

A.class (an EJB) extends Base in ejb1.jar

Before MR we have one binding:
  A has a comp entry for “myresource”

After MR we have an error, since sharable is false?
  A binds:
     "java:module/env/myresource”
  Base binds:
     "java:module/env/myresource”?

Example 4:

Base.class (not a component) in ejb1.jar,
     @Resource(name = “myresource”, sharable=false)

M.class (a managed bean) extends Base.class

Before MR we have one binding:
  java:module/env/myresource

After MR we have an error, since sharable is false?
   M binds:
     “java:module/env/myresource”
   Base binds:
     “java:module/env/myresource”?

  
      



>
> The longer we delay some of these clarifications to the spec, the more difficult
> it's going to be to enforce them.
>
> We've tried to be flexible in cases where there's a long history of products
> not implementing the intent of the spec. For the EE.5.2.5 change, we allow
> a deployment time option to address a common source of errors. Potentially
> we could allow such an option to ignore some EE.5.2.2 errors, but allowing
> completely different non-error behavior does *not* seem like a good idea.

I agree with this in principal, at least when we are talking about obvious mistakes and the impact is manageable. In this case, I have a really hard time justifying to users why we should break their apps. Further, there may be other unintended consequences we have yet to find.
>
> If there's agreement on what the behavior *should* be, what's the advantage
> of delaying that until Java EE 8?

I think thats a valid perspective to work from, to start with figuring out what it should be. I don’t think we have MR language yet that is as complete and consistent as it needs to be. In particular the namespace handling in the examples above needs to be clarified.

>
>
> Jason Greene wrote on 02/19/2015 12:36 PM:
>> One thing that came up internally is that the language of this MR will break compatibility with existing applications:
>>
>> Section EE.5.2.2
>>
>> An environment entry declared in the application.xml descriptor or
>> by an annotation on a class in the application package other than
>> within a web module or EJB module must specify a JNDI name in the
>> java:app or java:global namespace, for example:
>> java:app/env/myString or java:global/someValue.
>>
>> Section EE.5.2.5
>> Change the text starting on line 3 on page 74 from:
>> Resource annotations may appear on any of the classes listed above,
>> or on any superclass of any class listed above.
>> to:
>> Resource annotations may appear on any class in the application package.
>>
>> One common pattern that we have seen in applications, is that they contain annotated classes in ear/lib (interceptors, common base classes etc), which are reused across multiple components. The annotations are brought into effect by extending the class, and at that point the namespace references are relative to the EE component, not to the base class. With these changes if @Resource on a class in ear/lib specifies an unqualified name, the default is comp, which doesn’t exist for ear/lib, leading to undefined results (probably a failure, but maybe an unintended, potentially conflicting, mapping to java:app). Likewise, if @Resource on a class in ear/lib uses java:module then we again end up with undefined results. If a user happened to have specified @Resource on java:global then things start to work out, unless of course sharable was false, in which case we end up with a duplicate conflicting binding and failure again.
>>
>> Another problem is third party libraries which make use of common annotations using a different facility will suddenly be processed by EE containers and this also will likely lead to failure.
>>
>> It makes sense for @DatasourceDefinition (and friends), but we should still clarify the namespace handling for classes which are not a component and/or do not have a module namespace.
>>
>> --
>> Jason T. Greene
>> WildFly Lead / JBoss EAP Platform Architect
>> JBoss, a division of Red Hat
>>

--
Jason T. Greene
WildFly Lead / JBoss EAP Platform Architect
JBoss, a division of Red Hat