I received a bug report yesterday that Class.getPackage()
wasn’t working for user-defined classes and classes written in the Interactions Pane:
I was trying to run one of our assignment projects on DrJava and kepts getting a NullPointerException because getPackage() returns null. Corky said it was best to contact you about this.
To reporduce:
1. Load the attached project in DrJava
2. Run the following on the interactions pane:
new edu.rice.comp211.laundry.Main().getClass().getPackage()You’ll see null get printed.
This was a bit confusing for me because of several quick tests that I made: I tested it in the default package, and for the default package, the return value of Class.getPackage()
is supposed to be null
. I also compared DrJava’s Interactions Pane to running programs in DrJava using the “Run” button. I should have compared it to running programs on the command line.
I hadn’t heard of having to call ClassLoader.definePackage
before. Somehow, it had never been mentioned in any of the documents I had read about class loaders. The documentation seems to say that
package information is optional (“It may be null if no package information is available from the archive or codebase.”).
I figured out that we needed to call getPackage()
in the class loader and check if it is null
. If it is, and we are defining a class outside the default package, then we need to define a package by calling definePackage()
before we call defineClass()
(“Packages must be created before the class is defined”).
I just don’t understand why this isn’t done automatically with default values. My call looks like this:
definePackage(packageName, null, null, null, null, null, null, null);
There isn’t any more information being provided, except to say that this package exists. After a class in the package has been loaded, a package cannot be defined anymore, so there is no reason for not defining a package without information.