The Groovy compiler is able to compile Groovy source code, but not Java source code. Existing Java compilers compile Java source code, but not Groovy.
This leads to problems when trying to mix Groovy and Java classes freely in a project.
(1) Factory pattern
Assume a Java interface, a Java implementation and a Java factory that returns an instance of the Java implementation.
If you want to replace the Java implementation with one written in Groovy, the Groovy implementation will depend on the Java interface, while the Java factory will depend on the Groovy implementation.
With separate compilers for Java and Groovy, the developer will either have to
- manually assure a certain order of compilation (use Java compiler to compile Java interface, use Groovy compiler to compile Groovy implementation, use Java compiler to compile Java factory) - this can be done in an Ant build script, but e.g. not in Eclipse - or
- use classloading instead of direct references (e.g. use Class.forName in the factory, introduce an IoC container) - this can have negative side effects (refactoring, obfuscation)
(2) Circular dependencies
See the following class hierarchy (thanks Jochen for the example - J1 and J2 are Java classes, G1 is a Groovy class):
class J2 extends G1 extends J1
While this is valid (and can be compiled if only Java or only Groovy classes are used), it it impossible to compile it with the current compilers due to circular dependencies between Java and Groovy classes!
Therefore, for a seamless integration of Java and Groovy, a "combined compiler" is needed that can handle the above cases without the need to change the architecture or the build process for a project.