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.

Parser

Package Layout

Bytecode Hints

Classloader Structure

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

Class cls = foo.class
assert cls.name==Foo.class.name
assert cls==Foo.class

may fail because cls is not Foo. This also means calling a method like

def f(Foo f){
  println "f(Foo) called"
}

def f(Object o){
  println "f(Object) called"
}

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.

  1. always return the same class for the same name
  2. use your cache before asking a parent loader
  3. no parent loader doesn't mean the system loader
  4. 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

RootLoader

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.

GroovyClassLoader

ReflectorLoader

Optional Typing

Assignment

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.

String x = 8

is in fact

String x = (String) 8

Note: there is nothing to be done but boxing, if the cast is to Object, since everything in Groovy is an Object. The cast is realized in Groovy by writing ScriptByteCodeAdapter.castToType(8, String.class), which in turn will call DefaultTypeTransformation.castToType(Object, Class).

Casting Rules in General

The following rules apply in the order given.
Casting rules for identity:

Char Casting Rules

Casting Rules for Boolean / Groovy Truth implementation

The implementation of this is determined by calling the asBoolean method of the value. It will realize those cases:

Casting to an Array

We try to create a collection from the value (see collection casting rules), create an array of the length of that collection and then set each element of the array with the according element of the collection after we cast the collection item to the component type of our array. This is realizing a recursive call to the original casting logic.

Casting to a Collection