Subj : Re: Getting Rhino debugger working in servlets To : netscape.public.mozilla.jseng From : ow Date : Fri Sep 30 2005 03:04 am Hi Jon, Thanks for your writeup. With your help I was able to get it working too for my J2EE web application. I think I could simplify it even more. Here is a version that has no need to divide up code between debug and normal execution. As far as I see it, the single most important part is to create the Debugger and attach it to the ContextFactory before any context gets created. The Debugger must register itself with the ContextFactory to get notified of created contexts so it can prepare these to callback the debugger. I think this may be why Context.enter() was a killer for you. However, using Context.enter() and Context.exit() should be not necessary anyway as long as you call scripts using a ContextAction. The call method on ContextFactory seems to automatically do this (as stated in the javadoc in the source code). Also, I found out that instantiating the Debugger directly gives you more options than calling the mainEmbedded method. For instance you could prevent the debugger from killing the whole application when it closes and re-use the same instance for multiple debuggings. You could also manually redirect in/out/err streams of the debugger to wherever you like. Broken down to the important parts I do the following: I have this "RhinoExpressionEngine" object that handles script execution for me. If debug mode is enabled it creates the debugger right in its constructor before any context may be created. This debugger instance is stored in a field and re-used for all debugging purposes. The engine class has a method to execute scripts which calls a ContextAction implementor named "RhinoContextAction", a very simple inner class. If the script should be debugged I call the method doBreak() on the debugger just before script execution. In this demo class I don't do more complicated scope stuff since this seems not to interfer with the debugger functionality. I just use the scope returned from initStandardObjects. You might add a shared scope with predefined objects by taste/neccessity. I used the most current Rhino version 1.6R2. Here's the code: public class RhinoExpressionEngine { public class RhinoContextAction implements ContextAction { private String _script; public RhinoContextAction(String script) { _script = script; } public Object run(Context rcx) { return rcx.evaluateString(rcx.initStandardObjects(), _script, "", 1, null); } } private Main _debugger = null; public RhinoExpressionEngine(boolean debug) { if (debug) { _debugger = new Main("Rhino Debugger"); // Attach to the context factory to listen for context creation _debugger.attachTo(ContextFactory.getGlobal()); // Set the exit action. null means no action at all but you can provide // any Runnable you like _debugger.setExitAction(null); // Display the debugger window. You could choose to display it later. _debugger.pack(); _debugger.setSize(600, 460); _debugger.setVisible(true); } } public Object evaluateScript(String script, boolean debug) { if (debug && _debugger != null) { _debugger.doBreak(); // Instructs the debugger to break on execution } RhinoContextAction contextAction = new RhinoContextAction(script); return ContextFactory.getGlobal().call(contextAction); } } Oliver Weise Innovation Gate GmbH .