The drawbacks of annotation processing in Java?

前端 未结 3 2052
猫巷女王i
猫巷女王i 2021-01-30 02:21

I am considering starting a project which is used to generate code in Java using annotations (I won\'t get into specifics, as it\'s not really relevant). I am wondering about th

相关标签:
3条回答
  • 2021-01-30 03:00

    I think if annotation processor then definitely use the Java 6 version of the API. That is the one which will be supported in the future. The Java 5 API was still in the in the non official com.sun.xyz namespace.

    I think we will see a lot more uses of the annotation processor API in the near future. For example Hibernate is developing a processor for the new JPA 2 query related static meta model functionality. They are also developing a processor for validating Bean Validation annotations. So annotation processing is here to stay.

    Tool integration is ok. The latest versions of the mainstream IDEs contain options to configure the annotation processors and integrate them into the build process. The main stream build tools also support annotation processing where maven can still cause some grief.

    Testing I find a big problem though. All tests are indirect and somehow verify the end result of the annotation processing. I cannot write any simple unit tests which just assert simple methods working on TypeMirrors or other reflection based classes. The problem is that one cannot instantiate these type of classes outside the processors compilation cycle. I don't think that Sun had really testability in mind when designing the API.

    0 讨论(0)
  • 2021-01-30 03:00

    One specific which would be helpful in answering the question would be as opposed to what? Not doing the project, or doing it not using annotations? And if not using annotations, what are the alternatives?

    Personally, I find excessive annotations unreadable, and many times too inflexible. Take a look at this for one method on a web service to implement a vendor required WSDL:

        @WebMethod(action=QBWSBean.NS+"receiveResponseXML")
    @WebResult(name="receiveResponseXML"+result,targetNamespace = QBWSBean.NS)
    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public int receiveResponseXML(
            @WebParam(name = "ticket",targetNamespace = QBWSBean.NS) String ticket,
            @WebParam(name = "response",targetNamespace = QBWSBean.NS) String response,
            @WebParam(name = "hresult",targetNamespace = QBWSBean.NS) String hresult,
            @WebParam(name = "message",targetNamespace = QBWSBean.NS) String message) {
    

    I find that code highly unreadable. An XML configuration alternative isn't necessarily better, though.

    0 讨论(0)
  • 2021-01-30 03:12

    I've created a set of JavaBean annotations (http://code.google.com/p/javadude/wiki/Annotations)

    [Note: I'm working on a new version right now, so the trunk code doesn't match the update site downloads]

    Testing

    Testing them can be quite trying...

    I usually approach it by creating a project in eclipse with the test code and building it, then make a copy and turn off annotation processing.

    I can then use Eclipse to compare the "active" test project to the "expected" copy of the project.

    I don't have too many test cases yet (it's very tedious to generate so many combinations of attributes), but this is helping.

    Build System

    Using annotations in a build system is actually very easy. Take a look at http://code.google.com/p/javadude/wiki/Annotations for an example of how it's used in an ant script, and using it in eclipse is just a matter of making a plugin specifying the annotation processor extension and turning on annotation processing in projects that want to use it.

    I've used annotation processing in a continuous build environment, building the annotations & processor, then using it in the rest of the build. It's really pretty painless.

    Processing Time

    I haven't found this to be an issue - be careful of what you do in the processors. I generate a lot of code in mine and it runs fine. It's a little slower in ant.

    Note that Java6 processors can run a little faster because they are part of the normal compilation process. However, I've had trouble getting them to work properly in a code generation capacity (I think much of the problem is eclipse's support and running multiple-phase compiles). For now, I stick with Java 5.

    Error Processing

    This is one of the best-thought-through things in the annotation API. The API has a "messenger" object that handles all errors. Each IDE provides an implementation that converts this into appropriate error messages at the right location in the code.

    The only eclipse-specific thing I did was to cast the processing environment object so I could check if it was bring run as a build or for editor reconciliation. If editing, I exit. Eventually I'll change this to just do error checking at edit time so it can report errors as you type. Be careful, though -- you need to keep it really fast for use during reconciliation or editing gets sluggish.

    Code Generation Gotcha

    [added a little more per comments]

    The annotation processor specifications state that you are not allowed to modify the class that contains the annotation. I suspect this is to simplify the processing (further rounds do not need to include the annotated classes, preventing infinite update loops as well)

    You can generate other classes, however, and they recommend that approach.

    I generate a superclass for all of the get/set methods and anything else I need to generate. I also have the processor verify that the annotated class extends the generated class. For example:

    @Bean(...)
    public class Foo extends FooGen
    

    I generate a class in the same package with the name of the annotated class plus "Gen" and verify that the annotated class is declared to extend it.

    I have seen someone use the compiler tree api to modify the annotated class -- this is against spec and I suspect they'll plug that hole at some point so it won't work.

    I would recommend generating a superclass.

    Overall

    I'm really happy using annotation processors. Very well designed, especially looking at IDE/command-line build independence.

    For now, I would recommend sticking with the Java5 annotation processors if you're doing code generation - you need to run a separate tool called apt to process them, then do the compilation.

    Note that the API for Java 5 and Java 6 annotation processors is different! The Java 6 processing API is better IMHO, but I just haven't had luck with java 6 processors doing what I need yet.

    When Java 7 comes out I'll give the new processing approach another shot.

    Feel free to email me if you have questions. (scott@javadude.com)

    Hope this helps!

    0 讨论(0)
提交回复
热议问题