Hi Jochen,
While the current approach to joint compilation isn't perfect and fails to
resolve the issue for dynamically added methods or properties, it has been
running stably for years, and time has proven it to be good enough. On the
other hand, the maintenance workload for parsing Java source code is quite
substantial, especially now that Java has a new release every six months. This
was actually the main reason we originally introduced JavaParser, but we've
found that even JavaParser struggles to keep pace with Java's rapid evolution.
Cheers,
Daniel Sun
On 2026/04/23 23:08:18 Jochen Theodorou wrote:
> Hi all,
>
> I recently spend some time talking with AI about this project I had in
> mind for a long time: a new joint compiler working on the AST level.
>
> The goal was to allow transforms in Groovy to run and add methods and
> other class structures and give the Javacode a chance to see them.
> Basic problem:
>
> A.groovy:
> package pa
> @MyTransform
> class A{def b}
>
> B.java:
> package pb;
> import pa.*;
> public class B extends A {}
>
> C.groovy:
> package pc
> import pb.*
> class C extends B {}
>
> D.java:
> package pd;
> import pc.C;
> public class D extends C {}
>
>
> To compile the java code you need the Groovy code, but to compile the
> Groovy code you also need the Java code.
>
> Current solution: generate stubs for the Groovy code
> This is a lot like having headers in C, where you compile against those
> instead of the full source files. But the real problem is resolving
> classes. In C.groovy we cannot resolve B, since it is in Java. Thus we
> write the import also in the stub and just assume, that Java will
> resolve the class the same way Groovy would do. Which is a "mostly true"
> assumption, but not fully. While the property b in A is no problem, if
> MyTransform adds a method or anything like that in a late phase, then it
> will not be visible to the Java compiler when compiling against the stubs.
>
> So the idea was to create AST ClassNodes from the Java files, compile
> the Groovy code and then compile the java code against the final Groovy
> class files.
> The problem here is that class names need to be resolved. And that would
> then happen in the Groovy compiler. Basically an extra resolver for
> those Java source based ClassNodes for resolving in a "Java manner".
> This can become quite complex.
>
> Then I was wondering if the Java compiler could help or maybe a JDT
> based solution. But the resolver in the Java compiler is not made for
> this kind of usage really. You need internals and they will change. JDT
> is better suited but here too it is not quite doing what we want. Both
> will try to resolve too much.
>
> So my thinking was that a hand-written resolver will be needed for this.
> And here I was wondering if it is really worth it. I mean the complexity
> and somebody needs to maintain it as well. In the end the situation is
> like this: if java uses something like lombok, which may add
> constructors fields and methods then we will not see these things in
> Groovy. It is a bit like a reversal of the situation with the transforms.
>
> The best solution so far is for me to not mix groovy and java code in
> one src folder, and keep them in different sub projects. The situation
> on top of the post would mandate 4 such sub projects. Advantages are
> that you may not need to compile everything again, you do not generate
> hundreds of small files, that need to be parsed by Javac...
> Disadvantages are of course that you pay for the startup of the
> compilers several times and you can not freely mix.
>
> Do you think I am wrong? I really would like to hear some opinions....
> even if it is like "joint compilation is not important to us"
>
> bye Jochen
>
>