Topics

Platform wide guideline for build-in annotation literals?

Arjan Tijms
 

Hi,

CDI 2.0 introduced a number of very convenient build-in annotation literals, for many of the annotations it owns and for some it doesn't own (JSR 330).

See: http://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#built_in_annotation_literals

I think something like this would be a prime candidate for an umbrella spec guideline so:

1. All specs do this for their relevant annotations (e.g. @Transactional in JTA, @ViewScoped in JSF, @RememberMe in Security, @Named in AtInject, etc)
2. All specs do this in a consistent way

Thoughts?

Kind regards,
Arjan Tijms

Michael Remijan
 

I'd say if there is an umbrella spec with these kinds of annotations then then it must be a requirement for the other specs to implement them.  Otherwise, leave the annotations within the individual specs so that it's more clear that the annotation only applies to code in that spec.  Once you move it to an umbrella spec, I'd just naturally assume it's able to be used anywhere.



On Tuesday, September 19, 2017, 6:45:08 AM CDT, Arjan Tijms <arjan.tijms@...> wrote:


Hi,

CDI 2.0 introduced a number of very convenient build-in annotation literals, for many of the annotations it owns and for some it doesn't own (JSR 330).

See: http://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#built_in_annotation_literals

I think something like this would be a prime candidate for an umbrella spec guideline so:

1. All specs do this for their relevant annotations (e.g. @Transactional in JTA, @ViewScoped in JSF, @RememberMe in Security, @Named in AtInject, etc)
2. All specs do this in a consistent way

Thoughts?

Kind regards,
Arjan Tijms

Arjan Tijms
 

Sorry, that's not what I meant ;)

What I meant was that each annotation should of course stay within their respective spec. I.e. @Transactional should of course stay in JTA.

But the annotation literal support should be somewhat mandated by the umbrella spec, so that all specs provide those for their annotations (where applicable) and all specs do it in the same way.

For instance, CDI now has:

RequestScoped requestScopedLiteral = RequestScoped.Literal.INSTANCE;

So JSF should get:

ViewScoped viewScopedLiteral = ViewScoped.Literal.INSTANCE;

And not say:

ViewScoped viewScopedLiteral = ViewScoped.getAnnotation();

or 

ViewScoped viewScopedLiteral = ViewScoped.of(ViewScoped.class);

or ...

ViewScoped should of course stay within JSF and nothing should ever move to the umbrella spec. The umbrella spec should only establish a rule saying that annotation literals are to be done via [annotation class].Literal.INSTANCE;

Hope it's more clear now ;)

Kind regards,
Arjan Tijms

 

Bill Shannon
 

The CDI expert group didn't raise this at the platform level, and they didn't even do this consistently for their annotations, so I'm not clear on what their intent is with these annotation instances.  How would applications use them?  If there's a reason applications need to be able to create annotation instances, wouldn't it be better if it worked the same whether or not the annotation has members?  Maybe this really belongs in the JDK...

Arjan Tijms wrote on 9/19/17 9:00 AM:

Sorry, that's not what I meant ;)

What I meant was that each annotation should of course stay within their respective spec. I.e. @Transactional should of course stay in JTA.

But the annotation literal support should be somewhat mandated by the umbrella spec, so that all specs provide those for their annotations (where applicable) and all specs do it in the same way.

For instance, CDI now has:

RequestScoped requestScopedLiteral = RequestScoped.Literal.INSTANCE;

So JSF should get:

ViewScoped viewScopedLiteral = ViewScoped.Literal.INSTANCE;

And not say:

ViewScoped viewScopedLiteral = ViewScoped.getAnnotation();

or 

ViewScoped viewScopedLiteral = ViewScoped.of(ViewScoped.class);

or ...

ViewScoped should of course stay within JSF and nothing should ever move to the umbrella spec. The umbrella spec should only establish a rule saying that annotation literals are to be done via [annotation class].Literal.INSTANCE;

Hope it's more clear now ;)

Kind regards,
Arjan Tijms

 


Arjan Tijms
 

On Tue, Sep 19, 2017 at 12:09 pm, Bill Shannon wrote:
The CDI expert group didn't raise this at the platform level, and they didn't even do this consistently for their annotations
I'm not sure if there's any inconsistency, other than creating literals for the JSR 330 spec and including them in 299. Or is that what you're referring to?


, so I'm not clear on what their intent is with these annotation instances.  How would applications use them?
They're mostly used for the various builders that CDI has for dynamically adding annotations to beans. CDI already has a helper class for that that makes it somewhat easier (https://docs.jboss.org/cdi/api/2.0/javax/enterprise/util/AnnotationLiteral.html), but even with the helper class it's still a bit verbose.

