Skip to content
This repository was archived by the owner on Jan 30, 2019. It is now read-only.

Commit d4c2df2

Browse files
committed
test
1 parent 3aab377 commit d4c2df2

22 files changed

+1856
-790
lines changed

AnnotationRules.md

Lines changed: 368 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,368 @@
1+
# DRAFT Annotation Rules
2+
3+
This is a collection of rules for how annotations should work.
4+
Some of these duplicate what's in the specs (in particular,
5+
the platform spec and the Common Annotations spec).
6+
You can consider these to be rules about how annotations
7+
currently work, as well as rules about how new annotations
8+
should be designed to work to be consistent with current
9+
annotations. Of course, there are exceptions, called out below.
10+
11+
12+
13+
### Annotations and inheritance
14+
15+
This section describes how annotations interact with inheritance.
16+
Note that, in general, we do not use the @Inherited annotation
17+
on our annotations. @Inherited only applies to annotations at
18+
the class level. If multiple classes in a hierarchy are annotated
19+
with an @Inherited annotation, only the annotation furthest from
20+
the base class is returned. For resource annotations, we want
21+
all such annotations to apply, so @Inherited would give the wrong
22+
results. For component-defining annotations, we don't want the
23+
fact that a superclass is a component to cause all subclasses to
24+
be components, so we don't use @Inherited for component-defining
25+
annotations.
26+
27+
Some frameworks have defined additional annotations that specify
28+
how **their** annotations behave with regard to inheritance.
29+
For example, see the JPA @Inheritance and @DiscriminatorColumn
30+
annotations.
31+
32+
Note that CDI is an exception to this, and recommends that scopes and interceptor bindings are declared @Inherited. It also recommends that stereotypes may be @Inherited depending on their intended usage. It recommends that qualifiers are not declared @Inherited.
33+
##### General rules
34+
35+
A resource annotation (@Resource, @EJB, etc.) on a superclass
36+
is **not** overridden by a similar annotation on a subclass.
37+
38+
In general, annotations on interfaces are ignored.
39+
40+
A method-level annotation on a superclass method is ignored if the
41+
subclass overrides the method; only annotations on the subclass
42+
method apply.
43+
44+
Since a class always "overrides" methods in an interface, annotations on
45+
the interface method are ignored.
46+
47+
A method-level annotation on a superclass method or field that is **not**
48+
overridden "shows through" and still applies. (Note that it is not possible
49+
to override a field.)
50+
51+
A method-level annotation on a private superclass method or field remains
52+
in effect.
53+
54+
##### Exceptions
55+
56+
JAX-RS allows per-method annotations on the methods of an interface.
57+
If the implementing class doesn't declare **any** JAX-RS annotations
58+
on a method (other annotations are allowed), the JAX-RS annotations
59+
on the interface's method apply. Any JAX-RS annotation on a method
60+
overrides **all** JAX-RS annotations on the corresponding interface method.
61+
62+
JAX-RS defines a similar rule for annotations on methods of a superclass,
63+
again violating the general rule above. If a subclass overrides a method
64+
but does not include any JAX-RS annotations on the method declaration, the
65+
JAX-RS annotations from the superclass apply.
66+
67+
>XXX - what happens if the class implements multiple interfaces with the same method but different annotations?
68+
>Santiago - The spec is mute about this case. It does say that annotations from superclasses take precedence over annotations in implemented interfaces.
69+
70+
In some cases, an annotation on a method will "show through" to subclasses
71+
that override the method. Since this prevents the normal approach of
72+
"disabling" the annotation by omitting it, the annotation will need an
73+
attribute that undoes its normal effect. For example, JAX-WS has
74+
@WebMethod(exclude=true) and Connectors has @ConfigProprty(ignore=true).
75+
Generally this style is discouraged.
76+
77+
EJB allows the @Local and @Remote annotations to appear on interfaces.
78+
79+
The JPA annotations @Table, @SecondaryTable, and @SecondaryTables
80+
interact with the @Inheritance annotation to control how they behave
81+
with respect to inheritance.
82+
83+
CDI producer fields or methods are not inherited by subclasses, even if they
84+
are not overridden. The superclass would not know how to produce an
85+
instance of the subclass.
86+
87+
CDI introduces specialization, which affects inheritance. If a subclass is defined @Specializes, then
88+
89+
* all qualifiers are inherited, regardless of whether they are declared @Inherited
90+
* the EL name of the bean is inherited (@Named is not declared @Inherited)
91+
92+
93+
The following component-defining annotations do have @Inherited on them due to historical accident. In common usage, these annotations are not involved in inheritance hierarchies so it was decided to leave them in a state of non-compliance with these rules rather than risk introducing unforeseen problems.
94+
95+
* javax.faces.validator.FacesValidator
96+
* javax.faces.view.facelets.FaceletsResourceResolver
97+
* javax.faces.render.FacesBehaviorRenderer
98+
* javax.faces.render.FacesRenderer
99+
* javax.faces.convert.FacesConverter
100+
* javax.faces.component.behavior.FacesBehavior
101+
* javax.faces.component.FacesComponent
102+
103+
104+
105+
### @Documented
106+
107+
Many annotations are used to effect the implementation of a class.
108+
For example, the Resource annotations define resources that are
109+
used by the implementation of the class. The resources used by a
110+
class are rarely part of the API specification of the class.
111+
112+
In some cases, annotations add to the API specification of a class,
113+
and contain important information that a user of the class will need
114+
to know. Annotations of this sort should be marked with @Documented;
115+
these annotations will then appear in the javadoc for the class.
116+
117+
> XXX - We haven't done a good job of applying @Documented to our annotations. We need to reconsider this issue.
118+
119+
All CDI annotations are marked @Documented.
120+
121+
### Component-defining annotations
122+
123+
A component-defining annotation (e.g., @Stateless, @WebService) on a
124+
superclass does not apply to a subclass.
125+
126+
A component-defining annotation (e.g., @Stateless, @WebService) on an
127+
interface does not apply to a class that implements the interface.
128+
(This is an instance of the general rule that annotations on interfaces
129+
are ignored.)
130+
131+
132+
133+
### Class vs. method annotations
134+
135+
##### General rules
136+
137+
Class level annotations that effect the semantics of the class
138+
are local to the defining class.
139+
These class level annotations are a shorthand for annotating
140+
methods defined in that class. Class level annotations
141+
play no direct role in inheritance unless the annotation
142+
is marked @Inherited. See above for why we don't use
143+
@Inherited for annotations that need to combine, although
144+
it is useful for annotations that simply need to override
145+
the same annotation in a superclass (e.g., @ServletSecurity).
146+
147+
After the effect of class level annotations is considered
148+
for each class, the methods defined on that class end up
149+
with attributes that are a result of a direct annotation
150+
or a result of applying the class level annotation.
151+
152+
When a subclass overrides a method, none of the attributes
153+
of the superclass method apply. When a subclass does not
154+
override a method, the attributes of the method are the
155+
effective attributes for the method from the parent class.
156+
157+
A method default rule such as "all public methods are web
158+
service methods" acts as an implicit class level annotation.
159+
160+
Some class level annotations don't effect the semantics of
161+
the class, but are just attached to some class "for convenience".
162+
For example, @Resource doesn't effect the semantics of the class.
163+
Many JPA annotations don't effect the specific class they're
164+
attached to, but instead effect the persistence unit the class
165+
is a part of.
166+
167+
##### Exceptions
168+
169+
In some cases, annotations on subclass and superclass methods
170+
"combine". For example, the interceptor annotations on superclass
171+
methods apply even if the subclass overrides the method and provides
172+
its own interceptor annotations. The interceptors from both the
173+
superclass and the subclass are invoked, from superclass down to
174+
subclass.
175+
176+
##### Package level annotations
177+
178+
We've made very little use of package level annotations in Java EE.
179+
Where they are used, they effectively act as another level of defaulting
180+
above classes. That is, package level annotations are overridden by
181+
class level annotations, which in turn are overridden by method level
182+
annotations.
183+
184+
For annotations that can be used at the class level and at the package
185+
level, the implementation should look for the annotation on the class
186+
first [XXX - possibly following the superclass hierarchy if the annotation is not
187+
marked @Inherited]. If the annotation isn't found, the implementation
188+
should look for the annotation on the package for the class [XXX - possibly
189+
following the superclass hierarchy and considering the package for each
190+
superclass if the annotation isn't marked @Inherited].
191+
192+
JAXB uses package level annotations in this way.
193+
194+
> XXX - It's unclear what the inheritance rules for package level annotations should be.
195+
196+
197+
198+
### Annotations vs. deployment descriptors
199+
200+
In general, information in deployment descriptors should override
201+
information in annotations. In some cases, the information combines,
202+
such as for injection target specifications or for interceptors.
203+
In rare cases, an annotation can override a deployment descriptor entry;
204+
see the web fragments section below.
205+
206+
From (the proposed update to) the Java EE platform spec:
207+
208+
The following list describes the rules for how a deployment
209+
descriptor entry may override a Resource annotation.
210+
211+
- The relevant deployment descriptor entry is located based on
212+
the JNDI name used with the annotation (either defaulted or
213+
provided explicitly).
214+
215+
- The type specified in the deployment descriptor must be
216+
assignable to the type of the field or property.
217+
218+
- The description, if specified, overrides the description
219+
element of the annotation.
220+
221+
- The injection target, if specified, defines additional
222+
injection points for the resource.
223+
224+
- The mapped-name element, if specified, overrides the
225+
mappedName element of the annotation.
226+
227+
- The res-sharing-scope element, if specified, overrides the
228+
shareable element of the annotation. In general, the
229+
Application Assembler or Deployer should not change this
230+
value as doing so is likely to break the application.
231+
232+
- The res-auth element, if specified, overrides the
233+
authenticationType element of the annotation. In general, the
234+
Application Assembler or Deployer should not change this
235+
value as doing so is likely to break the application.
236+
237+
- The lookup-name element, if specified, overrides the lookup
238+
element of the annotation
239+
240+
It is an error to request injection of two resources into the
241+
same target. The behavior of an application that does so is
242+
undefined.
243+
244+
245+
246+
### Web fragment descriptors vs web.xml and annotations
247+
248+
An ejb-jar.xml in a war file is treated the same as a web-fragment.xml
249+
in terms of the interaction with web.xml for resources.
250+
251+
A Resource entry in a web fragment descriptor overrides annotations
252+
**only in the corresponding library**, using the rules above.
253+
254+
A Resource entry in a web.xml file overrides **all** attributes of any
255+
corresponding Resource entry in a web fragment descriptor, **except**
256+
for the injection targets, which are combined.
257+
258+
A Resource entry in a web.xml file overrides a Resource annotation on a
259+
class in WEB-INF/classes using the rules above.
260+
261+
A Resource annotation on a class in WEB-INF/classes overrides **all**
262+
attributes of any corresponding Resource entry in a web fragment descriptor.
263+
**This may be the only place where an annotation overrides a deployment
264+
descriptor entry.**
265+
266+
267+
268+
### Repeated annotations
269+
270+
In some cases it's desirable to allow a particular annotation to
271+
occur multiple times on a single element, usually with different
272+
parameters. The convention for allowing @SomeAnnotation to be
273+
repeated is to define a pluralized version of the annotation:
274+
275+
```java
276+
public @interface SomeAnnotations {
277+
SomeAnnotation[] value();
278+
}
279+
```
280+
281+
Used as:
282+
283+
```java
284+
@SomeAnnotations({
285+
@SomeAnnotation("value1"),
286+
@SomeAnnotation("value2")
287+
})
288+
public class MyClass { ... }
289+
```
290+
291+
We're hoping that Java SE 8 will support this style more directly
292+
in the compiler, allowing:
293+
294+
```java
295+
@SomeAnnotation("value1")
296+
@SomeAnnotation("value2")
297+
public class MyClass { ... }
298+
```
299+
300+
301+
302+
### Annotations vs. interfaces
303+
304+
In some cases we use annotations to mark which classes and which methods
305+
should be used by the container for which purposes, and in other cases we
306+
specify this interface with a Java language interface. The following rules are
307+
used to choose which to use when:
308+
309+
1. When defining an API that an application is going to implement and
310+
the container is going to call, use an interface, unless one of the
311+
following rules applies.
312+
2. If an application class is providing an API that's exposed to other
313+
applications, and that class also needs to provide methods that the
314+
container will call for lifecycle functions (or other container support
315+
or management functions), use an annotation to mark those methods so
316+
that the application has flexibility in the choice of names for those
317+
methods.
318+
3. If an application is going to expose an interface that another
319+
application (or user) is going to use **without** Java, use annotations
320+
to mark the methods that correspond to this interface. This avoids the
321+
need to define a Java interface that's never going to be used by anyone
322+
other than the one class implementing the interface.
323+
4. If there can be more than one occurrence of a method for a given
324+
purpose, use an annotation.
325+
5. If an interface is chosen and the interface has many methods,
326+
consider providing an "adapter" class that implements all the methods
327+
with nop implementations. Applications can then subclass this adapter
328+
class to avoid the need to implement all methods. It's often better to
329+
decompose the interface into multiple smaller interfaces.
330+
331+
332+
### Annotation Style
333+
334+
Use correct types instead of strings for annotation attributes when possible.
335+
336+
> XXX - Need guidance on use of Class vs. String for class names
337+
338+
For optional attributes, prefer these default values:
339+
* String - ""
340+
* int - -1
341+
* Class - void.class
342+
* [] - \{ }
343+
344+
Use enumerated types rather than magic String values when the set of
345+
possible options is finite and fairly small.
346+
347+
Avoid nesting annotations more than one level.
348+
349+
Rather than adding more and more different aspects to an annotation,
350+
try to separate the concerns by creating different annotations that
351+
may be applied together or independently.
352+
353+
Use "value()" as the element name in an annotation that only has one
354+
element or if, when using the annotation, that one element is the
355+
one most commonly specified.
356+
357+
358+
359+
### Open Issues
360+
361+
362+
Need to check JAXB annotations.
363+
364+
Need to write up something that describes when it's appropriate to only
365+
add an annotation, or only add a deployment descriptor entry, vs. having
366+
both.
367+
368+

0 commit comments

Comments
 (0)