This is due to a known issue with ClassLoader.getPackages(). It is implemented
"inconsistently" comparing with ClassLoader.getPackage(). I quoted inconsistent
since it is not exactly clear what the behaviour should be when multiple
class loaders in one delegation chain define different packages objects for
the same package.
ClassLoader.getPackage("foo") returns the package object defined for package
foo in this particular class loader, or if this class loader didn't define
package foo, the method returns what the parent class loader has defined for
foo, if any.
ClassLoader.getPackages() returns all the packages defined in this class loader
and its ancestors. The problem is: what happens when one of its ancestor defined
package foo, and this class loader also defined foo ? The current implementation
is: the parent's package object will be returned.
So when does this happen? It happens when a child class loader defines
package foo first. Later on when a parent class loader tries to define foo,
since the parent cannot see its children, it will succeed. This is exactly
what happened in the test case shown in the bug report, although it is not
a generic problem. It doesn't work the other way, since a child CAN see what its
parent has defined, and if it tries to define something that its parent has
already defined, an IllegalArgumentException will be thrown.
I don't think the test case is semantically correct, although it is totally
legal to write. The definePackage method should only be called when a class
in a package is actually loaded, and getPackage is supposed to return all the
packages that the current class loader and its ancestors have loaded so far.
Calling definePackage before any class from that package is loaded breaks this
definition and would interfere with the class loading delegation model, and
would cause confusing results as shown in the test case. In most cases, a well
behaved class loader follows the delegation model and would give users a
consistent view of packages. On the other hand, this may change in future
releases when we clarify and tighten the definition of packages.
So what should the correct behaviour be ? We cannot answer this without answer
the following question first: Can multiple package object exist for the same
package along one delegation chain ? In Roger Riggs' (one of the creators of packages) view, only one package can be defined in one delegation chain. But
again, this might need to change in the future.
A reasonable temporary fix to the problem would be: make ClassLoader.getPackages
return the package defined in the current class loader. But I would rather leave
this issue open until we have a better idea of how we are going to define
The change of behaviour from cricket to kestrel is a side effect of bug fix
Made getPackage and getPackages consistent with each other, i.e., return the
package defined in the current class loader, and if not, return the parent's