JDK-4302423 : class loaders should support "local" creation of Package objects
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 1.4.0
  • Priority: P4
  • Status: Closed
  • Resolution: Other
  • OS: generic
  • CPU: generic
  • Submitted: 2000-01-04
  • Updated: 2017-12-20
  • Resolved: 2016-03-23
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9Resolved
Related Reports
Relates :  
Relates :  
Relates :  
Description
The rfe, 4302406, describes functionality which is known as "Preferred
classes."  The preferred classes rfe describes functionality which
will enable a child class loader to prefer its own resources over
those of a parent.  To be consistent with the philosophy described in
the preferred classes rfe, child class loaders should not only be able
to override class loader resources but should also be permitted to
create their own Package objects (i.e. prefer them) even when a parent
class loader has already defined duplicate Package objects.

This rfe is related to a merlin bug, 4302406 which discusses the fact
that though it seems to be a side effect of the current Package
creation mechanism it is already possible to have duplicate Package
definitions for a given Java package in a single class loading
hierarchy.  Here is a relevant excerpt:

  - Package sealing does not enforce upward sealing consistently.
    The exact situations in which a sealing violation will be thrown
    depend upon the order in which ancestor and descendant loaders
    actually load resources.  If a descendant class loader happens
    to define a sealed package object before an ancestor defines a
    class in a relevant package, then no sealing violation will be
    thrown for any class the descendant defines in a package an
    ancestor may have also defined.  In other words, it is currently
    possible for parent and child class loaders to contain duplicate
    and sealed definitions of the same package.

It is necessary to read the information contained in 4251303 and
4302406 to understand the need for this rfe.

In addition, the Class.getPackage() (and related "getPackage") APIs
exhibit inconsistent behavior.  Specifically whether or not a child
class loader will create its own Package object for a Java package
foo, depends upon whether its parent has already defined a Package
object for foo.  The child class loader can define classes that the
parent does not have, but the Package object for those classes will be
the one contained in the parent - not the child.  This precedence of
parent Package object's can lead to problems (e.g. suppose the child's
package was of an incompatible version than its parents package... ).

On the other hand, the class loader delegation hierarchy will allow 
the child to use its own Package object for the classes its defines - 
as long as the child creates it Package object before its parent...

If a class loader loading preferred classes is allowed to
create its own duplicates of parent class loader resources, it would
be consistent to also allow class loaders which understand preferred
resources to create copies of (potentially sealed) packages that exist
in a parent class loader.  Of course, this ability would circumvent
some of the intended purposes of package sealing.  It may be
appropriate (to fully support preferred classes) to add an API to
java.lang.ClassLoader which enables access to Package definitions
which are "local" to a given class loader.

-----
I have also attached a simple test program which demonstrates that 
it is already possible for child and parent class loaders to have
duplicate copies of Package objects which describe the same Java 
package.


lairdd@east 2000-01-31

Comments
Package API has been updated in jdk-9+111 and this issue has been resolved. See the summary of the API change described at: https://bugs.openjdk.java.net/browse/JDK-8061804?focusedCommentId=13916978&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-13916978
23-03-2016

SUGGESTED FIX There are two major components to this problem: 1. class loaders that define preferred classes need to be able to create their own Package objects even if those objects duplicate those contained in a parent. 2. Java Package objects should be created so that they consistently contain correct meta-information about the classes with which they are associated. For example, parent version information should not supercede child version information simply because the parent happened to contain some classes in the same package as a child. Preferred classes require that child class loaders should always be able to create their own Package objects (even in the presence of parent duplicates). Allowing child Package information to persist even when a Parent already contains Package information which is different from the child's seems to require that multiple Packages exist in the delegation hierarchy - specifically one is needed for every class loader which ever defines a class in a package (if duplicates are not allowed then some Package information may be lost). Given the above constraints, the RMI team suggests the following solution to this report: ---------- - Class loaders that define classes in a package should be able to have create and hold their own Package objects. - Clients that wish to have access to the Package information of a particular class should be able access all Packages in a delegation hierarchy and should be able to access Packages in a specific class loader. ---------- We suggest the following changes to implement this functionality: A. java.lang.ClassLoader needs the following new protected API: protected Package java.lang.ClassLoader.findPackage(String packageName) The only use of this new API that we forsee is to be called by URLClassLoader. However the method should be added to java.lang.ClassLoader so that this modified Package mechanism may be used by all ClassLoader subclasses. B. The method URLClassLoader.getPackage() should be changed so that URLClassLoaders follow the algorithm below: 1. They should first invoke findPackage() on themselves to get a requested package. If there are any duplicate Package definitions in the delegation hierarchy, the most-specific or lowest Package object in the hierarchy will be returned. 2. If the findPackage() method returns no Packages, then class loaders should delegate to their parents to find the Package. C. Package object creation should have the following semantics: 1. The getPackage method should no longer "copy down" Package objects. Currently, in Java class loading, each class loader maintains a cache of Package objects. Whenever a class loader creates a new Package object it puts it into its local cache of Package objects. Whenever a class loader delegates to its parent to find a class, if the parent has a package to satisfy the delegation, the child puts/"copies down" the Package from its parent into its own local cache. This behavior can interfere with the child class loader's ability to create its own Package objects (i.e. when those Package objects are duplicates of those in a parent). Instead of copying down parent class loader Packages, class loaders should delegate to their parent every time they need to access a Parent's version of a given Package object. Class loader caches should only ever hold the Package objects that are created by their own local class loader. 2. Everytime a class loader defines a Class in a package, the class loader should create a Package object for the relevant package (unless the class loader itself has already created a Package object for the package). 3. The method definePackage() needs to be changed to only throw an exception if a local class loader has created the Package (findPackage() returns a Package object). This allows child class loaders to create Packages independent of their parents. This package creation scheme should resolve both components of this report.
11-06-2004