How to handle java annotation processor and process annotations from projectA and generate Java source files for projectB

I created a java annotation that marks some of my "utility" classes as services, and then wrote an annotation handler that generates the corresponding servicerequest and servicehandler classes. This is for a GWT maven project where service requests are sent to the server to a central dispatcher to be processed by various services.

My maven project consists of a parent project and 5 submodule projects.

The project structure looks something like this:

  • MoodleMobile (parent maven project)
    • gwtMoodleWS (GWT layer)
    • moodleBuildSupport (contains an annotation processor)
    • moodleGeneratedServiceHandlers (desired location of the generated classes)
    • moodleWS (server layer)
    • moodleWSAPI (The location of the code where the annotation processor will run)

My question is this.

What is the prescribed way to read and process annotations from one project (moodleWSAPI) and generate java source files in another project (moodleGeneratedServiceHandlers)?

It seems to me that a lot of annotation processor examples create java source files for the same project that the annotation processor is running on, but not for another project.

I have successfully built and tested my annotation processor but cannot figure out how to get it to create files outside of the project the processor is running in. It is currently generating java source files in moodleWSAPI (this is wrong). I want it to process the source files in moodleWSAPI and then output the new generated source files to moodleGeneratedServiceHandlers.

Here is the code snippet that should create the actual java source file.

    public void createSourceFileFromTemplate(Template template, ClassSignature classSignature, VelocityContext context, Element element) {
        PrintWriter pw = null;
        try {
            JavaFileObject sourceFile =  processingEnv.getFiler().createSourceFile(classSignature.getFullName(), classSignature.getElement());
            OutputStream fileStream = sourceFile.openOutputStream();
            pw = new PrintWriter(fileStream);
            template.merge(context, pw);
        } catch (Exception e) {
            e.printStackTrace();
            if (element!=null) {
               processingEnv.getMessager().printMessage(Kind.ERROR, e.getMessage(),element);
            } else {
                processingEnv.getMessager().printMessage(Kind.ERROR, e.getMessage());
            }
        } finally {
            if (pw!=null) {
                pw.close();
            }
        }
    }

      

Please note, ClassSignature is just my custom class which I am using to capture the class name. I am using Velocity as my templating engine to create an actual java source.

I don't see anything in the processingEnv.getFiler () spec that allows me to specify output outside of the project.

I could go the route without using processEnv.getFiler (). createSourceFile (..) and just create java source files using a simple java IO file. It would be trivially easy to do, but I'm trying to line up, so to speak, and fulfill my needs in a prescribed manner. Any ideas?

+3


source to share


1 answer


I don't think there is any specific API for creating files for use in other projects. As far as the processor (or even Java in general) is concerned, there are no such things as "projects" - only the input and output paths provided to the compiler are known.

Using Filer and StandardLocation helps with processor portability and eliminates the worry of the development environment directory structure. If the processor will only be used in this one project, this portability is not required and should not be harmful when using a direct io file, since you know exactly how your modules are structured.



To make this a little more idiomatic, you can pass the locations of other project source directories as compiler options to the annotation processor with -Akey[=value]

. This will at least lead to an assumption about the structure of other projects from your code and shift the responsibility for maintaining those paths to the build tool. Maven knows better how all projects are structured, so I think this would be a good solution.

+4


source







All Articles