28

I may be just looking in the wrong direction but I find the JSE documentation on annotation processing very ... sparse. I want to write an annotation processor which processes annotated String fields and local variables to substitute them with a computed String expression. This should not be too complicated but I'm pretty lost in the Javadoc for javax.annotation.processing.

EDIT: I need to process annotations at compile time because I want to modify the generated code. It should replace annotated constant String expressions with a computed String expression.

6
  • Agreed, my entry point was this tutorial: tutorials.jenkov.com/java-reflection/annotations.html Commented Jul 8, 2012 at 18:39
  • 2
    Do you want to process annotations at compile time or runtime? Note that annotations on local variables are effectively useless due to a silly javac limitation. Commented Jul 8, 2012 at 18:43
  • I want to process them at compile time, so this would obviously only work for constant string expressions. Commented Jul 8, 2012 at 19:03
  • You might be able to use ANT's replace task, but that might depend on what "computed" means. See this post for example. Commented Jul 8, 2012 at 23:33
  • Maybe it will be useful: github.com/vbauer/jackdaw Commented Mar 22, 2015 at 14:19

3 Answers 3

16

This can not be done with a compile time annotation processor. Compile time time annotation processors can only generate new files (and classes) they can not modify existing classes. You can do reflection at runtime but strictly speaking you that is not called annotation processing. Also you won't have access to local variables.

If you're looking on how to write a compile time annotation processor check out https://github.com/pellaton/spring-configuration-validation-processor

Sign up to request clarification or add additional context in comments.

6 Comments

Theoretically, you could use an annotation processor + Apache BCEL (or something similar) to modify the original .class file. But that sounds messy.
Err... what? I cannot modify the source code before compilation using the annotation framework?
I looked at the linked code. Obviously it doesn't generate code, it just validates it. I was hoping I could modify the Abstract Syntax Tree before the actual code generation step.
I think your only options are bytecode manipulation (using e.g. ASM, BCEL) or some classpath tricks like reference to the class that is generated by the annotation processor instead to the original file or something like that...
@christian-schlichtherle Yes, you can't modify. Check out the apt documentation. "These reflective APIs provide a build-time, source-based, read-only view of program structure." "runs annotation processors that can produce new source code and other files"
|
9

Two tools that do this are Project Lombok and DuctileJ. Both of these tools existed at the time the question was originally asked; additional tools now surely exist.

The key idea is to write an annotation processor that traverses and modifies the program's AST (abstract syntax tree) during compilation, before code generation. The compiler won't change the source code on disk, but the generated .class file will reflect the changes that your annotation processor makes.

You may be able to adapt one of these tools to suit your needs, or you could implement your own tool inspired by their implementation techniques.

Compile-time processing has two advantages over class-file processing. One is that the compiler usually has more information than is available from compiled code. Another is that everything happens in one step, during compilation, rather than requiring the developer to run a separate tool to rewrite the .class files after compilation.

2 Comments

sure, and worth mentioning that both use a hack to modify the AST, exploiting a bug in the current annotation processor in Java, making use of internal javac APIs which could be fixed/removed in some future JDK (which goes down as a big disadvantage to me).
I'm sorry, but as helpful this answer might be, its statements simply are not true. The mentioned tools are not aspect processors, but compiler plugins (completely different method, not as well supported in some tools). You cannot modify AST with aspect processor -- only generate new code in new compilation units (e.g. new classes)
3

Check

2 Comments

I have looked at Javassist and ASM. Maybe they would do the job, but they are about byte code manipulation. I would very much prefer to use a tool which would allow me to manipulate the Abstract Syntax Tree. Byte code manipulation would only be my last resort.
OK, after investigating the options, it seems that byte code manipulation is the only viable option left. The next challenge is to integrate this into a Maven build - not just for me, but for the users of my library, too.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.