79647798

Date: 2025-06-01 18:08:24
Score: 0.5
Natty:
Report link

Not sure this is a clean solution, but at least it is working.

Step one

make sure the annotation processing module has access to the com.sun.tools.javac.tree package by adding a add-exports command to JDK. In maven this is done by adding the following section in the maven-compiler-plugin config section:

<compilerArgs>
   <arg>--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED</arg>
</compilerArgs>

If you are using an other build system, you can for sure find a way to pass this parameter to javac.

Step two

Make sure that the annotation processor "opens" the neccesary modules on runtime. To do this, I followed the same approach that lombok does here. Please note that I had to also copy much of the permit package.

Step three

Once acess to com.sun.tools.javac.tree is ensured, you can cast the public interface types from com.sun.source.tree to their actual implementation from com.sun.tools.javac.tree and gain access to the write operations. Strangely, this is not done through setters, but access to public fields. Not super consistent to java standards, but at least it is possible :)

For example, I casted LiteralTree -> JCTree.JCLiteral and swap my booleans (was the goal of my POC) like that:

if (tree instanceof JCTree.JCLiteral casted && casted.getKind() == Tree.Kind.BOOLEAN_LITERAL) {
    casted.value = Objects.equals(casted.value, 1)? 0 : 1;
}

Huge thanks to @slaw for pointing out the lombok code responsible for opening the packages. You should definately get the credit for this solution. Feel free to copy-paste this in its entirety or parts of it and I will mark it as accepted answer.

Opinion alert

Finally, I just wanted to note that am surprised that the public API "normaly" available to annotation processors do not allow AST modifications. They only provide read-access (probably useful for compile-time validations) and the ability to generate new files, but not to modify existing ones.

So, heavily hacking java9 modules and gain access to private packages seems to be the only way to go at the moment. This is at least what lombok does, and the only solution I found. I find this sad.

If AST modifications should not be allowed (for security or whatever), then there should be no "backdoor" to do so, and thus, lombok should not exist at all. Of course, this would be a massive hit to java's usability and popularity.

If on the other hand, AST modifications should be allowed (count my vote here), then there should be a clear, open, and documented API to do so. One should not need to hack their way through, by using sun.misc.Unsafe to open private packages. This is simply a messy and sad way to do things.

Reasons:
  • Blacklisted phrase (0.5): thanks
  • Long answer (-1):
  • Has code block (-0.5):
  • User mentioned (1): @slaw
  • Self-answer (0.5):
Posted by: Alkis Mavridis