Re: why do I get this runtime error
Aryeh M. Friedman wrote:
When I run this:
[ snip ]
> I get:
Exception in thread "main" java.lang.ClassCastException: scratch.Main
cannot be cast to scratch.Main
at scratch.Main.main(Main.java:29)
Fun exceptions happen when working with class loaders.
The short answer:
Multiple class loaders don't mix. One can change the default class
loader through some java -D option; I don't remember what it is however.
The long answer:
A class is uniquely determined by its instantiating class loader and its
fully-qualified name.
This is an example of a working loadClass function. I did not write this
myself, and it is based off of a very old version of Java (discussion of
custom class loaders is almost nil), so I do not know which parts are
irrelevant.
public final Class<?> loadClass(String name, boolean resolve) throws
ClassNotFoundException {
// Don't bother loading Java classes
if (name.startsWith("java.") || name.startsWith("javax."))
return super.loadClass(name, resolve);
// Did we already define it?
Class result = findLoadedClass(name);
if (result == null) {
String internalName = name.replace('.', '/') + ".class";
InputStream is = getParent().getResourceAsStream(internalName);
if (is != null) {
try {
// Load the raw bytes.
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int b;
while ((b=is.read())!=-1)
bos.write((byte)b);
byte[] bytes = bos.toByteArray();
result = defineClass(name, bytes, 0, bytes.length);
} catch (IOException ex) {
throw new ClassNotFoundException(name +
" could not be loaded", ex);
}
}
}
if (result != null) {
if (resolve) {
resolveClass(result);
}
} else {
// Let someone else find it.
result = super.loadClass(name, resolve);
}
return result;
}
Even here, it is still incompatible with system-default loaded classes.
--
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth