views:

499

answers:

4

The question tells it all.

For the experts, is there a reason the SUN java 5 compiler accepts recursive annotations (contrary to the langspec), while the later compilers do not? I mean, what could be an argument against recursive annotations.

Edit: a recursive annotation is something like:

@Panel(layout=BorderLayout.class,
    nested={
        @Panel(region=NORTH, layout=FlowLayout.class, ...)
        @Panel(region=SOUTH, layout=FlowLayout.class, ...)
    }
)
+2  A: 

First -- I'm not sure what you mean by recursive annotations. Do you mean annotations that can contain references to other annotations of the same type? Something like

@Panel(layout=BorderLayout.class,
    nested={
        @Panel(region=NORTH, layout=FlowLayout.class, ...)
        @Panel(region=SOUTH, layout=FlowLayout.class, ...)
    }
)

(which would be an example of where I'd like to use it if it were possible...)

As for my use of custom annotations (and processors): code generation.

See http://code.google.com/p/javadude/wiki/Annotations

For example, JavaBean properties:

@Bean(
    properties={    
      @Property(name="name"),
      @Property(name="phone", bound=true),
      @Property(name="friend", type=Person.class, kind=PropertyKind.LIST)
    }
)
public class Person extends PersonGen {
    // generated superclass PersonGen will contain getters/setters
    //    field definitions, property change support...
}

or a mix-in example

package sample;

import java.util.List;

public interface IFlightAgent {
    List<IFlight> getFlight();
    void reserve(IFlight flight);
}

public interface ICarAgent {
    List<ICar> getCars();
    void reserve(ICar car);
}

public interface IHotelAgent {
    List<IHotel> getHotels();
    void reserve(IHotel hotel);
}

package sample;

import com.javadude.annotation.Bean;
import com.javadude.annotation.Delegate;

@Bean(delegates = {
    @Delegate(type = IHotelAgent.class,
              property = "hotelAgent",
              instantiateAs = HotelAgentImpl.class),
    @Delegate(type = ICarAgent.class,
              property = "carAgent",
              instantiateAs = CarAgentImpl.class),
    @Delegate(type = IFlightAgent.class,
              property = "flightAgent",
              instantiateAs = FlightAgentImpl.class)
    }
)
public class TravelAgent extends TravelAgentGen
    implements IHotelAgent, ICarAgent, IFlightAgent
{
    // generated superclass TravelAgentGen will create instances
    //   of the "instantiateAs" classes and delegate the interface
    //   methods to them
}

See http://stackoverflow.com/questions/687553/the-drawbacks-of-annotation-processing-in-java and my answer to it for some potential issues with their usage.

Scott Stanchfield
Thanks for a the compelling example of a recursive annotation. You got me exactly right. +1
Ingo
cool! I didn't know you could do that in java5... too bad they don't allow it :(
Scott Stanchfield
One can even use recursive annotations compiled with the java5 compiler in source code and compile that with the java6 compilers. It's just astonishing.
Ingo
+1  A: 

I have been using annotations recently, as it is used heavily by Oracle Weblogic Server to modify the behavior of Java Web Services. There's a full listing of the annotations they define here. In particular, I end up using their Policy annotation the most, since that's what their security model is based off of; you can see their detailed examples on their documentation page.

I've never heard of recursive annotations.

Daniel Lew
+1  A: 

I do use non-standard annotations, most usually to mark class fields as targets for a reflexive process, like caching in RPC calls, or specific initializations procedures. I never had a need for recursive annotations, however... And I think there is a potential problem with that, as annotations need to be processed at class-definition time, before standard initializers are ready... which was I think the main reason to limit Annotation contents to base types...

Varkhan
Thanks for the comment. However, surprisingly, in Sun SDK Java 5, recursive annotations work just fine. What is even more surprising, once you have compiled your recursive annotation with the Java 5 compiler, you can use them (i.e. annotate something) in source code and compile that with the Java 6!
Ingo
A: 

I don't know of any good argument against permitting recursive annotations in general, other than that certain pathological cases which you might write by accident could lead to infinite loops (during compilation or runtime) if not prohibited.

javac prohibits recursive annotation definitions simply because that is what the specification requires. What the specification should say in a future update of the JLS (say, for JDK 7) is another matter.

So please read and vote for:

http://bugs.sun.com/view_bug.do?bug_id=6264216

Jesse Glick