FeaturesPluginsDocs & SupportCommunityPartners

Debugger Core API/SPI Requirements

Autor: Jan Jancura
$Revision: 1.2 $
History:

1.6: First version
1.7: Some very useful comments from Ivan has been incorporated (I hope that properly), Debugger Engine definition has been added, DAR8, DAR2.1 has been added. Do not study relationship between Session <> Engine <> Language <> PlugIn in this version much, please. I will prepare some pictures ;) and description.
1.8: DAR9 and 10 added; DAR8, 6.2 and 6.1 changed


Why new Debugger Core APIs?

  • Compatibility & maintainability: Debugger is one of the most important modules in the IDE, and many other modules are based on it - JSP debugger, J2EE Debugger, Native Debugger, applet, RMI, Corba and some external moduels. Current NetBeans Debugger does not have public APIs. All dependencies are hardcoded.  Such dependencies are not maintainable in a longer period. Some communication standards, interfaces are needed.

  • Separation of UI and implementation: NetBeans debugger is bundled to differrent IDEs. And differrent IDEs have differrent user requirements, differrent UIs. That is why the Debugger UI should not be mixed with implementation, and should be easily replaceable. Debugger UI should be separated to special module, and Debugger Core API should define contract for it.

  • Testability: Current codebase is not stabe enough for unit testing. The debugger model must be changed.

  • Threading model: NB3.5 debugger does not have strictly separated UI & implementation. Definition of threading model is nearly impossible in such architecture.

  • Filterring of debugger stuff: One of the most important requirements from Enterprise Debugger group is to hide generated code (EJB stuff). So Debugger API should define some interface for filterring of Threads View, CallStack View and Smart Stepping functionality.

  • Multi-language debugging: Current Debugger Core does not support multi-language debugging. Implementation of JSP debugger is hacky, and it causes a large number of bugs in it.

  • JSR45 support: Support for JSR45 is required to the next releases. Its not possible to do it in the current model correctly.

Basic terms:

  • Debugger Plug-in is Netbeans module (or part of some module) which contains implementation of debugger for some special programming language / environment (like JPDA Debugger Plug-in, jdb debugger Plug-in, JSP debugger-plug-in...)
  • Debugger Session is visual representation of some process running in debug mode. Debugger API does not define if session represents one application, one process or something else. This should be defined by Debugger Plug-ins, or in some debugger UI guidelines. One of debugger sessions is always Current Session. This session defines behavoiur of Step actions, value of watches and other features.
  • Debugger Engine is Java class (or more classes) representing some engine capable of debugging = providing implementation of debugger actions like Start Debugging, Finish Debugging, Step into / Over / Out... Debugger Engine should be able to manage watches and breakpoints.  DebuggerEngine is provided by Debugger Plug-in.

DAR1 - Allow to install and use more Debugger Plug-ins (for different programming languages) to NetBeans IDE. <Web team, S1SEE, Native>

NetBeans Debugger consists of  Debugger Core (Debugger API +  implementation of debugger engine + some shared debugger UI components)  and Java Debugger. And its architecture should allow to install debugger plug-ins for other languages - JSP, C++, XSLT, ...

DAR2 - Debug more sessions at a one time - multisession debugging. <S1SEE, Native>

Architecture of NB debugger should support debugging of client-server, RMI, J2EE applications. It means that debugger can:
  1. start a new session even if some other is already running
  2. start more than one session at one time
  3. display state of all running sessions - it means watch threads / locals / callstack / watches / variables of all sessions.
There are two solutions for "3." - debugger can display state of one (current) session, or it can display all sessions simultaneously.  I think that both of them should be supported in APIs.

DAR2.1 - Debugger API should support visualisation of all running sessions simultaneously <Native>

DAR3 - Debugger Core API should be language neutral. <Native>

Debugger API should not contain special support for some specific language. While allowing language-specific features as extensions.

DAR4 - State management should be defined by Debugger Plug-In, and should be asynchronous. <Native>

Debugger APIs and its implementation (Debugger Core + shared debugger UI) should not drive changes of state of Debugger Plug-in. Debugger Plug-In (and all of its classes) can be in different states. Some of these states are visible to other modules through DebuggerAPIs or to a user through shared part of Debugger UI. The change of state can be initiated by some UI component, or some call of some Debugger API method, but it should always be validated / confirmed by debugger plug-in. Debugger Core should not change the state itself.  Both of synchronous and asynchronous confirmations should be supported.

Example: Debugger API defines "enabled" property for breakpoints. JPDALineBreakpoint is implemented in JPDA Debugger Plug-In.

  1. Breakpoint node calls Breakpoint.enable ()
  2. JPDALineBreakpoint.enable () method is called
  3. ---asynchronous call (different thread) ----
  4. JPDALineBreakpoint validates state change and calls protected method Breakpoint.setEnabled (true)
  5. Breakpoint.setEnabled method fires the change of state

DAR5 - Debugger API should support sharing of UI components for different Debugger Plug-Ins.

DAR5.1 - Share Debugger Actions <S1SEE, Native, Web team>

