This page is work in progress. It will document the internals of groovy, the ideas and the techniques used so other developers may it have more easy to contribute to groovy in the future.
One Class One Class Loader
When are two classes the same? If the name is equal and if the class loader is equal. This means you can have multiple versions of the same class if you load the class through different class loaders. Of course this versions don't really have to be the same. This also means if you have code like
may fail because cls is not Foo. This also means calling a method like
with an Foo does not mean that "f(Foo) called" will be printed! This is no secret, you will find it in the language specification.
Class Loading Conventions
There are small conventions about how to do class loading in Java.
- always return the same class for the same name
- use your cache before asking a parent loader
- no parent loader doesn't mean the system loader
- ask your parent loader before trying ot load a class by yourself
Most of the loaders in groovy are violating one or more of these rules. I will exlpain why and how in the next sections
First let us start with the RootLoader. This one used used to start the console programs and is something like an advanced java launcher. When using Groovy embedded this loader is usually not used. The RootLoader sees itself as a root in a class loader tree. Against the convention to ask the parent before loading a class this laoder tries to load it by itself first. Only when this fails the parent is asked. They parent is usually the system class loader then. This step was needed because of many problems with multiple versions of libs, causing multiple classes of the same name where they are not expected, or classes loaded from the wrong libs. Because of that reason this loader may also be used in ant or maven to avoid clashes with the classes used by ant.
If you assign a value to a typed variable in Groovy, then this assignment will include an implicit cast. A Declaration counts as assignment in that sense as well.
is in fact
MethodClosure method = (MethodClosure) value;
IteratorClosureAdapter adapter = new IteratorClosureAdapter(method.getDelegate());
, but might be broken and untested.
- a String or GString by a list of characters
- a File by its text lines
- an enum by the values() method
- all other cases by Collections.singletonList(value)