For a practical example see: http://arjan-tijms.omnifaces.org/2017/08/dynamically-adding-interceptor-to-build.html

It's also used for lookups, as in this code:

myGreetings.select(NamedLiteral.of("northern")).get();

For the full context see: https://github.com/javaee-samples/javaee8-samples/blob/master/cdi/qualified-lookup/src/test/java/org/javaee8/cdi/qualified/lookup/QualifiedLookupTest.java#L41

In that latter example a bean is selected that has the @Named("northern") annotation applied to it.

If there's a reason applications need to be able to create annotation instances, wouldn't it be better if it worked the same whether or not the annotation has members? 
Perhaps, but without members the annotation instance is a totally static singleton, like enum values basically. With members this is obviously not the case.

Maybe this really belongs in the JDK...
Possibly indeed, but not sure how feasible it is to get that in.

For now Java EE support throughout all applicable specs (basically the specs that already leverage CDI) isn't that hard at all. Had I learned about this annotation literals a tiny bit earlier I could have added them trivially to JSF and Java EE security (if the spec lead and EG would have agreed, of course).

Kind regards,
Arjan Tijms







Arjan Tijms wrote on 9/19/17 9:00 AM:

Sorry, that's not what I meant ;)

What I meant was that each annotation should of course stay within their respective spec. I.e. @Transactional should of course stay in JTA.

But the annotation literal support should be somewhat mandated by the umbrella spec, so that all specs provide those for their annotations (where applicable) and all specs do it in the same way.

For instance, CDI now has:

RequestScoped requestScopedLiteral = RequestScoped.Literal.INSTANCE;

So JSF should get:

ViewScoped viewScopedLiteral = ViewScoped.Literal.INSTANCE;

And not say:

ViewScoped viewScopedLiteral = ViewScoped.getAnnotation();

or 

ViewScoped viewScopedLiteral = ViewScoped.of(ViewScoped.class);

or ...

ViewScoped should of course stay within JSF and nothing should ever move to the umbrella spec. The umbrella spec should only establish a rule saying that annotation literals are to be done via [annotation class].Literal.INSTANCE;

Hope it's more clear now ;)

Kind regards,
Arjan Tijms

 

Bill Shannon
 

Arjan Tijms wrote on 09/19/17 01:29 PM:
On Tue, Sep 19, 2017 at 12:09 pm, Bill Shannon wrote:
The CDI expert group didn't raise this at the platform level, and they didn't even do this consistently for their annotations
I'm not sure if there's any inconsistency, other than creating literals for the JSR 330 spec and including them in 299. Or is that what you're referring to?
Some of the annotations have literals and some do not.  There may be some rationale for why only some of the annotations need literals, but it wasn't explained.


, so I'm not clear on what their intent is with these annotation instances.  How would applications use them?
They're mostly used for the various builders that CDI has for dynamically adding annotations to beans. CDI already has a helper class for that that makes it somewhat easier (https://docs.jboss.org/cdi/api/2.0/javax/enterprise/util/AnnotationLiteral.html), but even with the helper class it's still a bit verbose.

For a practical example see: http://arjan-tijms.omnifaces.org/2017/08/dynamically-adding-interceptor-to-build.html

It's also used for lookups, as in this code:

myGreetings.select(NamedLiteral.of("northern")).get();

For the full context see: https://github.com/javaee-samples/javaee8-samples/blob/master/cdi/qualified-lookup/src/test/java/org/javaee8/cdi/qualified/lookup/QualifiedLookupTest.java#L41

In that latter example a bean is selected that has the @Named("northern") annotation applied to it.
Hopefully this is very much an advanced case and not something that typical applications will need to do.

If there's a reason applications need to be able to create annotation instances, wouldn't it be better if it worked the same whether or not the annotation has members? 
Perhaps, but without members the annotation instance is a totally static singleton, like enum values basically. With members this is obviously not the case.
If an annotation evolves to have members, would you still want a static instance?  Wouldn't it be simpler if there was always just one way to get an instance?

Maybe this really belongs in the JDK...
Possibly indeed, but not sure how feasible it is to get that in.

For now Java EE support throughout all applicable specs (basically the specs that already leverage CDI) isn't that hard at all. Had I learned about this annotation literals a tiny bit earlier I could have added them trivially to JSF and Java EE security (if the spec lead and EG would have agreed, of course).
Depending on each spec to do it means that some won't.

This is not the first thing about annotations that we wished every spec would handle.  I really wish we could push more of this into the JDK, or find a way to centralize all of this in a place that would apply to all Java EE uses of annotations automatically.

Lacking that, a "design pattern" as you suggest might be the best approach.  Another item for the future Eclipse project to address!  :-)