Have you considered adding a "Go" method to Main.java with
public visibility (same behavior as pressing the "Go" button in the debugger UI).
This would be a big help in a system where the debugger has been
embedded. Being able to close the debugger and ensure that any
breakpoints were removed and any blocked threads notified would
be a nice feature. Without this, closing the debugger can either
a) halt the application or b) destroy the debugger leaving blocked
threads in a permanent wait state. Note that the debugger is
not actually destroyed in this case because the waiting threads
prevent it from being wholly GCed.
This looks like a simple case of using the Hashtable key
instead of the value...
public void clearAllBreakpoints() {
// Igor - Use of keys() is inappropriate here. It produces
// a ClassCastException on the assignment below. The
// keys are String instances, not SourceInfo instances...
//
//Enumeration e = sourceNames.keys();
Enumeration e = sourceNames.elements();
...
}
For that I added new method createClasssLoader to Context, which by default returns new instance of DefiningClassLoader and changed the code to use this method instead of creating DefiningClassLoader directly. I moved DefiningClassLoader to org.mozilla.javascript package so core Rhino classes would not depend on org.mozilla.classfile package. I also changed SecurityController.createClasssLoader to take additional parentLoader argument to explicitly specify which class loader should be parent for generated code.
From my mail to Norris Boyd:
When considering http://bugzilla.mozilla.org/show_bug.cgi?id=166530 I realized that my 2 years old suggestion to use Thread.getContextClassLoader() in org.mozilla.classfile.DefiningClassLoader was wrong, as it does not follow class loader chain pattern Rhino embeddings can use. Moreover, it is wrong to use Thread.getContextClassLoader() when searching for Rhino classes as if Rhino is available via the system class loader and an application uses its copy from another loader, Thread.getContextClassLoader() would return incompatible class while simple Class.forName() would do proper job of loading the requested class from a loader of Class.forName() caller.
The only place where Thread.getContextClassLoader() can be useful is when searching for classes in NativeJavaPackage, but even there with a new option to use Package with an explicit class loader argument it is not necessary as one can write in a script
Packages(java.lang.Thread.contextClassLoader) to get necessary behavior.