United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-4256589 ClassLoader.getPackage and Package.get* methods do not work correctly?
JDK-4256589 : ClassLoader.getPackage and Package.get* methods do not work correctly?

Details
Type:
Bug
Submit Date:
1999-07-23
Status:
Closed
Updated Date:
1999-09-28
Project Name:
JDK
Resolved Date:
1999-09-13
Component:
core-libs
OS:
generic
Sub-Component:
java.lang
CPU:
generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
1.3.0
Fixed Versions:
1.3.0 (kestrel)

Related Reports
Relates:

Sub Tasks

Description
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()


                                    

Comments
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
                                     
1999-09-13
CONVERTED DATA

BugTraq+ Release Management Values

COMMIT TO FIX:
kestrel

FIXED IN:
kestrel

INTEGRATED IN:
kestrel

VERIFIED IN:
kestrel


                                     
2004-06-14



Hardware and Software, Engineered to Work Together