Source Code Cross Referenced for EventHandlerThread.java in  » IDE » DrJava » edu » rice » cs » drjava » model » debug » jpda » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE » DrJava » edu.rice.cs.drjava.model.debug.jpda 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*BEGIN_COPYRIGHT_BLOCK
002:         *
003:         * Copyright (c) 2001-2007, JavaPLT group at Rice University (javaplt@rice.edu)
004:         * All rights reserved.
005:         * 
006:         * Redistribution and use in source and binary forms, with or without
007:         * modification, are permitted provided that the following conditions are met:
008:         *    * Redistributions of source code must retain the above copyright
009:         *      notice, this list of conditions and the following disclaimer.
010:         *    * Redistributions in binary form must reproduce the above copyright
011:         *      notice, this list of conditions and the following disclaimer in the
012:         *      documentation and/or other materials provided with the distribution.
013:         *    * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
014:         *      names of its contributors may be used to endorse or promote products
015:         *      derived from this software without specific prior written permission.
016:         * 
017:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
018:         * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
019:         * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
020:         * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
021:         * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
022:         * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
023:         * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
024:         * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
025:         * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
026:         * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
027:         * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028:         *
029:         * This software is Open Source Initiative approved Open Source Software.
030:         * Open Source Initative Approved is a trademark of the Open Source Initiative.
031:         * 
032:         * This file is part of DrJava.  Download the current version of this project
033:         * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
034:         * 
035:         * END_COPYRIGHT_BLOCK*/
036:
037:        package edu.rice.cs.drjava.model.debug.jpda;
038:
039:        import edu.rice.cs.util.Log;
040:
041:        import com.sun.jdi.*;
042:        import com.sun.jdi.event.*;
043:        import com.sun.jdi.request.*;
044:        import java.util.*;
045:        import java.io.*;
046:        import edu.rice.cs.drjava.model.debug.DebugException;
047:
048:        /** A thread that listens and responds to events from JPDA when the debugger has attached to another JVM.
049:         *  @version $Id: EventHandlerThread.java 4255 2007-08-28 19:17:37Z mgricken $
050:         */
051:        public class EventHandlerThread extends Thread {
052:
053:            /** Debugger to which this class reports events. */
054:            private final JPDADebugger _debugger;
055:
056:            /** JPDA reference to the VirtualMachine generating the events. */
057:            private final VirtualMachine _vm;
058:
059:            /** Whether this event handler is currently connected to the JPDA VirtualMachine. */
060:            private volatile boolean _connected;
061:
062:            /** A log for recording messages in a file. */
063:            private static final Log _log = new Log("EventTest", false);
064:
065:            /** Creates a new EventHandlerThread to listen to events from the given debugger and virtual machine.  Calling
066:             *  this Thread's start() method causes it to begin listenting.
067:             *  @param debugger Debugger to which to report events
068:             *  @param vm JPDA reference to the VirtualMachine generating the events
069:             */
070:            EventHandlerThread(JPDADebugger debugger, VirtualMachine vm) {
071:                super ("DrJava Debug Event Handler");
072:                _debugger = debugger;
073:                _vm = vm;
074:                _connected = true;
075:            }
076:
077:            /** Logs any unexpected behavior that occurs (but which should not cause DrJava to abort).
078:             *  @param message message to print to the log
079:             */
080:            private void _log(String message) {
081:                _log.log(message);
082:            }
083:
084:            /** Logs any unexpected behavior that occurs (but which should not cause DrJava to abort).
085:             *  @param message message to print to the log
086:             *  @param t Exception or Error being logged
087:             */
088:            private void _log(String message, Throwable t) {
089:                _log.log(message, t);
090:            }
091:
092:            /** Continually consumes events from the VM's event queue until it is disconnected.*/
093:            public void run() {
094:                _debugger.notifyDebuggerStarted();
095:
096:                EventQueue queue = _vm.eventQueue();
097:                while (_connected) {
098:                    try {
099:                        try {
100:                            // Remove and consume a set of events from the queue (blocks for an event)
101:                            EventSet eventSet = queue.remove();
102:                            EventIterator it = eventSet.eventIterator();
103:
104:                            while (it.hasNext())
105:                                handleEvent(it.nextEvent());
106:                        } catch (InterruptedException ie) {
107:                            // Don't need to do anything.  If the VM was disconnected,
108:                            // the loop will terminate.
109:                            _log("InterruptedException in main loop: " + ie);
110:                        } catch (VMDisconnectedException de) {
111:                            // We expect this to happen if the other JVM is reset
112:                            handleDisconnectedException();
113:                            break;
114:                        }
115:                    } catch (Exception e) {
116:                        // Log and report to the debugger
117:                        _log("Exception in main event handler loop.", e);
118:                        _debugger.eventHandlerError(e);
119:                        _debugger
120:                                .printMessage("An exception occurred in the event handler:\n"
121:                                        + e);
122:                        _debugger
123:                                .printMessage("The debugger may have become unstable as a result.");
124:                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
125:                        e.printStackTrace(new PrintWriter(baos, true));
126:                        _debugger.printMessage("Stack trace: "
127:                                + baos.toString());
128:                    }
129:                }
130:
131:                _debugger.notifyDebuggerShutdown();
132:            }
133:
134:            /** Processes a given event from JPDA. A visitor approach would be much better for this, but Sun's Event class 
135:             *  doesn't have an appropriate visit() method.
136:             */
137:            private void handleEvent(Event e) throws DebugException {
138:                //    Utilities.showDebug("EventHandler.handleEvent(" + e + ") called");
139:                _log("handling event: " + e);
140:
141:                if (e instanceof  BreakpointEvent)
142:                    _handleBreakpointEvent((BreakpointEvent) e);
143:                else if (e instanceof  StepEvent)
144:                    _handleStepEvent((StepEvent) e);
145:                //else if (e instanceof ModificationWatchpointEvent) {
146:                //  _handleModificationWatchpointEvent((ModificationWatchpointEvent) e);
147:                //}
148:                else if (e instanceof  ClassPrepareEvent)
149:                    _handleClassPrepareEvent((ClassPrepareEvent) e);
150:                else if (e instanceof  ThreadStartEvent)
151:                    _handleThreadStartEvent((ThreadStartEvent) e);
152:                else if (e instanceof  ThreadDeathEvent)
153:                    _handleThreadDeathEvent((ThreadDeathEvent) e);
154:                else if (e instanceof  VMDeathEvent)
155:                    _handleVMDeathEvent((VMDeathEvent) e);
156:                else if (e instanceof  VMDisconnectEvent)
157:                    _handleVMDisconnectEvent((VMDisconnectEvent) e);
158:                else
159:                    throw new DebugException("Unexpected event type: " + e);
160:            }
161:
162:            /** Returns whether the given thread is both suspended and has stack frames. */
163:            private boolean _isSuspendedWithFrames(ThreadReference thread)
164:                    throws DebugException {
165:
166:                try {
167:                    return thread.isSuspended() && thread.frameCount() > 0;
168:                } catch (IncompatibleThreadStateException itse) {
169:                    throw new DebugException(
170:                            "Could not count frames on a suspended thread: "
171:                                    + itse);
172:                }
173:            }
174:
175:            /** Responds to a breakpoint event.
176:             *  @param e breakpoint event from JPDA
177:             */
178:            private void _handleBreakpointEvent(BreakpointEvent e)
179:                    throws DebugException {
180:                synchronized (_debugger) {
181:                    if (_isSuspendedWithFrames(e.thread())
182:                            && _debugger.setCurrentThread(e.thread())) {
183:                        //        Utilities.showDebug("EventHandlerThread._handleBreakpointEvent(" + e + ") called");
184:                        _debugger.currThreadSuspended();
185:                        //        _debugger.scrollToSource(e);
186:                        _debugger.reachedBreakpoint((BreakpointRequest) e
187:                                .request());
188:                    }
189:                }
190:            }
191:
192:            /** Responds to a step event.
193:             *  @param e step event from JPDA
194:             */
195:            private void _handleStepEvent(StepEvent e) throws DebugException {
196:                // preload document without holding _debugger lock to avoid deadlock
197:                // in bug [ 1696060 ] Debugger Infinite Loop
198:                // if the document is not already open, the event thread may load the document and then call a
199:                // synchronized method in the debugger, so we must do this before we hold the _debugger lock
200:                _debugger.preloadDocument(e.location());
201:                // now acquire _debugger lock, the event thread won't need tge _debugger lock anymore
202:                synchronized (_debugger) {
203:                    if (_isSuspendedWithFrames(e.thread())
204:                            && _debugger.setCurrentThread(e.thread())) {
205:                        _debugger.printMessage("Stepped to "
206:                                + e.location().declaringType().name() + "."
207:                                + e.location().method().name()
208:                                + "(...)  [line " + e.location().lineNumber()
209:                                + "]");
210:                        _debugger.currThreadSuspended();
211:                        //        _debugger.scrollToSource(e);
212:                    }
213:                    // Delete the step request so it doesn't happen again
214:                    _debugger.getEventRequestManager().deleteEventRequest(
215:                            e.request());
216:                }
217:            }
218:
219:            //  /** Responds to an event for a modified watchpoint.
220:            //   *  This event is not currently expected in DrJava.
221:            //   *  @param e modification watchpoint event from JPDA
222:            //   */
223:            //  private void _handleModificationWatchpointEvent(ModificationWatchpointEvent e) {
224:            //    _debugger.printMessage("ModificationWatchpointEvent occured ");
225:            //    _debugger.printMessage("Field: " + e.field() + " Value: " +
226:            //                          e.valueToBe() +"]");
227:            //  }
228:
229:            /** Responds when a class of interest has been prepared. Allows the debugger to set a pending breakpoint before any 
230:             *  code in the class is executed.
231:             *  @param e class prepare event from JPDA
232:             *  @throws DebugException if actions performed on the prepared class fail
233:             */
234:            private void _handleClassPrepareEvent(ClassPrepareEvent e)
235:                    throws DebugException {
236:                synchronized (_debugger) {
237:                    _debugger.getPendingRequestManager().classPrepared(e);
238:                    // resume this thread which was suspended because its
239:                    // suspend policy was SUSPEND_EVENT_THREAD
240:                    e.thread().resume();
241:                }
242:            }
243:
244:            /** Responds to a thread start event.
245:             *  @param e thread start event from JPDA
246:             */
247:            private void _handleThreadStartEvent(ThreadStartEvent e) {
248:                synchronized (_debugger) {
249:                    _debugger.threadStarted();
250:                }
251:            }
252:
253:            /** Reponds to a thread death event.
254:             *  @param e thread death event from JPDA
255:             */
256:            private void _handleThreadDeathEvent(ThreadDeathEvent e)
257:                    throws DebugException {
258:                // no need to check if there are suspended threads on the stack
259:                // because all that logic should be in the debugger
260:                synchronized (_debugger) {
261:                    ThreadReference running = _debugger
262:                            .getCurrentRunningThread();
263:                    if (e.thread().equals(running)) {
264:                        // Delete any step requests pending on this thread
265:                        EventRequestManager erm = _vm.eventRequestManager();
266:                        List steps = erm.stepRequests();
267:                        for (int i = 0; i < steps.size(); i++) {
268:                            StepRequest step = (StepRequest) steps.get(i);
269:                            if (step.thread().equals(e.thread())) {
270:                                erm.deleteEventRequest(step);
271:
272:                                // There can only be one step request per thread,
273:                                //  so we can stop looking
274:                                break;
275:                            }
276:                        }
277:                        _debugger.currThreadDied();
278:                    } else
279:                        _debugger.nonCurrThreadDied();
280:                }
281:
282:                // Thread is suspended on death, so resume it now.
283:                e.thread().resume();
284:            }
285:
286:            /** Responds if the virtual machine being debugged dies.
287:             *  @param e virtual machine death event from JPDA
288:             */
289:            private void _handleVMDeathEvent(VMDeathEvent e)
290:                    throws DebugException {
291:                _cleanUp(e);
292:            }
293:
294:            /**
295:             * Responds if the virtual machine being debugged disconnects.
296:             * @param e virtual machine disconnect event from JPDA
297:             */
298:            private void _handleVMDisconnectEvent(VMDisconnectEvent e)
299:                    throws DebugException {
300:                _cleanUp(e);
301:            }
302:
303:            /** Cleans up the state after the virtual machine being debugged  dies or disconnects.
304:             * @param e JPDA event indicating the debugging session has ended
305:             */
306:            private void _cleanUp(Event e) throws DebugException {
307:                synchronized (_debugger) {
308:                    _connected = false;
309:                    if (_debugger.isReady()) {
310:                        // caused crash if "Run Document's Main Method" was invoked while debugging
311:                        // if (_debugger.hasSuspendedThreads()) _debugger.currThreadDied();
312:                        _debugger.shutdown();
313:                    }
314:                }
315:            }
316:
317:            /** Responds when a VMDisconnectedException occurs while dealing with another event.  We need to flush the event
318:             *  queue, dealing only with exit events (VMDeath, VMDisconnect) so that we terminate correctly. */
319:            private void handleDisconnectedException() throws DebugException {
320:                EventQueue queue = _vm.eventQueue();
321:                while (_connected) {
322:                    try {
323:                        EventSet eventSet = queue.remove();
324:                        EventIterator iter = eventSet.eventIterator();
325:                        while (iter.hasNext()) {
326:                            Event event = iter.nextEvent();
327:                            if (event instanceof  VMDeathEvent)
328:                                _handleVMDeathEvent((VMDeathEvent) event);
329:                            else if (event instanceof  VMDisconnectEvent)
330:                                _handleVMDisconnectEvent((VMDisconnectEvent) event);
331:                            // else ignore the event
332:                        }
333:                        eventSet.resume(); // Resume the VM
334:                    } catch (InterruptedException ie) {
335:                        // ignore
336:                        _log(
337:                                "InterruptedException after a disconnected exception.",
338:                                ie);
339:                    } catch (VMDisconnectedException de) {
340:                        // try to continue flushing the event queue anyway
341:                        _log("A second VMDisconnectedException.", de);
342:                    }
343:                }
344:            }
345:        }
w_w_w.ja__v___a2s__.__c___om | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.