/******************************************************************************* * Copyright (c) 2000, 2015 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.debug.tests.core; import static org.junit.Assert.assertNotEquals; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugException; import org.eclipse.jdt.core.IBuffer; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.debug.core.IJavaDebugTarget; import org.eclipse.jdt.debug.core.IJavaHotCodeReplaceListener; import org.eclipse.jdt.debug.core.IJavaLineBreakpoint; import org.eclipse.jdt.debug.core.IJavaStackFrame; import org.eclipse.jdt.debug.core.IJavaThread; import org.eclipse.jdt.debug.core.IJavaVariable; import org.eclipse.jdt.debug.core.JDIDebugModel; import org.eclipse.jdt.debug.testplugin.DebugElementEventWaiter; import org.eclipse.jdt.debug.testplugin.DebugEventWaiter; import org.eclipse.jdt.debug.tests.AbstractDebugTest; import org.eclipse.jdt.debug.tests.TestAgainException; /** * Tests hot code replace */ public class HcrTests extends AbstractDebugTest { class HCRListener implements IJavaHotCodeReplaceListener { boolean notified = false; IJavaDebugTarget target = null; /* (non-Javadoc) * @see org.eclipse.jdt.debug.core.IJavaHotCodeReplaceListener#hotCodeReplaceFailed(org.eclipse.jdt.debug.core.IJavaDebugTarget, org.eclipse.debug.core.DebugException) */ @Override public synchronized void hotCodeReplaceFailed(IJavaDebugTarget target, DebugException exception) { notified = true; notifyAll(); } /* (non-Javadoc) * @see org.eclipse.jdt.debug.core.IJavaHotCodeReplaceListener#hotCodeReplaceSucceeded(org.eclipse.jdt.debug.core.IJavaDebugTarget) */ @Override public synchronized void hotCodeReplaceSucceeded(IJavaDebugTarget target) { notified = true; this.target = target; notifyAll(); } /* (non-Javadoc) * @see org.eclipse.jdt.debug.core.IJavaHotCodeReplaceListener#obsoleteMethods(org.eclipse.jdt.debug.core.IJavaDebugTarget) */ @Override public synchronized void obsoleteMethods(IJavaDebugTarget target) { notified = true; notifyAll(); } /** * Returns whether notified (yet). * * @return whether notified */ public synchronized boolean wasNotified() { return notified; } /** * Waits for notification and returns whether notified. * * @return */ public synchronized boolean waitNotification() { if (!notified) { try { wait(AbstractDebugTest.DEFAULT_TIMEOUT); } catch (InterruptedException e) { } } return notified; } } public HcrTests(String name) { super(name); } /* (non-Javadoc) * * Revert the source file after the test. * * @see junit.framework.TestCase#tearDown() */ @Override protected void tearDown() throws Exception { ICompilationUnit cu = getCompilationUnit(get14Project(), "src", "org.eclipse.debug.tests.targets", "HcrClass.java"); cu = cu.getPrimary(); if (!cu.isWorkingCopy()) { cu = cu.getWorkingCopy(null); } assertTrue("HcrClass.java does not exist", cu.exists()); IBuffer buffer = cu.getBuffer(); String contents = buffer.getContents(); int index = contents.indexOf("\"Two\""); if (index >= 0) { String newCode = contents.substring(0, index) + "\"One\"" + contents.substring(index + 5); buffer.setContents(newCode); cu.commitWorkingCopy(true, null); waitForBuild(); } super.tearDown(); } public void testSimpleHcr() throws Exception { String typeName = "org.eclipse.debug.tests.targets.HcrClass"; createLineBreakpoint(39, typeName); IJavaThread thread= null; try { thread= launchToBreakpoint(typeName); assertNotNull("Breakpoint not hit within timeout period", thread); IJavaDebugTarget target = (IJavaDebugTarget)thread.getDebugTarget(); if (target.supportsHotCodeReplace()) { // look at the value of 'x' - it should be "One" IJavaStackFrame frame = (IJavaStackFrame)thread.getTopStackFrame(); IJavaVariable variable = findVariable(frame, "x"); assertNotNull("Could not find 'x'", variable); assertEquals("value of 'x' should be 'One'", "One", variable.getValue().getValueString()); removeAllBreakpoints(); // now do the HCR ICompilationUnit cu = getCompilationUnit(get14Project(), "src", "org.eclipse.debug.tests.targets", "HcrClass.java"); cu = cu.getPrimary(); if (!cu.isWorkingCopy()) { cu = cu.getWorkingCopy(null); } assertTrue("HcrClass.java does not exist", cu.exists()); IBuffer buffer = cu.getBuffer(); String contents = buffer.getContents(); String originalContent = buffer.getContents(); int index = contents.indexOf("\"One\""); assertTrue("Could not find code to replace", index > 0); String newCode = contents.substring(0, index) + "\"Two\"" + contents.substring(index + 5); buffer.setContents(newCode); // save contents DebugElementEventWaiter waiter = new DebugElementEventWaiter(DebugEvent.SUSPEND, thread); cu.commitWorkingCopy(true, null); waitForBuild(); waiter.waitForEvent(); // should have dropped to frame 'one' frame = (IJavaStackFrame)thread.getTopStackFrame(); assertNotNull("No top stack frame", frame); if (!"one".equals(frame.getMethodName())) { // terminate & restore, and try again - @see bug 287084 thread.terminate(); buffer.setContents(originalContent); cu.commitWorkingCopy(true, null); throw new TestAgainException("Retest - the correct method name was not present after HCR"); } assertEquals("Should have dropped to method 'one'", "one", frame.getMethodName()); // resume to breakpoint createLineBreakpoint(39, typeName); thread = resume(thread); // value of 'x' should now be "Two" frame = (IJavaStackFrame)thread.getTopStackFrame(); variable = findVariable(frame, "x"); assertNotNull("Could not find 'x'", variable); assertEquals("value of 'x' should be 'Two'", "Two", variable.getValue().getValueString()); } else { System.err.println("Warning: HCR test skipped since target VM does not support HCR."); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); } } /** * Tests a general (plug-in) listener. * * @throws Exception */ public void testGeneralHcrListener() throws Exception { String typeName = "org.eclipse.debug.tests.targets.HcrClass"; createLineBreakpoint(39, typeName); HCRListener listener = new HCRListener(); JDIDebugModel.addHotCodeReplaceListener(listener); IJavaThread thread= null; try { thread= launchToBreakpoint(typeName); assertNotNull("Breakpoint not hit within timeout period", thread); IJavaDebugTarget target = (IJavaDebugTarget)thread.getDebugTarget(); if (target.supportsHotCodeReplace()) { // look at the value of 'x' - it should be "One" IJavaStackFrame frame = (IJavaStackFrame)thread.getTopStackFrame(); IJavaVariable variable = findVariable(frame, "x"); assertNotNull("Could not find 'x'", variable); assertEquals("value of 'x' should be 'One'", "One", variable.getValue().getValueString()); removeAllBreakpoints(); // now do the HCR ICompilationUnit cu = getCompilationUnit(get14Project(), "src", "org.eclipse.debug.tests.targets", "HcrClass.java"); cu = cu.getPrimary(); if (!cu.isWorkingCopy()) { cu = cu.getWorkingCopy(null); } assertTrue("HcrClass.java does not exist", cu.exists()); IBuffer buffer = cu.getBuffer(); String contents = buffer.getContents(); int index = contents.indexOf("\"One\""); assertTrue("Could not find code to replace", index > 0); String newCode = contents.substring(0, index) + "\"Two\"" + contents.substring(index + 5); buffer.setContents(newCode); // save contents cu.commitWorkingCopy(true, null); waitForBuild(); assertTrue("Listener should have been notified", listener.waitNotification()); } else { System.err.println("Warning: HCR test skipped since target VM does not support HCR."); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); JDIDebugModel.removeHotCodeReplaceListener(listener); } } /** * Tests that a target specific listener overrides a generic listener. * * @throws Exception */ public void testSpecificHcrListener() throws Exception { String typeName = "org.eclipse.debug.tests.targets.HcrClass"; createLineBreakpoint(39, typeName); HCRListener listener = new HCRListener(); HCRListener listener2 = new HCRListener(); JDIDebugModel.addHotCodeReplaceListener(listener); IJavaThread thread= null; try { thread= launchToBreakpoint(typeName); assertNotNull("Breakpoint not hit within timeout period", thread); IJavaDebugTarget target = (IJavaDebugTarget)thread.getDebugTarget(); if (target.supportsHotCodeReplace()) { target.addHotCodeReplaceListener(listener2); // look at the value of 'x' - it should be "One" IJavaStackFrame frame = (IJavaStackFrame)thread.getTopStackFrame(); IJavaVariable variable = findVariable(frame, "x"); assertNotNull("Could not find 'x'", variable); assertEquals("value of 'x' should be 'One'", "One", variable.getValue().getValueString()); removeAllBreakpoints(); // now do the HCR ICompilationUnit cu = getCompilationUnit(get14Project(), "src", "org.eclipse.debug.tests.targets", "HcrClass.java"); cu = cu.getPrimary(); if (!cu.isWorkingCopy()) { cu = cu.getWorkingCopy(null); } assertTrue("HcrClass.java does not exist", cu.exists()); IBuffer buffer = cu.getBuffer(); String contents = buffer.getContents(); int index = contents.indexOf("\"One\""); assertTrue("Could not find code to replace", index > 0); String newCode = contents.substring(0, index) + "\"Two\"" + contents.substring(index + 5); buffer.setContents(newCode); // save contents cu.commitWorkingCopy(true, null); waitForBuild(); assertTrue("Specific listener should have been notified", listener2.waitNotification()); assertFalse("General listener should not have been notified", listener.wasNotified()); } else { System.err.println("Warning: HCR test skipped since target VM does not support HCR."); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); JDIDebugModel.removeHotCodeReplaceListener(listener); } } /** * Tests HCR in a local type with the same name as the enclosing * method * @throws Exception * @since 3.8.100 */ public void testHCRLocalType() throws Exception { String typeName = "org.eclipse.debug.tests.targets.HcrClass2"; createLineBreakpoint(33, typeName); HCRListener listener = new HCRListener(); JDIDebugModel.addHotCodeReplaceListener(listener); IJavaThread thread= null; try { thread= launchToBreakpoint(typeName); assertNotNull("Breakpoint not hit within timeout period", thread); IJavaDebugTarget target = (IJavaDebugTarget)thread.getDebugTarget(); if (target.supportsHotCodeReplace()) { IJavaStackFrame frame = (IJavaStackFrame)thread.getTopStackFrame(); assertEquals("We should be stopped in the local type", "org.eclipse.debug.tests.targets.HcrClass2$2$Local", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 33", 33, frame.getLineNumber()); ICompilationUnit cu = getCompilationUnit(get14Project(), "src", "org.eclipse.debug.tests.targets", "HcrClass2.java"); cu = cu.getPrimary(); if (!cu.isWorkingCopy()) { cu = cu.getWorkingCopy(null); } assertTrue("HcrClass2.java does not exist", cu.exists()); IBuffer buffer = cu.getBuffer(); String contents = buffer.getContents(); int index = contents.indexOf("\"Local#run()\""); assertTrue("Could not find code to replace", index > 0); String newCode = contents.substring(0, index) + "\"Local#run\"" + contents.substring(index + 13); buffer.setContents(newCode); DebugEventWaiter waiter = new DebugEventWaiter(DebugEvent.SUSPEND); cu.commitWorkingCopy(true, null); waitForBuild(); thread = (IJavaThread) waiter.waitForEvent(); assertTrue("Listener should have been notified", listener.waitNotification()); assertNotNull("HCR should have not failed", listener.target); assertTrue("the thread should be suspended again after the HCR", thread.isSuspended()); frame = (IJavaStackFrame) thread.getTopStackFrame(); assertEquals("We should be stopped in the local type", "org.eclipse.debug.tests.targets.HcrClass2$2$Local", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 33", 33, frame.getLineNumber()); } else { System.err.println("Warning: HCR test skipped since target VM does not support HCR."); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); JDIDebugModel.removeHotCodeReplaceListener(listener); } } /** * Tests HCR in a local type * @throws Exception * * @since 3.8.100 */ public void testHCRLocalType2() throws Exception { String typeName = "org.eclipse.debug.tests.targets.HcrClass2"; createLineBreakpoint(37, typeName); HCRListener listener = new HCRListener(); JDIDebugModel.addHotCodeReplaceListener(listener); IJavaThread thread= null; try { thread= launchToBreakpoint(typeName); assertNotNull("Breakpoint not hit within timeout period", thread); IJavaDebugTarget target = (IJavaDebugTarget)thread.getDebugTarget(); if (target.supportsHotCodeReplace()) { IJavaStackFrame frame = (IJavaStackFrame)thread.getTopStackFrame(); assertEquals("We should be stopped in the local type", "org.eclipse.debug.tests.targets.HcrClass2$2$Local", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 37", 37, frame.getLineNumber()); ICompilationUnit cu = getCompilationUnit(get14Project(), "src", "org.eclipse.debug.tests.targets", "HcrClass2.java"); cu = cu.getPrimary(); if (!cu.isWorkingCopy()) { cu = cu.getWorkingCopy(null); } assertTrue("HcrClass2.java does not exist", cu.exists()); IBuffer buffer = cu.getBuffer(); String contents = buffer.getContents(); int index = contents.indexOf("\"Local#run2()\""); assertTrue("Could not find code to replace", index > 0); String newCode = contents.substring(0, index) + "\"Local#run2\"" + contents.substring(index + 14); buffer.setContents(newCode); DebugEventWaiter waiter = new DebugEventWaiter(DebugEvent.SUSPEND); cu.commitWorkingCopy(true, null); waitForBuild(); thread = (IJavaThread) waiter.waitForEvent(); assertTrue("Listener should have been notified", listener.waitNotification()); assertNotNull("HCR should have not failed", listener.target); assertTrue("the thread should be suspended again after the HCR", thread.isSuspended()); frame = (IJavaStackFrame) thread.getTopStackFrame(); assertEquals("We should be stopped in the local type", "org.eclipse.debug.tests.targets.HcrClass2$2$Local", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 37", 37, frame.getLineNumber()); } else { System.err.println("Warning: HCR test skipped since target VM does not support HCR."); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); JDIDebugModel.removeHotCodeReplaceListener(listener); } } /** * Tests HCR in a local type defined in a constructor * @throws Exception * * @since 3.8.100 */ public void testHCRLocalType3() throws Exception { String typeName = "org.eclipse.debug.tests.targets.HcrClass2"; createLineBreakpoint(19, typeName); HCRListener listener = new HCRListener(); JDIDebugModel.addHotCodeReplaceListener(listener); IJavaThread thread= null; try { thread= launchToBreakpoint(typeName); assertNotNull("Breakpoint not hit within timeout period", thread); IJavaDebugTarget target = (IJavaDebugTarget)thread.getDebugTarget(); if (target.supportsHotCodeReplace()) { IJavaStackFrame frame = (IJavaStackFrame)thread.getTopStackFrame(); assertEquals("We should be stopped in the local type", "org.eclipse.debug.tests.targets.HcrClass2$1$Local", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 19", 19, frame.getLineNumber()); ICompilationUnit cu = getCompilationUnit(get14Project(), "src", "org.eclipse.debug.tests.targets", "HcrClass2.java"); cu = cu.getPrimary(); if (!cu.isWorkingCopy()) { cu = cu.getWorkingCopy(null); } assertTrue("HcrClass2.java does not exist", cu.exists()); IBuffer buffer = cu.getBuffer(); String contents = buffer.getContents(); int index = contents.indexOf("\"CLocal#run()\""); assertTrue("Could not find code to replace", index > 0); String newCode = contents.substring(0, index) + "\"CLocal#run\"" + contents.substring(index + 14); buffer.setContents(newCode); DebugEventWaiter waiter = new DebugEventWaiter(DebugEvent.SUSPEND); cu.commitWorkingCopy(true, null); waitForBuild(); thread = (IJavaThread) waiter.waitForEvent(); assertTrue("Listener should have been notified", listener.waitNotification()); assertNotNull("HCR should have not failed", listener.target); assertTrue("the thread should be suspended again after the HCR", thread.isSuspended()); frame = (IJavaStackFrame) thread.getTopStackFrame(); assertEquals("We should be stopped in the local type", "org.eclipse.debug.tests.targets.HcrClass2$1$Local", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 19", 19, frame.getLineNumber()); } else { System.err.println("Warning: HCR test skipped since target VM does not support HCR."); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); JDIDebugModel.removeHotCodeReplaceListener(listener); } } /** * Tests HCR in an anonymous type with the same name as the method * where the anonymous type was defined * * @throws Exception * @since 3.8.100 */ public void testHCRAnonymousType() throws Exception { String typeName = "org.eclipse.debug.tests.targets.HcrClass3"; createLineBreakpoint(34, typeName); HCRListener listener = new HCRListener(); JDIDebugModel.addHotCodeReplaceListener(listener); IJavaThread thread= null; try { thread= launchToBreakpoint(typeName); assertNotNull("Breakpoint not hit within timeout period", thread); IJavaDebugTarget target = (IJavaDebugTarget)thread.getDebugTarget(); if (target.supportsHotCodeReplace()) { IJavaStackFrame frame = (IJavaStackFrame)thread.getTopStackFrame(); assertEquals("We should be stopped in the anonymous type", "org.eclipse.debug.tests.targets.HcrClass3$2", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 34", 34, frame.getLineNumber()); ICompilationUnit cu = getCompilationUnit(get14Project(), "src", "org.eclipse.debug.tests.targets", "HcrClass3.java"); cu = cu.getPrimary(); if (!cu.isWorkingCopy()) { cu = cu.getWorkingCopy(null); } assertTrue("HcrClass3.java does not exist", cu.exists()); IBuffer buffer = cu.getBuffer(); String contents = buffer.getContents(); int index = contents.indexOf("\"TEST_RUN1\""); assertTrue("Could not find code to replace", index > 0); String newCode = contents.substring(0, index) + "\"NEW_CODE\"" + contents.substring(index + 11); buffer.setContents(newCode); DebugEventWaiter waiter = new DebugEventWaiter(DebugEvent.SUSPEND); cu.commitWorkingCopy(true, null); waitForBuild(); thread = (IJavaThread) waiter.waitForEvent(); assertNotNull("Thread did not suspend after HCR", thread); assertTrue("Listener should have been notified", listener.waitNotification()); assertNotNull("HCR should have not failed", listener.target); assertTrue("the thread should be suspended again after the HCR", thread.isSuspended()); frame = (IJavaStackFrame) thread.getTopStackFrame(); assertEquals("We should be stopped in the anonymous type", "org.eclipse.debug.tests.targets.HcrClass3$2", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 34", 34, frame.getLineNumber()); } else { System.err.println("Warning: HCR test skipped since target VM does not support HCR."); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); JDIDebugModel.removeHotCodeReplaceListener(listener); } } /** * Tests HCR in an anonymous type defined in a method * @throws Exception * @since 3.8.100 */ public void testHCRAnonymousType2() throws Exception { String typeName = "org.eclipse.debug.tests.targets.HcrClass3"; createLineBreakpoint(44, typeName); HCRListener listener = new HCRListener(); JDIDebugModel.addHotCodeReplaceListener(listener); IJavaThread thread= null; try { thread= launchToBreakpoint(typeName); assertNotNull("Breakpoint not hit within timeout period", thread); IJavaDebugTarget target = (IJavaDebugTarget)thread.getDebugTarget(); if (target.supportsHotCodeReplace()) { IJavaStackFrame frame = (IJavaStackFrame)thread.getTopStackFrame(); assertEquals("We should be stopped in the anonymous type", "org.eclipse.debug.tests.targets.HcrClass3$3", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 44", 44, frame.getLineNumber()); ICompilationUnit cu = getCompilationUnit(get14Project(), "src", "org.eclipse.debug.tests.targets", "HcrClass3.java"); cu = cu.getPrimary(); if (!cu.isWorkingCopy()) { cu = cu.getWorkingCopy(null); } assertTrue("HcrClass3.java does not exist", cu.exists()); IBuffer buffer = cu.getBuffer(); String contents = buffer.getContents(); int index = contents.indexOf("\"TEST_RUN2\""); assertTrue("Could not find code to replace", index > 0); String newCode = contents.substring(0, index) + "\"NEW_CODE\"" + contents.substring(index + 11); buffer.setContents(newCode); DebugEventWaiter waiter = new DebugEventWaiter(DebugEvent.SUSPEND); cu.commitWorkingCopy(true, null); waitForBuild(); thread = (IJavaThread) waiter.waitForEvent(); assertTrue("Listener should have been notified", listener.waitNotification()); assertNotNull("HCR should have not failed", listener.target); assertTrue("the thread should be suspended again after the HCR", thread.isSuspended()); frame = (IJavaStackFrame) thread.getTopStackFrame(); assertEquals("We should be stopped in the anonymous type", "org.eclipse.debug.tests.targets.HcrClass3$3", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 44", 44, frame.getLineNumber()); } else { System.err.println("Warning: HCR test skipped since target VM does not support HCR."); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); JDIDebugModel.removeHotCodeReplaceListener(listener); } } /** * Tests HCR in an anonymous type defined in a constructor * @throws Exception * @since 3.8.100 */ public void testHCRAnonymousType3() throws Exception { String typeName = "org.eclipse.debug.tests.targets.HcrClass3"; createLineBreakpoint(24, typeName); HCRListener listener = new HCRListener(); JDIDebugModel.addHotCodeReplaceListener(listener); IJavaThread thread= null; try { thread= launchToBreakpoint(typeName); assertNotNull("Breakpoint not hit within timeout period", thread); IJavaDebugTarget target = (IJavaDebugTarget)thread.getDebugTarget(); if (target.supportsHotCodeReplace()) { IJavaStackFrame frame = (IJavaStackFrame)thread.getTopStackFrame(); assertEquals("We should be stopped in the anonymous type", "org.eclipse.debug.tests.targets.HcrClass3$1", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 24", 24, frame.getLineNumber()); ICompilationUnit cu = getCompilationUnit(get14Project(), "src", "org.eclipse.debug.tests.targets", "HcrClass3.java"); cu = cu.getPrimary(); if (!cu.isWorkingCopy()) { cu = cu.getWorkingCopy(null); } assertTrue("HcrClass3.java does not exist", cu.exists()); IBuffer buffer = cu.getBuffer(); String contents = buffer.getContents(); int index = contents.indexOf("\"TEST_RUN3\""); assertTrue("Could not find code to replace", index > 0); String newCode = contents.substring(0, index) + "\"NEW_CODE\"" + contents.substring(index + 11); buffer.setContents(newCode); DebugEventWaiter waiter = new DebugEventWaiter(DebugEvent.SUSPEND); cu.commitWorkingCopy(true, null); waitForBuild(); thread = (IJavaThread) waiter.waitForEvent(); assertTrue("Listener should have been notified", listener.waitNotification()); assertNotNull("HCR should have not failed", listener.target); assertTrue("the thread should be suspended again after the HCR", thread.isSuspended()); frame = (IJavaStackFrame) thread.getTopStackFrame(); assertEquals("We should be stopped in the anonymous type", "org.eclipse.debug.tests.targets.HcrClass3$1", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 24", 24, frame.getLineNumber()); } else { System.err.println("Warning: HCR test skipped since target VM does not support HCR."); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); JDIDebugModel.removeHotCodeReplaceListener(listener); } } /** * Tests HCR on a method called from a constructor * @throws Exception * @since 3.8.100 */ public void testHCRConstructor() throws Exception { String typeName = "org.eclipse.debug.tests.targets.HcrClass4"; createLineBreakpoint(21, typeName); HCRListener listener = new HCRListener(); JDIDebugModel.addHotCodeReplaceListener(listener); IJavaThread thread= null; try { thread= launchToBreakpoint(typeName); assertNotNull("Breakpoint not hit within timeout period", thread); IJavaDebugTarget target = (IJavaDebugTarget)thread.getDebugTarget(); if (target.supportsHotCodeReplace()) { IJavaStackFrame frame = (IJavaStackFrame)thread.getTopStackFrame(); assertEquals("We should be stopped in the run() method", "run", frame.getMethodName()); assertEquals("We shoud be stopped on line 21", 21, frame.getLineNumber()); ICompilationUnit cu = getCompilationUnit(get14Project(), "src", "org.eclipse.debug.tests.targets", "HcrClass4.java"); cu = cu.getPrimary(); if (!cu.isWorkingCopy()) { cu = cu.getWorkingCopy(null); } assertTrue("HcrClass4.java does not exist", cu.exists()); IBuffer buffer = cu.getBuffer(); String contents = buffer.getContents(); int index = contents.indexOf("\"HcrClass4#run()\""); assertTrue("Could not find code to replace", index > 0); String newCode = contents.substring(0, index) + "\"HcrClass4#run\"" + contents.substring(index + 17); buffer.setContents(newCode); DebugEventWaiter waiter = new DebugEventWaiter(DebugEvent.SUSPEND); cu.commitWorkingCopy(true, null); waitForBuild(); thread = (IJavaThread) waiter.waitForEvent(); assertTrue("Listener should have been notified", listener.waitNotification()); assertNotNull("HCR should have not failed", listener.target); assertTrue("the thread should be suspended again after the HCR", thread.isSuspended()); frame = (IJavaStackFrame) thread.getTopStackFrame(); assertEquals("We should be stopped in the run() method", "run", frame.getMethodName()); assertEquals("We shoud be stopped on line 21", 21, frame.getLineNumber()); } else { System.err.println("Warning: HCR test skipped since target VM does not support HCR."); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); JDIDebugModel.removeHotCodeReplaceListener(listener); } } /** * Tests HCR within a constructor * @throws Exception * @since 3.8.100 */ public void testHCRConstructor2() throws Exception { String typeName = "org.eclipse.debug.tests.targets.HcrClass4"; createLineBreakpoint(16, typeName); HCRListener listener = new HCRListener(); JDIDebugModel.addHotCodeReplaceListener(listener); IJavaThread thread= null; try { thread= launchToBreakpoint(typeName); assertNotNull("Breakpoint not hit within timeout period", thread); IJavaDebugTarget target = (IJavaDebugTarget)thread.getDebugTarget(); if (target.supportsHotCodeReplace()) { IJavaStackFrame frame = (IJavaStackFrame)thread.getTopStackFrame(); assertEquals("We should be stopped in the constuctor method", "<init>", frame.getMethodName()); assertEquals("We shoud be stopped on line 16", 16, frame.getLineNumber()); ICompilationUnit cu = getCompilationUnit(get14Project(), "src", "org.eclipse.debug.tests.targets", "HcrClass4.java"); cu = cu.getPrimary(); if (!cu.isWorkingCopy()) { cu = cu.getWorkingCopy(null); } assertTrue("HcrClass4.java does not exist", cu.exists()); IBuffer buffer = cu.getBuffer(); String contents = buffer.getContents(); int index = contents.indexOf("\"Constructor\""); assertTrue("Could not find code to replace", index > 0); String newCode = contents.substring(0, index) + "\"Construct\"" + contents.substring(index + 13); buffer.setContents(newCode); DebugEventWaiter waiter = new DebugEventWaiter(DebugEvent.SUSPEND); cu.commitWorkingCopy(true, null); waitForBuild(); thread = (IJavaThread) waiter.waitForEvent(); assertTrue("Listener should have been notified", listener.waitNotification()); assertNotNull("HCR should have not failed", listener.target); assertTrue("the thread should be suspended again after the HCR", thread.isSuspended()); frame = (IJavaStackFrame) thread.getTopStackFrame(); assertEquals("We should be stopped in the constructor method", "<init>", frame.getMethodName()); //after HCR constructors re-enter assertEquals("We shoud be stopped on line 15", 15, frame.getLineNumber()); } else { System.err.println("Warning: HCR test skipped since target VM does not support HCR."); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); JDIDebugModel.removeHotCodeReplaceListener(listener); } } /** * Tests HCR on an inner type method with the same name as the enclosing type * method it was called from * @throws Exception * @since 3.8.100 */ public void testHCRInnerType() throws Exception { String typeName = "org.eclipse.debug.tests.targets.HcrClass5"; createLineBreakpoint(23, typeName); HCRListener listener = new HCRListener(); JDIDebugModel.addHotCodeReplaceListener(listener); IJavaThread thread= null; try { thread= launchToBreakpoint(typeName); assertNotNull("Breakpoint not hit within timeout period", thread); IJavaDebugTarget target = (IJavaDebugTarget)thread.getDebugTarget(); if (target.supportsHotCodeReplace()) { IJavaStackFrame frame = (IJavaStackFrame)thread.getTopStackFrame(); assertEquals("We should be stopped in the run() method", "run", frame.getMethodName()); assertEquals("We should be stopped in the HcrClass5$InnerClass type", "org.eclipse.debug.tests.targets.HcrClass5$InnerClass", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 23", 23, frame.getLineNumber()); ICompilationUnit cu = getCompilationUnit(get14Project(), "src", "org.eclipse.debug.tests.targets", "HcrClass5.java"); cu = cu.getPrimary(); if (!cu.isWorkingCopy()) { cu = cu.getWorkingCopy(null); } assertTrue("HcrClass5.java does not exist", cu.exists()); IBuffer buffer = cu.getBuffer(); String contents = buffer.getContents(); int index = contents.indexOf("\"InnerClass#run()\""); assertTrue("Could not find code to replace", index > 0); String newCode = contents.substring(0, index) + "\"InnerClass#run\"" + contents.substring(index + 18); buffer.setContents(newCode); DebugEventWaiter waiter = new DebugEventWaiter(DebugEvent.SUSPEND); cu.commitWorkingCopy(true, null); waitForBuild(); thread = (IJavaThread) waiter.waitForEvent(); assertTrue("Listener should have been notified", listener.waitNotification()); assertNotNull("HCR should have not failed", listener.target); assertTrue("the thread should be suspended again after the HCR", thread.isSuspended()); frame = (IJavaStackFrame) thread.getTopStackFrame(); assertEquals("We should be stopped in the run() method", "run", frame.getMethodName()); assertEquals("We should be stopped in the HcrClass5$InnerClass type", "org.eclipse.debug.tests.targets.HcrClass5$InnerClass", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 23", 23, frame.getLineNumber()); } else { System.err.println("Warning: HCR test skipped since target VM does not support HCR."); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); JDIDebugModel.removeHotCodeReplaceListener(listener); } } /** * Tests HCR on an inner type method * @throws Exception * @since 3.8.100 */ public void testHCRInnerType2() throws Exception { String typeName = "org.eclipse.debug.tests.targets.HcrClass5"; createLineBreakpoint(27, typeName); HCRListener listener = new HCRListener(); JDIDebugModel.addHotCodeReplaceListener(listener); IJavaThread thread= null; try { thread= launchToBreakpoint(typeName); assertNotNull("Breakpoint not hit within timeout period", thread); IJavaDebugTarget target = (IJavaDebugTarget)thread.getDebugTarget(); if (target.supportsHotCodeReplace()) { IJavaStackFrame frame = (IJavaStackFrame)thread.getTopStackFrame(); assertEquals("We should be stopped in the run2() method", "run2", frame.getMethodName()); assertEquals("We should be stopped in the HcrClass5$InnerClass type", "org.eclipse.debug.tests.targets.HcrClass5$InnerClass", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 27", 27, frame.getLineNumber()); ICompilationUnit cu = getCompilationUnit(get14Project(), "src", "org.eclipse.debug.tests.targets", "HcrClass5.java"); cu = cu.getPrimary(); if (!cu.isWorkingCopy()) { cu = cu.getWorkingCopy(null); } assertTrue("HcrClass5.java does not exist", cu.exists()); IBuffer buffer = cu.getBuffer(); String contents = buffer.getContents(); int index = contents.indexOf("\"InnerClass#run2()\""); assertTrue("Could not find code to replace", index > 0); String newCode = contents.substring(0, index) + "\"InnerClass#run2\"" + contents.substring(index + 19); buffer.setContents(newCode); DebugEventWaiter waiter = new DebugEventWaiter(DebugEvent.SUSPEND); cu.commitWorkingCopy(true, null); waitForBuild(); thread = (IJavaThread) waiter.waitForEvent(); assertTrue("Listener should have been notified", listener.waitNotification()); assertNotNull("HCR should have not failed", listener.target); assertTrue("the thread should be suspended again after the HCR", thread.isSuspended()); frame = (IJavaStackFrame) thread.getTopStackFrame(); assertEquals("We should be stopped in the run2() method", "run2", frame.getMethodName()); assertEquals("We should be stopped in the HcrClass5$InnerClass type", "org.eclipse.debug.tests.targets.HcrClass5$InnerClass", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 27", 27, frame.getLineNumber()); } else { System.err.println("Warning: HCR test skipped since target VM does not support HCR."); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); JDIDebugModel.removeHotCodeReplaceListener(listener); } } /** * Tests HCR on a constructor in an inner type * @throws Exception * @since 3.8.100 */ public void testHCRInnerType3() throws Exception { String typeName = "org.eclipse.debug.tests.targets.HcrClass5"; createLineBreakpoint(18, typeName); HCRListener listener = new HCRListener(); JDIDebugModel.addHotCodeReplaceListener(listener); IJavaThread thread= null; try { thread= launchToBreakpoint(typeName); assertNotNull("Breakpoint not hit within timeout period", thread); IJavaDebugTarget target = (IJavaDebugTarget)thread.getDebugTarget(); if (target.supportsHotCodeReplace()) { IJavaStackFrame frame = (IJavaStackFrame)thread.getTopStackFrame(); assertEquals("We should be stopped in the <init> method", "<init>", frame.getMethodName()); assertEquals("We should be stopped in the HcrClass5$InnerClass type", "org.eclipse.debug.tests.targets.HcrClass5$InnerClass", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 18", 18, frame.getLineNumber()); ICompilationUnit cu = getCompilationUnit(get14Project(), "src", "org.eclipse.debug.tests.targets", "HcrClass5.java"); cu = cu.getPrimary(); if (!cu.isWorkingCopy()) { cu = cu.getWorkingCopy(null); } assertTrue("HcrClass5.java does not exist", cu.exists()); IBuffer buffer = cu.getBuffer(); String contents = buffer.getContents(); int index = contents.indexOf("\"Constructor\""); assertTrue("Could not find code to replace", index > 0); String newCode = contents.substring(0, index) + "\"Construct\"" + contents.substring(index + 13); buffer.setContents(newCode); DebugEventWaiter waiter = new DebugEventWaiter(DebugEvent.SUSPEND); cu.commitWorkingCopy(true, null); waitForBuild(); thread = (IJavaThread) waiter.waitForEvent(); assertTrue("Listener should have been notified", listener.waitNotification()); assertNotNull("HCR should have not failed", listener.target); assertTrue("the thread should be suspended again after the HCR", thread.isSuspended()); frame = (IJavaStackFrame) thread.getTopStackFrame(); assertEquals("We should be stopped in the <init> method", "<init>", frame.getMethodName()); assertEquals("We should be stopped in the HcrClass5$InnerClass type", "org.eclipse.debug.tests.targets.HcrClass5$InnerClass", frame.getDeclaringTypeName()); //after HCR constructors re-enter assertEquals("We shoud be stopped on line 17", 17, frame.getLineNumber()); } else { System.err.println("Warning: HCR test skipped since target VM does not support HCR."); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); JDIDebugModel.removeHotCodeReplaceListener(listener); } } /** * Tests HCR on an enclosing method called from an inner type * method with the same name * @throws Exception * @since 3.8.100 */ public void testHCRInnerType4() throws Exception { String typeName = "org.eclipse.debug.tests.targets.HcrClass5"; createLineBreakpoint(33, typeName); HCRListener listener = new HCRListener(); JDIDebugModel.addHotCodeReplaceListener(listener); IJavaThread thread= null; try { thread= launchToBreakpoint(typeName); assertNotNull("Breakpoint not hit within timeout period", thread); IJavaDebugTarget target = (IJavaDebugTarget)thread.getDebugTarget(); if (target.supportsHotCodeReplace()) { IJavaStackFrame frame = (IJavaStackFrame)thread.getTopStackFrame(); assertEquals("We should be stopped in the run() method", "run", frame.getMethodName()); assertEquals("We should be stopped in the HcrClass5 type", "org.eclipse.debug.tests.targets.HcrClass5", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 33", 33, frame.getLineNumber()); ICompilationUnit cu = getCompilationUnit(get14Project(), "src", "org.eclipse.debug.tests.targets", "HcrClass5.java"); cu = cu.getPrimary(); if (!cu.isWorkingCopy()) { cu = cu.getWorkingCopy(null); } assertTrue("HcrClass5.java does not exist", cu.exists()); IBuffer buffer = cu.getBuffer(); String contents = buffer.getContents(); int index = contents.indexOf("\"LocalHCR#run()\""); assertTrue("Could not find code to replace", index > 0); String newCode = contents.substring(0, index) + "\"LocalHCR#run\"" + contents.substring(index + 16); buffer.setContents(newCode); DebugEventWaiter waiter = new DebugEventWaiter(DebugEvent.SUSPEND); cu.commitWorkingCopy(true, null); waitForBuild(); thread = (IJavaThread) waiter.waitForEvent(); assertTrue("Listener should have been notified", listener.waitNotification()); assertNotNull("HCR should have not failed", listener.target); assertTrue("the thread should be suspended again after the HCR", thread.isSuspended()); frame = (IJavaStackFrame) thread.getTopStackFrame(); assertEquals("We should be stopped in the run method", "run", frame.getMethodName()); assertEquals("We should be stopped in the HcrClass5 type", "org.eclipse.debug.tests.targets.HcrClass5", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 33", 33, frame.getLineNumber()); } else { System.err.println("Warning: HCR test skipped since target VM does not support HCR."); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); JDIDebugModel.removeHotCodeReplaceListener(listener); } } /** * Tests HCR on an enclosing method called from an inner type * method * @throws Exception * @since 3.8.100 */ public void testHCRInnerType5() throws Exception { String typeName = "org.eclipse.debug.tests.targets.HcrClass5"; createLineBreakpoint(37, typeName); HCRListener listener = new HCRListener(); JDIDebugModel.addHotCodeReplaceListener(listener); IJavaThread thread= null; try { thread= launchToBreakpoint(typeName); assertNotNull("Breakpoint not hit within timeout period", thread); IJavaDebugTarget target = (IJavaDebugTarget)thread.getDebugTarget(); if (target.supportsHotCodeReplace()) { IJavaStackFrame frame = (IJavaStackFrame)thread.getTopStackFrame(); assertEquals("We should be stopped in the outerrun() method", "outerrun", frame.getMethodName()); assertEquals("We should be stopped in the HcrClass5 type", "org.eclipse.debug.tests.targets.HcrClass5", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 37", 37, frame.getLineNumber()); ICompilationUnit cu = getCompilationUnit(get14Project(), "src", "org.eclipse.debug.tests.targets", "HcrClass5.java"); cu = cu.getPrimary(); if (!cu.isWorkingCopy()) { cu = cu.getWorkingCopy(null); } assertTrue("HcrClass5.java does not exist", cu.exists()); IBuffer buffer = cu.getBuffer(); String contents = buffer.getContents(); int index = contents.indexOf("\"LocalHCR#outerrun()\""); assertTrue("Could not find code to replace", index > 0); String newCode = contents.substring(0, index) + "\"LocalHCR#outerrun\"" + contents.substring(index +21); buffer.setContents(newCode); DebugEventWaiter waiter = new DebugEventWaiter(DebugEvent.SUSPEND); cu.commitWorkingCopy(true, null); waitForBuild(); thread = (IJavaThread) waiter.waitForEvent(); assertTrue("Listener should have been notified", listener.waitNotification()); assertNotNull("HCR should have not failed", listener.target); assertTrue("the thread should be suspended again after the HCR", thread.isSuspended()); frame = (IJavaStackFrame) thread.getTopStackFrame(); assertEquals("We should be stopped in the outerrun method", "outerrun", frame.getMethodName()); assertEquals("We should be stopped in the HcrClass5 type", "org.eclipse.debug.tests.targets.HcrClass5", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 37", 37, frame.getLineNumber()); } else { System.err.println("Warning: HCR test skipped since target VM does not support HCR."); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); JDIDebugModel.removeHotCodeReplaceListener(listener); } } /** * Tests HCR on a local type defined in an inner type * @throws Exception * @since 3.8.100 */ public void testHCRLocalInner() throws Exception { String typeName = "org.eclipse.debug.tests.targets.HcrClass9"; createLineBreakpoint(19, typeName); HCRListener listener = new HCRListener(); JDIDebugModel.addHotCodeReplaceListener(listener); IJavaThread thread= null; try { thread= launchToBreakpoint(typeName); assertNotNull("Breakpoint not hit within timeout period", thread); IJavaDebugTarget target = (IJavaDebugTarget)thread.getDebugTarget(); if (target.supportsHotCodeReplace()) { IJavaStackFrame frame = (IJavaStackFrame)thread.getTopStackFrame(); assertEquals("We should be stopped in the run() method", "run", frame.getMethodName()); assertEquals("We should be stopped in the HcrClass9$1$Local type", "org.eclipse.debug.tests.targets.HcrClass9$1$Local", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 19", 19, frame.getLineNumber()); ICompilationUnit cu = getCompilationUnit(get14Project(), "src", "org.eclipse.debug.tests.targets", "HcrClass9.java"); cu = cu.getPrimary(); if (!cu.isWorkingCopy()) { cu = cu.getWorkingCopy(null); } assertTrue("HcrClass9.java does not exist", cu.exists()); IBuffer buffer = cu.getBuffer(); String contents = buffer.getContents(); int index = contents.indexOf("\"Inner$Local#run()\""); assertTrue("Could not find code to replace", index > 0); String newCode = contents.substring(0, index) + "\"Inner$Local#run\"" + contents.substring(index +19); buffer.setContents(newCode); DebugEventWaiter waiter = new DebugEventWaiter(DebugEvent.SUSPEND); cu.commitWorkingCopy(true, null); waitForBuild(); thread = (IJavaThread) waiter.waitForEvent(); assertTrue("Listener should have been notified", listener.waitNotification()); assertNotNull("HCR should have not failed", listener.target); assertTrue("the thread should be suspended again after the HCR", thread.isSuspended()); frame = (IJavaStackFrame) thread.getTopStackFrame(); assertEquals("We should be stopped in the run method", "run", frame.getMethodName()); assertEquals("We should be stopped in the HcrClass9$1$Local type", "org.eclipse.debug.tests.targets.HcrClass9$1$Local", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 19", 19, frame.getLineNumber()); } else { System.err.println("Warning: HCR test skipped since target VM does not support HCR."); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); JDIDebugModel.removeHotCodeReplaceListener(listener); } } /** * Tests HCR on a local type defined in an anonymous type * @throws Exception * @since 3.8.100 */ public void testHCRLocalAnonymous() throws Exception { String typeName = "org.eclipse.debug.tests.targets.HcrClass8"; createLineBreakpoint(24, typeName); HCRListener listener = new HCRListener(); JDIDebugModel.addHotCodeReplaceListener(listener); IJavaThread thread= null; try { thread= launchToBreakpoint(typeName); assertNotNull("Breakpoint not hit within timeout period", thread); IJavaDebugTarget target = (IJavaDebugTarget)thread.getDebugTarget(); if (target.supportsHotCodeReplace()) { IJavaStackFrame frame = (IJavaStackFrame)thread.getTopStackFrame(); assertEquals("We should be stopped in the run() method", "run", frame.getMethodName()); assertEquals("We should be stopped in the HcrClass8$1$Local type", "org.eclipse.debug.tests.targets.HcrClass8$1$Local", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 24", 24, frame.getLineNumber()); ICompilationUnit cu = getCompilationUnit(get14Project(), "src", "org.eclipse.debug.tests.targets", "HcrClass8.java"); cu = cu.getPrimary(); if (!cu.isWorkingCopy()) { cu = cu.getWorkingCopy(null); } assertTrue("HcrClass8.java does not exist", cu.exists()); IBuffer buffer = cu.getBuffer(); String contents = buffer.getContents(); int index = contents.indexOf("\"Inner$Local#run()\""); assertTrue("Could not find code to replace", index > 0); String newCode = contents.substring(0, index) + "\"Inner$Local#run\"" + contents.substring(index +19); buffer.setContents(newCode); DebugEventWaiter waiter = new DebugEventWaiter(DebugEvent.SUSPEND); cu.commitWorkingCopy(true, null); waitForBuild(); thread = (IJavaThread) waiter.waitForEvent(); assertTrue("Listener should have been notified", listener.waitNotification()); assertNotNull("HCR should have not failed", listener.target); assertTrue("the thread should be suspended again after the HCR", thread.isSuspended()); frame = (IJavaStackFrame) thread.getTopStackFrame(); assertEquals("We should be stopped in the run method", "run", frame.getMethodName()); assertEquals("We should be stopped in the HcrClass8$1$Local type", "org.eclipse.debug.tests.targets.HcrClass8$1$Local", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 24", 24, frame.getLineNumber()); } else { System.err.println("Warning: HCR test skipped since target VM does not support HCR."); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); JDIDebugModel.removeHotCodeReplaceListener(listener); } } /** * Tests HCR on an inner type defined in a local type * @throws Exception * @since 3.8.100 */ public void testHCRInnerLocal() throws Exception { String typeName = "org.eclipse.debug.tests.targets.HcrClass7"; createLineBreakpoint(19, typeName); HCRListener listener = new HCRListener(); JDIDebugModel.addHotCodeReplaceListener(listener); IJavaThread thread= null; try { thread= launchToBreakpoint(typeName); assertNotNull("Breakpoint not hit within timeout period", thread); IJavaDebugTarget target = (IJavaDebugTarget)thread.getDebugTarget(); if (target.supportsHotCodeReplace()) { IJavaStackFrame frame = (IJavaStackFrame)thread.getTopStackFrame(); assertEquals("We should be stopped in the run() method", "run", frame.getMethodName()); assertEquals("We should be stopped in the HcrClass7$1$Local$Inner type", "org.eclipse.debug.tests.targets.HcrClass7$1$Local$Inner", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 19", 19, frame.getLineNumber()); ICompilationUnit cu = getCompilationUnit(get14Project(), "src", "org.eclipse.debug.tests.targets", "HcrClass7.java"); cu = cu.getPrimary(); if (!cu.isWorkingCopy()) { cu = cu.getWorkingCopy(null); } assertTrue("HcrClass7.java does not exist", cu.exists()); IBuffer buffer = cu.getBuffer(); String contents = buffer.getContents(); int index = contents.indexOf("\"Local$Inner#run()\""); assertTrue("Could not find code to replace", index > 0); String newCode = contents.substring(0, index) + "\"Local$Inner#run\"" + contents.substring(index +19); buffer.setContents(newCode); DebugEventWaiter waiter = new DebugEventWaiter(DebugEvent.SUSPEND); cu.commitWorkingCopy(true, null); waitForBuild(); thread = (IJavaThread) waiter.waitForEvent(); assertTrue("Listener should have been notified", listener.waitNotification()); assertNotNull("HCR should have not failed", listener.target); assertTrue("the thread should be suspended again after the HCR", thread.isSuspended()); frame = (IJavaStackFrame) thread.getTopStackFrame(); assertEquals("We should be stopped in the run method", "run", frame.getMethodName()); assertEquals("We should be stopped in the HcrClass7$1$Local$Inner type", "org.eclipse.debug.tests.targets.HcrClass7$1$Local$Inner", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 19", 19, frame.getLineNumber()); } else { System.err.println("Warning: HCR test skipped since target VM does not support HCR."); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); JDIDebugModel.removeHotCodeReplaceListener(listener); } } /** * Tests HCR on an anonymous type defined in a local type * @throws Exception * @since 3.8.100 */ public void testHCRAnnonymousLocal() throws Exception { String typeName = "org.eclipse.debug.tests.targets.HcrClass6"; createLineBreakpoint(23, typeName); HCRListener listener = new HCRListener(); JDIDebugModel.addHotCodeReplaceListener(listener); IJavaThread thread= null; try { thread= launchToBreakpoint(typeName); assertNotNull("Breakpoint not hit within timeout period", thread); IJavaDebugTarget target = (IJavaDebugTarget)thread.getDebugTarget(); if (target.supportsHotCodeReplace()) { IJavaStackFrame frame = (IJavaStackFrame)thread.getTopStackFrame(); assertEquals("We should be stopped in the run() method", "run", frame.getMethodName()); assertEquals("We should be stopped in the HcrClass6$1 type", "org.eclipse.debug.tests.targets.HcrClass6$1", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 23", 23, frame.getLineNumber()); ICompilationUnit cu = getCompilationUnit(get14Project(), "src", "org.eclipse.debug.tests.targets", "HcrClass6.java"); cu = cu.getPrimary(); if (!cu.isWorkingCopy()) { cu = cu.getWorkingCopy(null); } assertTrue("HcrClass6.java does not exist", cu.exists()); IBuffer buffer = cu.getBuffer(); String contents = buffer.getContents(); int index = contents.indexOf("\"Local$Inner#run()\""); assertTrue("Could not find code to replace", index > 0); String newCode = contents.substring(0, index) + "\"Local$Inner#run\"" + contents.substring(index +19); buffer.setContents(newCode); DebugEventWaiter waiter = new DebugEventWaiter(DebugEvent.SUSPEND); cu.commitWorkingCopy(true, null); waitForBuild(); thread = (IJavaThread) waiter.waitForEvent(); assertTrue("Listener should have been notified", listener.waitNotification()); assertNotNull("HCR should have not failed", listener.target); assertTrue("the thread should be suspended again after the HCR", thread.isSuspended()); frame = (IJavaStackFrame) thread.getTopStackFrame(); assertEquals("We should be stopped in the run method", "run", frame.getMethodName()); assertEquals("We should be stopped in the HcrClass6$1 type", "org.eclipse.debug.tests.targets.HcrClass6$1", frame.getDeclaringTypeName()); assertEquals("We shoud be stopped on line 23", 23, frame.getLineNumber()); } else { System.err.println("Warning: HCR test skipped since target VM does not support HCR."); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); JDIDebugModel.removeHotCodeReplaceListener(listener); } } /** * Tests that HCR is NOT triggered if the code change is happened on an unrelated type, see bug 508524 and 5188 */ public void testNoHcrOnUnrelatedType() throws Exception { String typeName = "org.eclipse.debug.tests.targets.HcrClass"; IJavaProject unrelatedProject = get14Project(); IJavaProject debuggedProject = get15Project(); IType type1 = unrelatedProject.findType(typeName); IType type2 = debuggedProject.findType(typeName); assertNotEquals(type1, type2); // Types FQNs are same assertEquals(type1.getFullyQualifiedName(), type2.getFullyQualifiedName()); // Paths are same, except the project part assertEquals(type1.getResource().getFullPath().removeFirstSegments(1), type2.getResource().getFullPath().removeFirstSegments(1)); final int lineNumber = 39; IJavaLineBreakpoint bp1 = createLineBreakpoint(type1, lineNumber); IJavaLineBreakpoint bp2 = createLineBreakpoint(type2, lineNumber); assertNotEquals(bp1, bp2); HCRListener listener = new HCRListener(); HCRListener listener2 = new HCRListener(); JDIDebugModel.addHotCodeReplaceListener(listener); IJavaThread thread = null; try { // We start debugging on the one project but do modifications on the unrelated one! thread = launchToBreakpoint(debuggedProject, typeName, typeName + CLONE_SUFFIX, true); assertNotNull("Breakpoint not hit within timeout period", thread); IJavaDebugTarget target = (IJavaDebugTarget) thread.getDebugTarget(); if (target.supportsHotCodeReplace()) { target.addHotCodeReplaceListener(listener2); // look at the value of 'x' - it should be "One" IJavaStackFrame frame = (IJavaStackFrame) thread.getTopStackFrame(); IJavaVariable variable = findVariable(frame, "x"); assertNotNull("Could not find 'x'", variable); assertEquals("value of 'x' should be 'One'", "One", variable.getValue().getValueString()); removeAllBreakpoints(); // now modify the source in *unrelated* project => NO HCR should happen, even if type names are same! ICompilationUnit cu = getCompilationUnit(unrelatedProject, "src", "org.eclipse.debug.tests.targets", "HcrClass.java"); cu = cu.getPrimary(); if (!cu.isWorkingCopy()) { cu = cu.getWorkingCopy(null); } assertTrue("HcrClass.java does not exist", cu.exists()); IBuffer buffer = cu.getBuffer(); String contents = buffer.getContents(); int index = contents.indexOf("\"One\""); assertTrue("Could not find code to replace", index > 0); String newCode = contents.substring(0, index) + "\"Two\"" + contents.substring(index + 5); buffer.setContents(newCode); // save contents cu.commitWorkingCopy(true, null); waitForBuild(); assertFalse("Specific listener should not have been notified", listener2.waitNotification()); assertFalse("General listener should not have been notified", listener.wasNotified()); } else { System.err.println("Warning: HCR test skipped since target VM does not support HCR."); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); JDIDebugModel.removeHotCodeReplaceListener(listener); } } }