----------------------------------------------------------------------
Please note that the file which is attached to this report,
kestrel-issues-summary.txt, contains a discussion of issues that are
related to Merlin functionality which is known as "Preferred Classes."
This file was mailed to jdk-extmech@eng. This discussion provides
useful and important background information for this bug.
----------------------------------------------------------------------
Package sealing does not enforce restrictions on child class loaders
consistently. Parent and child class loaders can contain duplicate
java.lang.Package definitions which are both sealed:
As it currently interacts with the class loader delegation model,
sealing a package now has the following effect: If a JAR file seals a
package, foo, and that JAR file is a resource of a URLClassLoader, and
at least one class, foo.Bar, in that package can only be found in that
class loader (i.e. not by delegating to a parent) from that JAR file,
then sealing enforces the following restriction: If any class in that
package has been defined by an ancestor class loader (i.e. the
ancestor called definePackage for "foo"), then an exception will be
thrown when the URLClassLoader attempts to define foo.Bar from its JAR
(assuming the JAR has a different seal base than the parent's
package). In other words, a child class loader cannot create a new
sealed package if it or a parent class loader has already defined an
equivalent package (sealed or not). Additionally, a URLClassLoader
will also throw a "sealing violation" exception if it is asked to
define a class in a package to a different seal base than that of an
equivalent package that any of its ancestors may have sealed. Sealing
is intended to enable parent class loaders to prevent the creation of any
duplicate packages in child class loaders, but since
The important point to take from the above description is that a Java
package is not sealed until a Package object has been created for it
(this will happen when some class loader first calls defineClass(...)
for a class which declares itself as a member of a relevant
package). If a child class loader creates a Package before a parent
has a chance to seal or create that Package, the child will be able to
create a sealed Package that a parent class loader might load
(possibly sealed) later on. That fact that this situation can occur
goes against the original design of Package sealing. Specifically,
it is possible for a child class loader and a parent class loader to
both create duplicate Package objects which describe the same Java
package (this is true as long as the child class loader creates its
Package object before any parent has a chance to do so). This behavior
invalidates that claim that if a package is sealed with respect to one
sealbase, then all classes in that package must be loaded from that
sealBase.
One particularly useful aspect of package sealing is that it can be
used to force a child class loader to make a choice to use all of its
own or all of its parents resources in a given package but not a
combination of both. However, as described above, class loading order
dependencies make it difficult to know exactly when a sealing
violation will be thrown when a class loader attempts to create a
Package. Because of this, package sealing can not always be used to
guarantee package version consistency among the classes in a "single"
package. The current implementation of sealing should be changed to
fully support loading restrictions that a parent wishes to enforce
for all its child class loaders.
Also see the attached files for package-test.tar for a simple test
which demonstrates inconsistencies described in this report.