Skip to main content

[javaee-spec users] [jsr342-experts] Re: annotations vs. interfaces

  • From: Pete Muir <pmuir@...>
  • To: jsr342-experts@...
  • Cc: Kevin Conner <kconner@...>
  • Subject: [javaee-spec users] [jsr342-experts] Re: annotations vs. interfaces
  • Date: Fri, 5 Oct 2012 12:55:59 -0700
  • List-id: <jsr342-experts.javaee-spec.java.net>


On 4 Oct 2012, at 15:36, Bill Shannon wrote:

> Earlier this year I wrote up a bunch of our "rules" for how annotations
> should work: http://java.net/projects/javaee-spec/pages/AnnotationRules
> 
> While reviewing the Batch spec:
> http://download.oracle.com/otndocs/jcp/batch-1_0-edr-spec/index.html
> I noticed that they were using annotations in places that I expected
> to see interfaces.
> 
> For example, they allow a class to be a "listener" for events, and they
> declare that the class is a listener by annotating the class.  To indicate
> which method of the class should be called when the event occurs, they
> annotate the method.  The different events are a finite and fixed set,
> and each type of listener handles only a few events associated with that
> type.  You might have:
> 
> @JobListener
> public class MyJobListener {
>   @JobStarted
>   public void jobStarted() { ... }
>   @JobFinished
>   public void jobFinished() { ... }
> }
> 
> To me, this just felt like an abuse of annotations in a place where a
> listener interface is a widely used and well understood approach.
> Why would you not simply do:
> 
> public interface JobListener {
>   public void jobStarted();
>   public void jobFinished();
> }
> 
> public class MyJobListener implements JobListener {
>   public void jobStarted() { ... }
>   public void jobFinished() { ... }
> }
> 
> Of course, you'll want an annotation on MyJobListener to configure
> the listener and associate it with a specific job.  (You don't want
> a class to be used just because it's been declared.)

We agree entirely with this specific example. Kev (our batch EG rep) and I 
have recently discussed this exact point about the Batch Draft, and I know he 
took that feedback to the Batch EG.

> 
> It seemed like it would be worth writing down some general principles
> as an update to my annotation rules page above.  Here's what I have so
> far, but I'd love your feedback.  Of course, it's likely that we haven't
> followed a consistent set of rules for things we've already done, so there
> will always be exceptions.  Let me know if you agree with the following,
> and especially let me know of any additions.
> 
> 
> - When defining an API that an application is going to implement and
> the container is going to call, use an interface.

Agreed. A classic example of where we got this wrong is method 
interceptors/around invoke - it's a nightmare to remember the correct 
signature for around invoke methods (lifecycle callbacks defined on 
interceptors have the same issue).

> 
> - To configure the container to use a particular implementation of such
> an interface in a particular situation, use an annotation.

+1

> 
> - If an application class is providing an API that's exposed to other
> applications, and that class also needs to provide methods that the
> container will call for lifecycle functions, use an annotation to
> mark those methods so that the application has flexibility in the
> choice of names for those methods.
> 
> - If an application is going to expose an interface that another
> application (or user) is going to use *without* Java, use annotations
> to mark the methods that correspond to this interface.  This avoids
> the need to define a Java interface that's never going to be used by
> anyone other than the one class implementing the interface.

I think there is also something to be said around whether you are going to 
use the functionality in your business classes (your POJO model) or whether 
you are going to do this in a separate class. For example, to go back to 
interceptors, whilst lifecycle callbacks defined on interceptor classes would 
probably be better done as an interface implementation, lifecycle callbacks 
defined on beans clearly need to declared using annotations.

I think there is also something to be said for addressing how the 
functionality is used:

1) If there must be exactly one occurrence of every method defined on the 
implementation class, then an interface is best
2) If some (but not all) methods are optional to implement, then perhaps an 
abstract class is best (not sure, annotations might be best here as well).
3) If you can have none, one or more occurrences of a method, then 
annotations are best



[javaee-spec users] [jsr342-experts] annotations vs. interfaces

Bill Shannon 10/04/2012

[javaee-spec users] [jsr342-experts] Re: annotations vs. interfaces

Jeff Genender 10/04/2012

[javaee-spec users] [jsr342-experts] Re: annotations vs. interfaces

Florent BENOIT 10/08/2012

[javaee-spec users] [jsr342-experts] Re: annotations vs. interfaces

Pete Muir 10/10/2012

[javaee-spec users] [jsr342-experts] Re: annotations vs. interfaces

Pete Muir 10/08/2012

[javaee-spec users] [jsr342-experts] Re: annotations vs. interfaces

Bill Shannon 10/09/2012

[javaee-spec users] [jsr342-experts] Re: annotations vs. interfaces

Pete Muir 10/10/2012
 
 
Close
loading
Please Confirm
Close