JDK-4256589 : ClassLoader.getPackage and Package.get* methods do not work correctly?
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 1.3.0
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 1999-07-23
  • Updated: 1999-09-28
  • Resolved: 1999-09-13
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.
1.3.0 kestrelFixed
Related Reports
Relates :  
On Kestrel,
When package is defined by ClassLoader.definePackage correctly, 
1)only "name" is returned by ClassLoader.getPackage.
2)Package information can not get by Package.get* methods and
null is returned.
(ex.getSpecificationTitle, getSpecificationVersion....)
3) Package.isCompatibleWith() causes NumberFormatException

On the other hand, package is defined as same way, on Cricket
1)"name", "tilte" and "version" are returned by ClassLoader.getPackage
2)Package information is get by Package.get* methods
3) Package.isCompatibleWith() returns true

To reproduce,

1)Extract attached file.
2)Run PackageTest
3)You can see the result

The part of the result is as below;

*********result of ClassLoader.getPackage :package cat
Name :cat
--- Package.getSpecificationTitle()
SpecificationTitle :null
--- Package.getSpecificationVersion()
SpecificationVersion :null
--- Package.getSpecificationVendor()
SpecificationVendor :null
--- Package.getImplementationTitle()
ImplementationTitle :null
--- Package.getImplementationVersion()
ImplementationVersion :null
--- Package.getImplementationVendor()
ImplementationVendor :null
--- Package.isCompatibleWith()
!!!exception : java.lang.NumberFormatException: Empty version string
--- Package.toString()

CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: kestrel FIXED IN: kestrel INTEGRATED IN: kestrel VERIFIED IN: kestrel

EVALUATION 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 packages. The change of behaviour from cricket to kestrel is a side effect of bug fix to 4244970. ###@###.### 1999-07-23 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 package object. ###@###.### 1999-09-13