List of Actions: Run in Debugger,  Attach, Finish, Pause, Continue, Step Over / Into / Out, Run to Cursor, Fix, New Watch, New Breakpoint, Make Callee Current, Make Caller Current, Pop Topmost Call, Debugger Window
Current Debugger Session (provided by some Debugger Plug-In) defines behaviour of all shared actions. It can:
  • manage enabled / disabled state of action
  • define action performer

DAR5.2 - Share Debugger Views <S1SEE, Native, Web team>

DAR5.2.1 - Default set of Debugger Views defined in Debugger Core can be shared by different Debugger Plug Ins:

  • Sesions View: show list (or tree) of all sessions, one session is current
  • Threads View: show list (or tree) of all threads from the current session, one threads is current
  • Call Stack View: show call stack of the current thread from the current session
  • Locals View: show list of current local variables, local variable can present set of its fields in tree structure
  • Breakpoints View: shows list (or tree) of all breakpoints
  • Watches View: show list of all watches

DAR5.2.2 - Debugger Plug-In can define list (tree) of nodes visible in Threads / Call Stack / Locals Views.

Content of this views is defined by current session. But other sessions can filter it - see requirement DAR7.1.

DAR5.2.3 - Debugger Plug-In can add its own visual representation of session / breakpoint / watch (Node) to Sessions / Breakpoints / Watches View.

DAR5.2.4 - Debugger Views are implemented using TreeTableViews / Nodes.

DAR5.2.5 - Debugger PlugIn can add a new column to Debugger View or hide / redefine some existing one.

DAR5.2.6 - Debugger PlugIn can install new Debugger View(s), remove some existing or replace them.

Author of Debugger Plug-In should be careful in the case of removing / modifying default views. Conflicts may occur if two plug-ins would like to redefine the same view and so on.

DAR5.3 - Share New Breakpoint Dialog <S1SEE, Native, Web team>

Debugger API should allow sharing one New Breakpoint Dialog among different breakpoint types installed by different Debugger Plug-ins.

DAR5.4 - Share Attach Dialog <S1SEE, Native, Web team>

Debugger API should allow sharing one Attach Dialog among different Debugger Plug-ins.

DAR5.5 - Share New Watch Dialog <S1SEE, Native, Web team>

Debugger API should allow sharing one New Watch Dialog among different Debugger Plug-ins.

Support for multilanguage debugging.

Debugger API should support debugging in multilanguage environments. There are two usecases:
  • Current context of debugger can be represented by more than one programming language (for example user can see one position in code as JSP / Java / Bytecode).
  • When the current context is changed (step action, stop on breakpoint) a current language can be changed too (for example call from Java code to some native code).

DAR6.1 - Each Session has set of programming languages supported in the current context. <web team>

DAR6.2 - Session has Current Language property. <web team>

Current language defines:
- context for threads / call stack / locals views / watches view (if there is one View shared by all sessions)
- context for editor window or some other "source viewer" (UML...)
- context for Step actions (= context for debugger engine)

Breakpoint and other components can have some specific notion of language. For example "class load breakpoint" will be always Java specific. Line breakpoint should be attached to some source, and this source will define the language.

DAR6.3 - One Debugger Engine can support debugging in more than one language. <Native>

Each language is represented by some Debugger Engine

DAR6.4 - User can change current language for each session separately. <web team>

DAR6.5 - One debugger Plug-in can install support for more than one language. <Native>

It means that one Debugger Plug-In can install more than one Debugger Engines and one Debugger Engine can support more than one language.

DAR6.6 - Set of languages supported by some session can be changed when the context is changed. <web team>

Some new language can be detected during debugging (during debugging of some Java code a JSP can be detected) and the support for the new language can be added automatically.

DAR6.7 - One Debugger Plug-In can add support for some new programming language to the Session produced by different Debugger Plug-In. <web team>

For example, JSP debugger can be implemented as a "plug-in" to some already existing implementation of Java Debugger. In this case JSP Debugger will register JSPDebuggerEngine to already existing JavaSession produced by JPDADebuggerPlugIn. JSPDebuggerEngine than only delegates some functionality to already existing JPDADebuggerEngine.

Support for Debug Accross Tiers.

Enterprise applications consists of different tiers. Each tier can run in different process and / or can be written in different programming language. Some tiers are automatically generated and should be hidden to user. Debugger should present application as one unit - through all different tiers. So, for example, call stack view can contain call stack lines from different languages, some part of call stack can be hidden (generated RMI stub), and call stack can be combined from two threads from two processes (RMI call).

DAR7.1 - Each Debugger Plug-In can install some filters for Threads / Call Stack / Locals View. This filter can add / remove / replace default Nodes in list (tree) of Nodes in view. <S1SEE>

DAR8 - Debugger Engine can be "reused" for a new Debugger Session. <native>

DAR9 - Debugger Plug-in can create a new Session / Engine anytime during debugging. <native>

DAR10 - Debugger API should allow to split debugger UI and implementation to differrent modules. <Rave>




Companion
Projects:
MySQL Database Server   Open JDK: an Open SourceJDK   GlassFish Community: an Open Source Application Server    Mobile & Embedded Community    Open Solaris   java.net - The Source for Java Technology Collaboration   Virtual Box - full virtualizer  Open ESB - The Open Enterprise Service Bus Powered by