1 /******************************************************************************* 2 * Copyright (c) 2000, 2020 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 * Jesper Steen Møller - bug 422029: [1.8] Enable debug evaluation support for default methods 14 * Jesper Steen Møller - bug 426903: [1.8] Cannot evaluate super call to default method 15 * Jesper Steen Møller - bug 341232 16 *******************************************************************************/ 17 package org.eclipse.jdt.debug.tests; 18 19 import java.io.File; 20 import java.io.PrintWriter; 21 import java.io.StringWriter; 22 import java.util.ArrayList; 23 import java.util.Arrays; 24 import java.util.Collection; 25 import java.util.Collections; 26 import java.util.HashMap; 27 import java.util.HashSet; 28 import java.util.List; 29 import java.util.Map; 30 import java.util.Set; 31 import java.util.stream.Collectors; 32 33 import org.eclipse.core.resources.IFile; 34 import org.eclipse.core.resources.IFolder; 35 import org.eclipse.core.resources.IMarker; 36 import org.eclipse.core.resources.IMarkerDelta; 37 import org.eclipse.core.resources.IProject; 38 import org.eclipse.core.resources.IResource; 39 import org.eclipse.core.resources.IncrementalProjectBuilder; 40 import org.eclipse.core.resources.ResourcesPlugin; 41 import org.eclipse.core.runtime.CoreException; 42 import org.eclipse.core.runtime.IPath; 43 import org.eclipse.core.runtime.IProgressMonitor; 44 import org.eclipse.core.runtime.IStatus; 45 import org.eclipse.core.runtime.OperationCanceledException; 46 import org.eclipse.core.runtime.Path; 47 import org.eclipse.core.runtime.Platform; 48 import org.eclipse.core.runtime.Status; 49 import org.eclipse.core.runtime.jobs.Job; 50 import org.eclipse.core.runtime.preferences.IEclipsePreferences; 51 import org.eclipse.core.runtime.preferences.InstanceScope; 52 import org.eclipse.debug.core.DebugEvent; 53 import org.eclipse.debug.core.DebugException; 54 import org.eclipse.debug.core.DebugPlugin; 55 import org.eclipse.debug.core.IBreakpointListener; 56 import org.eclipse.debug.core.IBreakpointManager; 57 import org.eclipse.debug.core.ILaunch; 58 import org.eclipse.debug.core.ILaunchConfiguration; 59 import org.eclipse.debug.core.ILaunchConfigurationType; 60 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; 61 import org.eclipse.debug.core.ILaunchDelegate; 62 import org.eclipse.debug.core.ILaunchManager; 63 import org.eclipse.debug.core.model.IBreakpoint; 64 import org.eclipse.debug.core.model.IDebugTarget; 65 import org.eclipse.debug.core.model.ILineBreakpoint; 66 import org.eclipse.debug.core.model.IProcess; 67 import org.eclipse.debug.core.model.IThread; 68 import org.eclipse.debug.core.model.IValue; 69 import org.eclipse.debug.core.model.IVariable; 70 import org.eclipse.debug.internal.core.LaunchDelegate; 71 import org.eclipse.debug.internal.core.LaunchManager; 72 import org.eclipse.debug.internal.ui.DebugUIPlugin; 73 import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; 74 import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointOrganizer; 75 import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager; 76 import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationPresentationManager; 77 import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationsDialog; 78 import org.eclipse.debug.internal.ui.launchConfigurations.LaunchShortcutExtension; 79 import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants; 80 import org.eclipse.debug.internal.ui.views.breakpoints.BreakpointOrganizerManager; 81 import org.eclipse.debug.internal.ui.views.console.ProcessConsole; 82 import org.eclipse.debug.ui.DebugUITools; 83 import org.eclipse.debug.ui.IDebugModelPresentation; 84 import org.eclipse.debug.ui.IDebugUIConstants; 85 import org.eclipse.debug.ui.IDebugView; 86 import org.eclipse.debug.ui.ILaunchConfigurationDialog; 87 import org.eclipse.debug.ui.ILaunchConfigurationTabGroup; 88 import org.eclipse.debug.ui.actions.ToggleBreakpointAction; 89 import org.eclipse.jdt.core.IAccessRule; 90 import org.eclipse.jdt.core.IBuffer; 91 import org.eclipse.jdt.core.IClassFile; 92 import org.eclipse.jdt.core.IClasspathAttribute; 93 import org.eclipse.jdt.core.IClasspathEntry; 94 import org.eclipse.jdt.core.ICompilationUnit; 95 import org.eclipse.jdt.core.IField; 96 import org.eclipse.jdt.core.IJavaElement; 97 import org.eclipse.jdt.core.IJavaProject; 98 import org.eclipse.jdt.core.IMember; 99 import org.eclipse.jdt.core.IMethod; 100 import org.eclipse.jdt.core.IPackageFragment; 101 import org.eclipse.jdt.core.IPackageFragmentRoot; 102 import org.eclipse.jdt.core.ISourceRange; 103 import org.eclipse.jdt.core.IType; 104 import org.eclipse.jdt.core.JavaCore; 105 import org.eclipse.jdt.core.JavaModelException; 106 import org.eclipse.jdt.core.Signature; 107 import org.eclipse.jdt.debug.core.IJavaClassPrepareBreakpoint; 108 import org.eclipse.jdt.debug.core.IJavaDebugTarget; 109 import org.eclipse.jdt.debug.core.IJavaExceptionBreakpoint; 110 import org.eclipse.jdt.debug.core.IJavaLineBreakpoint; 111 import org.eclipse.jdt.debug.core.IJavaMethodBreakpoint; 112 import org.eclipse.jdt.debug.core.IJavaObject; 113 import org.eclipse.jdt.debug.core.IJavaPatternBreakpoint; 114 import org.eclipse.jdt.debug.core.IJavaStackFrame; 115 import org.eclipse.jdt.debug.core.IJavaStratumLineBreakpoint; 116 import org.eclipse.jdt.debug.core.IJavaTargetPatternBreakpoint; 117 import org.eclipse.jdt.debug.core.IJavaThread; 118 import org.eclipse.jdt.debug.core.IJavaVariable; 119 import org.eclipse.jdt.debug.core.IJavaWatchpoint; 120 import org.eclipse.jdt.debug.core.JDIDebugModel; 121 import org.eclipse.jdt.debug.eval.EvaluationManager; 122 import org.eclipse.jdt.debug.eval.IAstEvaluationEngine; 123 import org.eclipse.jdt.debug.eval.IEvaluationListener; 124 import org.eclipse.jdt.debug.eval.IEvaluationResult; 125 import org.eclipse.jdt.debug.testplugin.DebugElementEventWaiter; 126 import org.eclipse.jdt.debug.testplugin.DebugElementKindEventDetailWaiter; 127 import org.eclipse.jdt.debug.testplugin.DebugElementKindEventWaiter; 128 import org.eclipse.jdt.debug.testplugin.DebugEventWaiter; 129 import org.eclipse.jdt.debug.testplugin.JavaProjectHelper; 130 import org.eclipse.jdt.debug.testplugin.JavaTestPlugin; 131 import org.eclipse.jdt.debug.tests.core.LiteralTests17; 132 import org.eclipse.jdt.debug.tests.refactoring.MemberParser; 133 import org.eclipse.jdt.debug.ui.IJavaDebugUIConstants; 134 import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget; 135 import org.eclipse.jdt.internal.debug.eval.ast.engine.ASTEvaluationEngine; 136 import org.eclipse.jdt.internal.debug.ui.BreakpointUtils; 137 import org.eclipse.jdt.internal.debug.ui.IJDIPreferencesConstants; 138 import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin; 139 import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; 140 import org.eclipse.jdt.launching.IVMInstall; 141 import org.eclipse.jdt.launching.JavaRuntime; 142 import org.eclipse.jdt.launching.environments.IExecutionEnvironment; 143 import org.eclipse.jface.dialogs.ErrorDialog; 144 import org.eclipse.jface.dialogs.MessageDialogWithToggle; 145 import org.eclipse.jface.preference.IPreferenceStore; 146 import org.eclipse.jface.text.BadPositionCategoryException; 147 import org.eclipse.jface.text.Document; 148 import org.eclipse.jface.text.IDocument; 149 import org.eclipse.jface.text.IRegion; 150 import org.eclipse.jface.text.Position; 151 import org.eclipse.jface.text.source.IVerticalRulerInfo; 152 import org.eclipse.jface.util.SafeRunnable; 153 import org.eclipse.swt.widgets.Display; 154 import org.eclipse.ui.IEditorPart; 155 import org.eclipse.ui.IWorkbench; 156 import org.eclipse.ui.IWorkbenchPage; 157 import org.eclipse.ui.IWorkbenchWindow; 158 import org.eclipse.ui.PartInitException; 159 import org.eclipse.ui.PlatformUI; 160 import org.eclipse.ui.console.IConsole; 161 import org.eclipse.ui.console.IHyperlink; 162 import org.eclipse.ui.console.TextConsole; 163 import org.eclipse.ui.ide.IDE; 164 import org.eclipse.ui.internal.console.ConsoleHyperlinkPosition; 165 import org.eclipse.ui.intro.IIntroManager; 166 import org.eclipse.ui.intro.IIntroPart; 167 import org.eclipse.ui.progress.UIJob; 168 import org.eclipse.ui.progress.WorkbenchJob; 169 import org.osgi.service.prefs.BackingStoreException; 170 171 import com.sun.jdi.InternalException; 172 import com.sun.jdi.InvocationException; 173 174 import junit.framework.TestCase; 175 176 /** 177 * Tests for launch configurations 178 */ 179 @SuppressWarnings("deprecation") 180 public abstract class AbstractDebugTest extends TestCase implements IEvaluationListener { 181 182 public static final String MULTI_OUTPUT_PROJECT_NAME = "MultiOutput"; 183 public static final String BOUND_EE_PROJECT_NAME = "BoundEE"; 184 public static final String ONE_FOUR_PROJECT_NAME = "DebugTests"; 185 public static final String ONE_FOUR_PROJECT_CLOSED_NAME = "ClosedDebugTests"; 186 public static final String ONE_FIVE_PROJECT_NAME = "OneFive"; 187 public static final String ONE_SEVEN_PROJECT_NAME = "OneSeven"; 188 public static final String ONE_EIGHT_PROJECT_NAME = "OneEight"; 189 public static final String NINE_PROJECT_NAME = "Nine"; 190 public static final String BOUND_JRE_PROJECT_NAME = "BoundJRE"; 191 public static final String CLONE_SUFFIX = "Clone"; 192 193 final String[] LAUNCH_CONFIG_NAMES_1_4 = {"LargeSourceFile", "LotsOfFields", "Breakpoints", "InstanceVariablesTests", "LocalVariablesTests", "LocalVariableTests2", "StaticVariablesTests", 194 "DropTests", "ThrowsNPE", "ThrowsException", "org.eclipse.debug.tests.targets.Watchpoint", 195 "org.eclipse.debug.tests.targets.BreakpointsLocationBug344984", "org.eclipse.debug.tests.targets.CallLoop", "A", 196 "HitCountLooper", "CompileError", "MultiThreadedLoop", "HitCountException", "MultiThreadedException", "MultiThreadedList", "MethodLoop", "StepFilterOne", 197 "StepFilterFour", "EvalArrayTests", "EvalSimpleTests", "EvalTypeTests", "EvalNestedTypeTests", "EvalTypeHierarchyTests", 198 "EvalAnonymousClassVariableTests", "WorkingDirectoryTest", 199 "OneToTen", "OneToTenPrint", "FloodConsole", "ConditionalStepReturn", "VariableChanges", "DefPkgReturnType", "InstanceFilterObject", "org.eclipse.debug.tests.targets.CallStack", 200 "org.eclipse.debug.tests.targets.ThreadStack", "org.eclipse.debug.tests.targets.HcrClass", "org.eclipse.debug.tests.targets.StepIntoSelectionClass", 201 "WatchItemTests", "ArrayTests", "ByteArrayTests", "PerfLoop", "Console80Chars", "ConsoleStackTrace", "ConsoleVariableLineLength", "StackTraces", 202 "ConsoleInput", "PrintConcatenation", "VariableDetails", "org.eclipse.debug.tests.targets.ArrayDetailTests", "ArrayDetailTestsDef", "ForceReturnTests", 203 "ForceReturnTestsTwo", "LogicalStructures", "BreakpointListenerTest", "LaunchHistoryTest", "LaunchHistoryTest2", "RunnableAppletImpl", "java6.AllInstancesTests", 204 "bug329294", "bug401270", "org.eclipse.debug.tests.targets.HcrClass2", "org.eclipse.debug.tests.targets.HcrClass3", "org.eclipse.debug.tests.targets.HcrClass4", 205 "org.eclipse.debug.tests.targets.HcrClass5", "org.eclipse.debug.tests.targets.HcrClass6", "org.eclipse.debug.tests.targets.HcrClass7", "org.eclipse.debug.tests.targets.HcrClass8", 206 "org.eclipse.debug.tests.targets.HcrClass9", "TestContributedStepFilterClass", "TerminateAll_01", "TerminateAll_02", "StepResult1", 207 "StepResult2", "StepResult3", "StepUncaught", "TriggerPoint_01", "BulkThreadCreationTest", "MethodExitAndException", 208 "Bug534319earlyStart", "Bug534319lateStart", "Bug534319singleThread", "Bug534319startBetwen", "MethodCall", "Bug538303", "Bug540243", 209 "OutSync", "OutSync2", "ConsoleOutputUmlaut", "ErrorRecurrence" }; 210 211 /** 212 * the default timeout 213 */ 214 public static final int DEFAULT_TIMEOUT = 30000; 215 216 //constants 217 protected static final String JAVA = "java"; //$NON-NLS-1$ 218 protected static final String JAVA_EXTENSION = ".java"; //$NON-NLS-1$ 219 protected static final String LAUNCHCONFIGURATIONS = "launchConfigurations"; //$NON-NLS-1$ 220 protected static final String LAUNCH_EXTENSION = ".launch"; //$NON-NLS-1$ 221 protected static final String LOCAL_JAVA_APPLICATION_TYPE_ID = "org.eclipse.jdt.launching.localJavaApplication"; //$NON-NLS-1$ 222 protected static final String JAVA_LAUNCH_SHORTCUT_ID = "org.eclipse.jdt.debug.ui.localJavaShortcut"; //$NON-NLS-1$ 223 protected static final String TEST_LAUNCH_SHORTCUT = "org.eclipse.jdt.debug.tests.testShortCut"; 224 225 /** 226 * an evaluation result 227 */ 228 public IEvaluationResult fEvaluationResult; 229 230 /** 231 * The last relevant event set - for example, that caused 232 * a thread to suspend 233 */ 234 protected DebugEvent[] fEventSet; 235 236 private static boolean loadedPrefs = false; 237 private static boolean loaded14 = false; 238 private static boolean loaded15 = false; 239 private static boolean loaded17 = false; 240 private static boolean loaded18 = false; 241 private static boolean loaded9 = false; 242 private static boolean loadedEE = false; 243 private static boolean loadedJRE = false; 244 private static boolean loadedMulti = false; 245 private static boolean welcomeClosed = false; 246 247 /** 248 * Constructor 249 * @param name 250 */ AbstractDebugTest(String name)251 public AbstractDebugTest(String name) { 252 super(name); 253 // set error dialog to non-blocking to avoid hanging the UI during test 254 ErrorDialog.AUTOMATED_MODE = true; 255 SafeRunnable.setIgnoreErrors(true); 256 } 257 258 @Override setUp()259 protected void setUp() throws Exception { 260 TestUtil.log(IStatus.INFO, getName(), "setUp"); 261 super.setUp(); 262 setPreferences(); 263 IProject pro = ResourcesPlugin.getWorkspace().getRoot().getProject(ONE_FOUR_PROJECT_NAME); 264 loaded14 = pro.exists(); 265 pro = ResourcesPlugin.getWorkspace().getRoot().getProject(ONE_FIVE_PROJECT_NAME); 266 loaded15 = pro.exists(); 267 pro = ResourcesPlugin.getWorkspace().getRoot().getProject(ONE_SEVEN_PROJECT_NAME); 268 loaded17 = pro.exists(); 269 pro = ResourcesPlugin.getWorkspace().getRoot().getProject(ONE_EIGHT_PROJECT_NAME); 270 loaded18 = pro.exists(); 271 pro = ResourcesPlugin.getWorkspace().getRoot().getProject(NINE_PROJECT_NAME); 272 loaded9 = pro.exists(); 273 pro = ResourcesPlugin.getWorkspace().getRoot().getProject(BOUND_JRE_PROJECT_NAME); 274 loadedJRE = pro.exists(); 275 pro = ResourcesPlugin.getWorkspace().getRoot().getProject(BOUND_EE_PROJECT_NAME); 276 loadedEE = pro.exists(); 277 pro = ResourcesPlugin.getWorkspace().getRoot().getProject(MULTI_OUTPUT_PROJECT_NAME); 278 loadedMulti = pro.exists(); 279 assertWelcomeScreenClosed(); 280 } 281 setPreferences()282 synchronized void setPreferences() throws BackingStoreException { 283 if(!loadedPrefs) { 284 IPreferenceStore debugUIPreferences = DebugUIPlugin.getDefault().getPreferenceStore(); 285 // Don't prompt for perspective switching 286 debugUIPreferences.setValue(IInternalDebugUIConstants.PREF_SWITCH_PERSPECTIVE_ON_SUSPEND, MessageDialogWithToggle.ALWAYS); 287 debugUIPreferences.setValue(IInternalDebugUIConstants.PREF_SWITCH_TO_PERSPECTIVE, MessageDialogWithToggle.ALWAYS); 288 debugUIPreferences.setValue(IInternalDebugUIConstants.PREF_RELAUNCH_IN_DEBUG_MODE, MessageDialogWithToggle.NEVER); 289 debugUIPreferences.setValue(IInternalDebugUIConstants.PREF_WAIT_FOR_BUILD, MessageDialogWithToggle.ALWAYS); 290 debugUIPreferences.setValue(IInternalDebugUIConstants.PREF_CONTINUE_WITH_COMPILE_ERROR, MessageDialogWithToggle.ALWAYS); 291 debugUIPreferences.setValue(IInternalDebugUIConstants.PREF_SAVE_DIRTY_EDITORS_BEFORE_LAUNCH, MessageDialogWithToggle.NEVER); 292 293 String property = System.getProperty("debug.workbenchActivation"); 294 boolean activate = property != null && property.equals("on"); 295 debugUIPreferences.setValue(IDebugPreferenceConstants.CONSOLE_OPEN_ON_ERR, activate); 296 debugUIPreferences.setValue(IDebugPreferenceConstants.CONSOLE_OPEN_ON_OUT, activate); 297 debugUIPreferences.setValue(IInternalDebugUIConstants.PREF_ACTIVATE_DEBUG_VIEW, activate); 298 debugUIPreferences.setValue(IDebugUIConstants.PREF_ACTIVATE_WORKBENCH, activate); 299 300 IPreferenceStore jdiUIPreferences = JDIDebugUIPlugin.getDefault().getPreferenceStore(); 301 // Turn off suspend on uncaught exceptions 302 jdiUIPreferences.setValue(IJDIPreferencesConstants.PREF_SUSPEND_ON_UNCAUGHT_EXCEPTIONS, false); 303 jdiUIPreferences.setValue(IJDIPreferencesConstants.PREF_SUSPEND_ON_COMPILATION_ERRORS, false); 304 // Don't warn about HCR failures 305 jdiUIPreferences.setValue(IJDIPreferencesConstants.PREF_ALERT_HCR_FAILED, false); 306 jdiUIPreferences.setValue(IJDIPreferencesConstants.PREF_ALERT_HCR_NOT_SUPPORTED, false); 307 jdiUIPreferences.setValue(IJDIPreferencesConstants.PREF_ALERT_OBSOLETE_METHODS, false); 308 // Set the timeout preference to a high value, to avoid timeouts while 309 // testing 310 JDIDebugModel.getPreferences().setDefault(JDIDebugModel.PREF_REQUEST_TIMEOUT, 10000); 311 // turn off monitor information 312 jdiUIPreferences.setValue(IJavaDebugUIConstants.PREF_SHOW_MONITOR_THREAD_INFO, false); 313 314 //make sure we are auto-refreshing external workspace changes 315 IEclipsePreferences node = InstanceScope.INSTANCE.getNode(ResourcesPlugin.PI_RESOURCES); 316 if(node != null) { 317 node.putBoolean(ResourcesPlugin.PREF_AUTO_REFRESH, true); 318 node.putBoolean(ResourcesPlugin.PREF_LIGHTWEIGHT_AUTO_REFRESH, true); 319 node.flush(); 320 } 321 loadedPrefs = true; 322 } 323 } 324 325 /** 326 * Creates the Java 1.4 compliant project 327 */ assert14Project()328 synchronized void assert14Project() { 329 IJavaProject jp = null; 330 ArrayList<ILaunchConfiguration> cfgs = new ArrayList<>(1); 331 try { 332 if (!loaded14) { 333 try { 334 jp = JavaProjectHelper.createJavaProject(ONE_FOUR_PROJECT_CLOSED_NAME); 335 jp.getProject().close(null); 336 } 337 catch(Exception e) { 338 handleProjectCreationException(e, ONE_FOUR_PROJECT_CLOSED_NAME, jp); 339 } 340 jp = createProject(ONE_FOUR_PROJECT_NAME, JavaProjectHelper.TEST_SRC_DIR.toString(), JavaProjectHelper.JAVA_SE_1_7_EE_NAME, false); 341 IPackageFragmentRoot src = jp.findPackageFragmentRoot(new Path(ONE_FOUR_PROJECT_NAME).append(JavaProjectHelper.SRC_DIR).makeAbsolute()); 342 assertNotNull("The 'src' package fragment root should not be null", src); 343 File root = JavaTestPlugin.getDefault().getFileInPlugin(new Path("testjars")); 344 JavaProjectHelper.importFilesFromDirectory(root, src.getPath(), null); 345 IPath path = src.getPath().append("A.jar"); 346 JavaProjectHelper.addLibrary(jp, path); 347 348 //add a closed project optional classpath entry 349 //see https://bugs.eclipse.org/bugs/show_bug.cgi?id=380918 350 IClasspathEntry entry = JavaCore.newProjectEntry( 351 new Path(ONE_FOUR_PROJECT_CLOSED_NAME).makeAbsolute(), 352 new IAccessRule[0], 353 false, 354 new IClasspathAttribute[] {JavaCore.newClasspathAttribute(IClasspathAttribute.OPTIONAL, Boolean.TRUE.toString())}, 355 false); 356 JavaProjectHelper.addToClasspath(jp, entry); 357 358 // create launch configurations 359 for (int i = 0; i < LAUNCH_CONFIG_NAMES_1_4.length; i++) { 360 cfgs.add(createLaunchConfiguration(jp, LAUNCH_CONFIG_NAMES_1_4[i])); 361 } 362 loaded14 = true; 363 waitForBuild(); 364 } 365 } 366 catch(Exception e) { 367 try { 368 if(jp != null) { 369 jp.getProject().delete(true, true, null); 370 } 371 for (int i = 0; i < cfgs.size(); i++) { 372 cfgs.get(i).delete(); 373 } 374 } 375 catch (CoreException ce) { 376 //ignore 377 } 378 handleProjectCreationException(e, ONE_FOUR_PROJECT_NAME, jp); 379 } 380 } 381 382 /** 383 * Creates the Java 1.5 compliant project 384 */ assert15Project()385 void assert15Project() { 386 IJavaProject jp = null; 387 ArrayList<ILaunchConfiguration> cfgs = new ArrayList<>(1); 388 try { 389 if (!loaded15) { 390 jp = createProject(ONE_FIVE_PROJECT_NAME, JavaProjectHelper.TEST_1_5_SRC_DIR.toString(), JavaProjectHelper.JAVA_SE_1_7_EE_NAME, true); 391 cfgs.add(createLaunchConfiguration(jp, "a.b.c.MethodBreakpoints")); 392 cfgs.add(createLaunchConfiguration(jp, "a.b.c.IntegerAccess")); 393 cfgs.add(createLaunchConfiguration(jp, "a.b.c.StepIntoSelectionWithGenerics")); 394 cfgs.add(createLaunchConfiguration(jp, "a.b.c.ConditionalsNearGenerics")); 395 cfgs.add(createLaunchConfiguration(jp, "a.b.c.bug329294WithGenerics")); 396 cfgs.add(createLaunchConfiguration(jp, "a.b.c.bug403028")); 397 cfgs.add(createLaunchConfiguration(jp, "a.b.c.bug484686")); 398 cfgs.add(createLaunchConfiguration(jp, "a.b.c.GenericMethodEntryTest")); 399 cfgs.add(createLaunchConfiguration(jp, "org.eclipse.debug.tests.targets.HcrClass", true)); 400 loaded15 = true; 401 waitForBuild(); 402 } 403 } 404 catch(Exception e) { 405 try { 406 if(jp != null) { 407 jp.getProject().delete(true, true, null); 408 for (int i = 0; i < cfgs.size(); i++) { 409 cfgs.get(i).delete(); 410 } 411 } 412 } 413 catch (CoreException ce) { 414 //ignore 415 } 416 handleProjectCreationException(e, ONE_FIVE_PROJECT_NAME, jp); 417 } 418 } 419 420 /** 421 * Creates the Java 1.7 compliant project 422 */ assert17Project()423 synchronized void assert17Project() { 424 IJavaProject jp = null; 425 ArrayList<ILaunchConfiguration> cfgs = new ArrayList<>(1); 426 try { 427 if (!loaded17) { 428 jp = createProject(ONE_SEVEN_PROJECT_NAME, JavaProjectHelper.TEST_1_7_SRC_DIR.toString(), JavaProjectHelper.JAVA_SE_1_7_EE_NAME, false); 429 cfgs.add(createLaunchConfiguration(jp, LiteralTests17.LITERAL_TYPE_NAME)); 430 cfgs.add(createLaunchConfiguration(jp, "ThreadNameChange")); 431 loaded17 = true; 432 waitForBuild(); 433 } 434 } 435 catch(Exception e) { 436 try { 437 if(jp != null) { 438 jp.getProject().delete(true, true, null); 439 for (int i = 0; i < cfgs.size(); i++) { 440 cfgs.get(i).delete(); 441 } 442 } 443 } 444 catch (CoreException ce) { 445 //ignore 446 } 447 handleProjectCreationException(e, ONE_SEVEN_PROJECT_NAME, jp); 448 } 449 } 450 451 /** 452 * Creates the Java 1.8 compliant project 453 */ assert18Project()454 synchronized void assert18Project() { 455 IJavaProject jp = null; 456 ArrayList<ILaunchConfiguration> cfgs = new ArrayList<>(1); 457 try { 458 if (!loaded18) { 459 jp = createProject(ONE_EIGHT_PROJECT_NAME, JavaProjectHelper.TEST_1_8_SRC_DIR.toString(), JavaProjectHelper.JAVA_SE_1_8_EE_NAME, false); 460 cfgs.add(createLaunchConfiguration(jp, "EvalTest18")); 461 cfgs.add(createLaunchConfiguration(jp, "FunctionalCaptureTest18")); 462 cfgs.add(createLaunchConfiguration(jp, "EvalTestIntf18")); 463 cfgs.add(createLaunchConfiguration(jp, "EvalIntfSuperDefault")); 464 cfgs.add(createLaunchConfiguration(jp, "DebugHoverTest18")); 465 cfgs.add(createLaunchConfiguration(jp, "DebugHoverTest2Lambdas")); 466 cfgs.add(createLaunchConfiguration(jp, "Bug317045")); 467 cfgs.add(createLaunchConfiguration(jp, "Bug549394")); 468 cfgs.add(createLaunchConfiguration(jp, "Bug541110")); 469 cfgs.add(createLaunchConfiguration(jp, "ClosureVariableTest_Bug542989")); 470 cfgs.add(createLaunchConfiguration(jp, "Bug404097BreakpointInLocalClass")); 471 cfgs.add(createLaunchConfiguration(jp, "Bug404097BreakpointInAnonymousLocalClass")); 472 cfgs.add(createLaunchConfiguration(jp, "Bug404097BreakpointInLambda")); 473 cfgs.add(createLaunchConfiguration(jp, "Bug404097BreakpointUsingInnerClass")); 474 cfgs.add(createLaunchConfiguration(jp, "Bug404097BreakpointUsingLocalClass")); 475 cfgs.add(createLaunchConfiguration(jp, "Bug560392")); 476 cfgs.add(createLaunchConfiguration(jp, "Bug561715")); 477 cfgs.add(createLaunchConfiguration(jp, "Bug562056")); 478 cfgs.add(createLaunchConfiguration(jp, "RemoteEvaluator")); 479 loaded18 = true; 480 waitForBuild(); 481 } 482 } 483 catch(Exception e) { 484 try { 485 if(jp != null) { 486 jp.getProject().delete(true, true, null); 487 for (int i = 0; i < cfgs.size(); i++) { 488 cfgs.get(i).delete(); 489 } 490 } 491 } 492 catch (CoreException ce) { 493 //ignore 494 } 495 handleProjectCreationException(e, ONE_EIGHT_PROJECT_NAME, jp); 496 } 497 } 498 499 /** 500 * Creates the Java 9 compliant project 501 */ assert9Project()502 synchronized void assert9Project() { 503 IJavaProject jp = null; 504 ArrayList<ILaunchConfiguration> cfgs = new ArrayList<>(1); 505 try { 506 if (!loaded9) { 507 jp = createProject(NINE_PROJECT_NAME, JavaProjectHelper.TEST_9_SRC_DIR.toString(), JavaProjectHelper.JAVA_SE_9_EE_NAME, false); 508 cfgs.add(createLaunchConfiguration(jp, "LogicalStructures")); 509 loaded9 = true; 510 waitForBuild(); 511 } 512 } catch (Exception e) { 513 try { 514 if (jp != null) { 515 jp.getProject().delete(true, true, null); 516 for (int i = 0; i < cfgs.size(); i++) { 517 cfgs.get(i).delete(); 518 } 519 } 520 } catch (CoreException ce) { 521 // ignore 522 } 523 handleProjectCreationException(e, NINE_PROJECT_NAME, jp); 524 } 525 } 526 527 /** 528 * Creates the 'BoundJRE' project used for the JRE testing 529 */ assertBoundJreProject()530 synchronized void assertBoundJreProject() { 531 IJavaProject jp = null; 532 try { 533 if (!loadedJRE) { 534 jp =JavaProjectHelper.createJavaProject(BOUND_JRE_PROJECT_NAME); 535 JavaProjectHelper.addSourceContainer(jp, JavaProjectHelper.SRC_DIR, JavaProjectHelper.BIN_DIR); 536 // add VM specific JRE container 537 IPath path = JavaRuntime.newJREContainerPath(JavaRuntime.getDefaultVMInstall()); 538 JavaProjectHelper.addContainerEntry(jp, path); 539 loadedJRE = true; 540 waitForBuild(); 541 } 542 } 543 catch(Exception e) { 544 try { 545 if(jp != null) { 546 jp.getProject().delete(true, true, null); 547 } 548 } 549 catch (CoreException ce) { 550 //ignore 551 } 552 handleProjectCreationException(e, BOUND_JRE_PROJECT_NAME, jp); 553 } 554 } 555 556 /** 557 * Creates the 'BoundEE' project for EE testing 558 */ assertBoundeEeProject()559 void assertBoundeEeProject() { 560 IJavaProject jp = null; 561 try { 562 if(!loadedEE) { 563 // create project with two src folders and output locations 564 jp = JavaProjectHelper.createJavaProject(BOUND_EE_PROJECT_NAME); 565 JavaProjectHelper.addSourceContainer(jp, JavaProjectHelper.SRC_DIR, JavaProjectHelper.BIN_DIR); 566 567 // add VM specific JRE container 568 IExecutionEnvironment j2se14 = JavaRuntime.getExecutionEnvironmentsManager().getEnvironment(JavaProjectHelper.JAVA_SE_1_7_EE_NAME); 569 assertNotNull("Missing J2SE-1.4 environment", j2se14); 570 IPath path = JavaRuntime.newJREContainerPath(j2se14); 571 JavaProjectHelper.addContainerEntry(jp, path); 572 loadedEE = true; 573 waitForBuild(); 574 } 575 } 576 catch(Exception e) { 577 try { 578 if(jp != null) { 579 jp.getProject().delete(true, true, null); 580 } 581 } 582 catch (CoreException ce) { 583 //ignore 584 } 585 handleProjectCreationException(e, BOUND_EE_PROJECT_NAME, jp); 586 } 587 } 588 589 /** 590 * Creates the 'MultiOutput' project for source / binary output testing 591 */ assertMultioutputProject()592 synchronized void assertMultioutputProject() { 593 IJavaProject jp = null; 594 try { 595 if(!loadedMulti) { 596 // create project with two src folders and output locations 597 jp = JavaProjectHelper.createJavaProject(MULTI_OUTPUT_PROJECT_NAME); 598 JavaProjectHelper.addSourceContainer(jp, "src1", "bin1"); 599 JavaProjectHelper.addSourceContainer(jp, "src2", "bin2"); 600 601 // add rt.jar 602 IVMInstall vm = JavaRuntime.getDefaultVMInstall(); 603 assertNotNull("No default JRE", vm); 604 JavaProjectHelper.addContainerEntry(jp, new Path(JavaRuntime.JRE_CONTAINER)); 605 loadedMulti = true; 606 waitForBuild(); 607 } 608 } 609 catch(Exception e) { 610 try { 611 if(jp != null) { 612 jp.getProject().delete(true, true, null); 613 } 614 } 615 catch (CoreException ce) { 616 //ignore 617 } 618 handleProjectCreationException(e, MULTI_OUTPUT_PROJECT_NAME, jp); 619 } 620 } 621 622 /** 623 * Ensure the welcome screen is closed because in 4.x the debug perspective opens a giant fast-view causing issues 624 * 625 * @throws Exception 626 * @since 3.8 627 */ assertWelcomeScreenClosed()628 protected final void assertWelcomeScreenClosed() throws Exception { 629 if(!welcomeClosed && PlatformUI.isWorkbenchRunning()) { 630 final IWorkbench wb = PlatformUI.getWorkbench(); 631 if (wb == null) { 632 return; 633 } 634 // In UI thread we don't need to run a job 635 if (Display.getCurrent() != null) { 636 closeIntro(wb); 637 return; 638 } 639 640 UIJob job = new UIJob("close welcome screen for debug test suite") { 641 @Override 642 public IStatus runInUIThread(IProgressMonitor monitor) { 643 closeIntro(wb); 644 return Status.OK_STATUS; 645 } 646 647 }; 648 job.setPriority(Job.INTERACTIVE); 649 job.setSystem(true); 650 job.schedule(); 651 } 652 } 653 closeIntro(final IWorkbench wb)654 private static void closeIntro(final IWorkbench wb) { 655 IWorkbenchWindow window = wb.getActiveWorkbenchWindow(); 656 if (window != null) { 657 IIntroManager im = wb.getIntroManager(); 658 IIntroPart intro = im.getIntro(); 659 if (intro != null) { 660 welcomeClosed = im.closeIntro(intro); 661 } 662 } 663 } 664 handleProjectCreationException(Exception e, String pname, IJavaProject jp)665 void handleProjectCreationException(Exception e, String pname, IJavaProject jp) { 666 StringWriter buf = new StringWriter(); 667 String msg = e.getMessage(); 668 if(msg == null) { 669 msg = "could not acquire message for exception class: " + e.getClass(); 670 } 671 buf.write("Failed to create the '" + pname + "' test project.\n"); 672 buf.write("'jp' is " + (jp != null ? "not " : "") + " 'null'\n"); 673 buf.write("Stack tace:\n"); 674 e.printStackTrace(new PrintWriter(buf)); 675 fail(buf.toString()); 676 } 677 678 /** 679 * Sets the contents of the given {@link ICompilationUnit} to be the new contents provided 680 * @param unit 681 * @param contents the new {@link String} contents, cannot be <code>null</code> 682 * @throws JavaModelException 683 */ setFileContents(ICompilationUnit unit, String contents)684 protected void setFileContents(ICompilationUnit unit, String contents) throws JavaModelException { 685 assertNotNull("You cannot set the new contents of an ICompilationUnit to null", contents); 686 IBuffer buffer = unit.getBuffer(); 687 buffer.setContents(contents); 688 unit.save(null, true); 689 waitForBuild(); 690 } 691 692 /** 693 * Sets the last relevant event set 694 * 695 * @param set event set 696 */ setEventSet(DebugEvent[] set)697 protected void setEventSet(DebugEvent[] set) { 698 fEventSet = set; 699 } 700 701 /** 702 * Returns the last relevant event set 703 * 704 * @return event set 705 */ getEventSet()706 protected DebugEvent[] getEventSet() { 707 return fEventSet; 708 } 709 710 /** 711 * Returns the launch manager 712 * 713 * @return launch manager 714 */ getLaunchManager()715 protected ILaunchManager getLaunchManager() { 716 return DebugPlugin.getDefault().getLaunchManager(); 717 } 718 719 /** 720 * Returns the singleton instance of the <code>LaunchConfigurationManager</code> 721 * 722 * @return the singleton instance of the <code>LaunchConfigurationManager</code> 723 * @since 3.3 724 */ getLaunchConfigurationManager()725 protected LaunchConfigurationManager getLaunchConfigurationManager() { 726 return DebugUIPlugin.getDefault().getLaunchConfigurationManager(); 727 } 728 729 /** 730 * Returns the breakpoint manager 731 * 732 * @return breakpoint manager 733 */ getBreakpointManager()734 protected IBreakpointManager getBreakpointManager() { 735 return DebugPlugin.getDefault().getBreakpointManager(); 736 } 737 738 /** 739 * Returns the project context for the current test - each 740 * test must implement this method 741 */ getProjectContext()742 protected IJavaProject getProjectContext() { 743 return get14Project(); 744 } 745 746 /** 747 * Returns the 'DebugTests' project. 748 * 749 * @return the test project 750 */ get14Project()751 protected IJavaProject get14Project() { 752 assert14Project(); 753 return getJavaProject(ONE_FOUR_PROJECT_NAME); 754 } 755 756 /** 757 * Returns the {@link IBreakpointOrganizer} with the given id or <code>null</code> 758 * if no such organizer exists 759 * @param id 760 * @return the {@link IBreakpointOrganizer} or <code>null</code> 761 * @since 3.8.100 762 */ getOrganizer(String id)763 protected IBreakpointOrganizer getOrganizer(String id) { 764 return BreakpointOrganizerManager.getDefault().getOrganizer(id); 765 } 766 767 /** 768 * Returns the 'OneFive' project. 769 * 770 * @return the test project 771 */ get15Project()772 protected IJavaProject get15Project() { 773 assert15Project(); 774 return getJavaProject(ONE_FIVE_PROJECT_NAME); 775 } 776 777 /** 778 * Returns the 'OneSeven' project. 779 * 780 * @return the test project 781 */ get17Project()782 protected IJavaProject get17Project() { 783 assert17Project(); 784 return getJavaProject(ONE_SEVEN_PROJECT_NAME); 785 } 786 787 /** 788 * Returns the 'OneEight' project. 789 * 790 * @return the test project 791 */ get18Project()792 protected IJavaProject get18Project() { 793 assert18Project(); 794 return getJavaProject(ONE_EIGHT_PROJECT_NAME); 795 } 796 797 /** 798 * Returns the 'Nine' project, used for Java 9 tests. 799 * 800 * @return the test project 801 */ get9Project()802 protected IJavaProject get9Project() { 803 assert9Project(); 804 return getJavaProject(NINE_PROJECT_NAME); 805 } 806 807 /** 808 * Returns the 'BoundJRE' project 809 * 810 * @return the test project 811 */ getBoundJreProject()812 protected IJavaProject getBoundJreProject() { 813 assertBoundJreProject(); 814 return getJavaProject(BOUND_JRE_PROJECT_NAME); 815 } 816 817 /** 818 * Returns the 'BoundEE' project 819 * 820 * @return the test project 821 */ getBoundEeProject()822 protected IJavaProject getBoundEeProject() { 823 assertBoundeEeProject(); 824 return getJavaProject(BOUND_EE_PROJECT_NAME); 825 } 826 827 /** 828 * Returns the 'MultiOutput' project 829 * 830 * @return the test project 831 */ getMultiOutputProject()832 protected IJavaProject getMultiOutputProject() { 833 assertMultioutputProject(); 834 return getJavaProject(MULTI_OUTPUT_PROJECT_NAME); 835 } 836 837 /** 838 * Returns the Java project with the given name. 839 * 840 * @param name project name 841 * @return the Java project with the given name 842 */ getJavaProject(String name)843 protected IJavaProject getJavaProject(String name) { 844 IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(name); 845 return JavaCore.create(project); 846 } 847 848 /** 849 * Creates a new {@link IJavaProject} with the given name and optionally initializing it from the given 850 * resource path from the testing bundle. 851 * <br><br> 852 * The project has the default <code>src</code> and <code>bin</code> folders. It is also created with a default 853 * <code>launchConfigurations</code> folder. 854 * 855 * @param name the name for the project 856 * @param contentpath the path within the jdt.debug test bundle to initialize the source from 857 * @param ee the level of execution environment to use 858 * @param if an existing project should be deleted 859 * @return the new Java project 860 * @throws Exception 861 */ createProject(String name, String contentpath, String ee, boolean delete)862 protected IJavaProject createProject(String name, String contentpath, String ee, boolean delete) throws Exception { 863 IProject pro = ResourcesPlugin.getWorkspace().getRoot().getProject(name); 864 if (pro.exists() && delete) { 865 try { 866 pro.delete(true, true, null); 867 } 868 catch(Exception e) {} 869 } 870 // create project and import source 871 IJavaProject jp = JavaProjectHelper.createJavaProject(name, JavaProjectHelper.BIN_DIR); 872 IPackageFragmentRoot src = JavaProjectHelper.addSourceContainer(jp, JavaProjectHelper.SRC_DIR); 873 File root = JavaTestPlugin.getDefault().getFileInPlugin(new Path(contentpath)); 874 JavaProjectHelper.importFilesFromDirectory(root, src.getPath(), null); 875 876 // add the EE library 877 IVMInstall vm = JavaRuntime.getDefaultVMInstall(); 878 assertNotNull("No default JRE", vm); 879 IExecutionEnvironment environment = JavaRuntime.getExecutionEnvironmentsManager().getEnvironment(ee); 880 assertNotNull("The EE ["+ee+"] does not exist", environment); 881 IPath containerPath = JavaRuntime.newJREContainerPath(environment); 882 JavaProjectHelper.addContainerEntry(jp, containerPath); 883 pro = jp.getProject(); 884 885 JavaProjectHelper.updateCompliance(jp, ee); 886 887 // create launch configuration folder 888 IFolder folder = pro.getFolder("launchConfigurations"); 889 if (!folder.exists()) { 890 folder.create(true, true, null); 891 } 892 return jp; 893 } 894 895 /** 896 * Creates a new {@link IJavaProject} with the given name and initializes the contents from the given 897 * resource path from the testing bundle. 898 * <br><br> 899 * The project has the default <code>src</code> and <code>bin</code> folders. It is also created with a default 900 * <code>launchConfigurations</code> folder. 901 * 902 * @param name the name for the project 903 * @param contentpath the path within the jdt.debug test bundle to initialize the source from 904 * @param ee the level of execution environment to use 905 * @param if an existing project should be deleted 906 * @return the new Java project 907 * @throws Exception 908 */ createJavaProjectClone(String name, String contentpath, String ee, boolean delete)909 protected IJavaProject createJavaProjectClone(String name, String contentpath, String ee, boolean delete) throws Exception { 910 IProject pro = ResourcesPlugin.getWorkspace().getRoot().getProject(name); 911 String owner = "Creating project: " + name; 912 if (pro.exists() && delete) { 913 pro.delete(true, true, null); 914 TestUtil.waitForJobs(owner, 100, 10000); 915 TestUtil.runEventLoop(); 916 } 917 // create project and import source 918 IJavaProject jp = JavaProjectHelper.createJavaProject(name, JavaProjectHelper.BIN_DIR); 919 TestUtil.waitForJobs(owner, 100, 10000); 920 TestUtil.runEventLoop(); 921 922 JavaProjectHelper.addSourceContainer(jp, JavaProjectHelper.SRC_DIR); 923 TestUtil.waitForJobs(owner, 100, 10000); 924 TestUtil.runEventLoop(); 925 926 File root = JavaTestPlugin.getDefault().getFileInPlugin(new Path(contentpath)); 927 JavaProjectHelper.importFilesFromDirectory(root, jp.getPath(), null); 928 929 TestUtil.waitForJobs(owner, 100, 10000); 930 TestUtil.runEventLoop(); 931 932 // add the EE library 933 IVMInstall vm = JavaRuntime.getDefaultVMInstall(); 934 assertNotNull("No default JRE", vm); 935 IExecutionEnvironment environment = JavaRuntime.getExecutionEnvironmentsManager().getEnvironment(ee); 936 assertNotNull("The EE ["+ee+"] does not exist", environment); 937 IPath containerPath = JavaRuntime.newJREContainerPath(environment); 938 JavaProjectHelper.addContainerEntry(jp, containerPath); 939 pro = jp.getProject(); 940 941 // create launch configuration folder 942 IFolder folder = pro.getFolder("launchConfigurations"); 943 if (!folder.exists()) { 944 folder.create(true, true, null); 945 } 946 TestUtil.waitForJobs(owner, 100, 10000); 947 TestUtil.runEventLoop(); 948 return jp; 949 } 950 951 /** 952 * Creates a new {@link IProject} with the given name and initializes the contents from the given 953 * resource path from the testing bundle. 954 * 955 * @param name the name for the project 956 * @param contentpath the path within the jdt.debug test bundle to initialize the source from 957 * @param if an existing project should be deleted 958 * @return the new project 959 * @throws Exception 960 */ createProjectClone(String name, String contentpath, boolean delete)961 protected IProject createProjectClone(String name, String contentpath, boolean delete) throws Exception { 962 IProject pro = ResourcesPlugin.getWorkspace().getRoot().getProject(name); 963 String owner = "Creating project: " + name; 964 if (pro.exists() && delete) { 965 pro.delete(true, true, null); 966 TestUtil.waitForJobs(owner, 100, 10000); 967 TestUtil.runEventLoop(); 968 } 969 // create project and import source 970 IProject pj = JavaProjectHelper.createProject(name); 971 TestUtil.waitForJobs(owner, 100, 10000); 972 TestUtil.runEventLoop(); 973 974 File root = JavaTestPlugin.getDefault().getFileInPlugin(new Path(contentpath)); 975 JavaProjectHelper.importFilesFromDirectory(root, pj.getFullPath(), null); 976 TestUtil.waitForJobs(owner, 100, 10000); 977 TestUtil.runEventLoop(); 978 return pj; 979 } 980 981 /** 982 * Returns the launch shortcut with the given id 983 * @param id 984 * @return the <code>LaunchShortcutExtension</code> with the given id, 985 * or <code>null</code> if none 986 * 987 * @since 3.3 988 */ getLaunchShortcutExtension(String id)989 protected LaunchShortcutExtension getLaunchShortcutExtension(String id) { 990 List<?> exts = getLaunchConfigurationManager().getLaunchShortcuts(); 991 LaunchShortcutExtension ext = null; 992 for (int i = 0; i < exts.size(); i++) { 993 ext = (LaunchShortcutExtension) exts.get(i); 994 if(ext.getId().equals(id)) { 995 return ext; 996 } 997 } 998 return null; 999 } 1000 1001 /** 1002 * New to 3.3 is the ability to have multiple delegates for a variety of overlapping mode combinations. 1003 * As such, for tests that launch specific configurations, must be check to ensure that there is a preferred 1004 * launch delegate available for the launch in the event there are duplicates. Otherwise the tests 1005 * will hang waiting for a user to select a resolution action. 1006 * @param configuration 1007 * @param modes 1008 * @throws CoreException 1009 * 1010 * @since 3.3 1011 */ ensurePreferredDelegate(ILaunchConfiguration configuration, Set<String> modes)1012 protected void ensurePreferredDelegate(ILaunchConfiguration configuration, Set<String> modes) throws CoreException { 1013 ILaunchConfigurationType type = configuration.getType(); 1014 ILaunchDelegate[] delegates = type.getDelegates(modes); 1015 if(delegates.length > 1) { 1016 type.setPreferredDelegate(modes, getDelegateById(type.getIdentifier(), LOCAL_JAVA_APPLICATION_TYPE_ID)); 1017 } 1018 } 1019 1020 /** 1021 * Returns the LaunchDelegate for the specified ID 1022 * @param delegateId the id of the delegate to search for 1023 * @return the <code>LaunchDelegate</code> associated with the specified id or <code>null</code> if not found 1024 * @since 3.3 1025 */ getDelegateById(String typeId, String delegateId)1026 protected ILaunchDelegate getDelegateById(String typeId, String delegateId) { 1027 LaunchManager lm = (LaunchManager) getLaunchManager(); 1028 LaunchDelegate[] delegates = lm.getLaunchDelegates(typeId); 1029 for(int i = 0; i < delegates.length; i++) { 1030 if(delegates[i].getId().equals(delegateId)) { 1031 return delegates[i]; 1032 } 1033 } 1034 return null; 1035 } 1036 1037 /** 1038 * Returns the source folder with the given name in the given project. 1039 * 1040 * @param project 1041 * @param name source folder name 1042 * @return package fragment root 1043 */ getPackageFragmentRoot(IJavaProject project, String name)1044 protected IPackageFragmentRoot getPackageFragmentRoot(IJavaProject project, String name) { 1045 IProject p = project.getProject(); 1046 return project.getPackageFragmentRoot(p.getFolder(name)); 1047 } 1048 1049 /** 1050 * Returns the <code>IHyperLink</code> at the given offset in the specified document 1051 * or <code>null</code> if the offset does not point to an <code>IHyperLink</code> 1052 * @param offset 1053 * @param doc 1054 * @return the <code>IHyperLink</code> at the given offset or <code>null</code> 1055 */ getHyperlink(int offset, IDocument doc)1056 protected IHyperlink getHyperlink(int offset, IDocument doc) { 1057 if (offset >= 0 && doc != null) { 1058 Position[] positions = null; 1059 try { 1060 positions = doc.getPositions(ConsoleHyperlinkPosition.HYPER_LINK_CATEGORY); 1061 } catch (BadPositionCategoryException ex) { 1062 // no links have been added 1063 return null; 1064 } 1065 for (int i = 0; i < positions.length; i++) { 1066 Position position = positions[i]; 1067 if (offset >= position.getOffset() && offset <= (position.getOffset() + position.getLength())) { 1068 return ((ConsoleHyperlinkPosition)position).getHyperLink(); 1069 } 1070 } 1071 } 1072 return null; 1073 } 1074 1075 /** 1076 * Launches the given configuration and waits for an event. Returns the 1077 * source of the event. If the event is not received, the launch is 1078 * terminated and an exception is thrown. 1079 * 1080 * @param configuration the configuration to launch 1081 * @param waiter the event waiter to use 1082 * @return Object the source of the event 1083 * @exception Exception if the event is never received. 1084 */ launchAndWait(ILaunchConfiguration configuration, DebugEventWaiter waiter)1085 protected Object launchAndWait(ILaunchConfiguration configuration, DebugEventWaiter waiter) throws CoreException { 1086 return launchAndWait(configuration, waiter, true); 1087 } 1088 1089 /** 1090 * Launches the given configuration in debug mode and waits for an event. 1091 * Returns the source of the event. If the event is not received, the 1092 * launch is terminated and an exception is thrown. 1093 * 1094 * @param configuration the configuration to launch 1095 * @param waiter the event waiter to use 1096 * @param register whether to register the launch 1097 * @return Object the source of the event 1098 * @exception Exception if the event is never received. 1099 */ launchAndWait(ILaunchConfiguration configuration, DebugEventWaiter waiter, boolean register)1100 protected Object launchAndWait(ILaunchConfiguration configuration, DebugEventWaiter waiter, boolean register) throws CoreException { 1101 return launchAndWait(configuration, ILaunchManager.DEBUG_MODE, waiter, register); 1102 } 1103 1104 /** 1105 * Launches the given configuration and waits for an event. Returns the 1106 * source of the event. If the event is not received, the launch is 1107 * terminated and an exception is thrown. 1108 * 1109 * @param configuration the configuration to launch 1110 * @param mode the mode to launch the configuration in 1111 * @param waiter the event waiter to use 1112 * @param register whether to register the launch 1113 * @return Object the source of the event 1114 * @exception Exception if the event is never received. 1115 */ launchAndWait(ILaunchConfiguration configuration, String mode, DebugEventWaiter waiter, boolean register)1116 protected Object launchAndWait(ILaunchConfiguration configuration, String mode, DebugEventWaiter waiter, boolean register) throws CoreException { 1117 ILaunch launch = configuration.launch(mode, null, false, register); 1118 Object suspendee= waiter.waitForEvent(); 1119 if (suspendee == null) { 1120 StringBuilder buf = new StringBuilder(); 1121 buf.append("Test case: "); //$NON-NLS-1$ 1122 buf.append(getName()); 1123 buf.append("\n"); //$NON-NLS-1$ 1124 buf.append("Never received event: "); //$NON-NLS-1$ 1125 buf.append(waiter.getEventKindName()); 1126 buf.append("\n"); //$NON-NLS-1$ 1127 if (launch.isTerminated()) { 1128 buf.append("Process exit value: "); //$NON-NLS-1$ 1129 buf.append(launch.getProcesses()[0].getExitValue()); 1130 buf.append("\n"); //$NON-NLS-1$ 1131 } 1132 IConsole console = DebugUITools.getConsole(launch.getProcesses()[0]); 1133 if (console instanceof TextConsole) { 1134 TextConsole textConsole = (TextConsole)console; 1135 String string = textConsole.getDocument().get(); 1136 buf.append("Console output follows:\n"); //$NON-NLS-1$ 1137 buf.append(string); 1138 } 1139 buf.append("\n"); //$NON-NLS-1$ 1140 DebugPlugin.log(new Status(IStatus.ERROR, "org.eclipse.jdt.debug.ui.tests", buf.toString())); //$NON-NLS-1$ 1141 try { 1142 launch.terminate(); 1143 } catch (CoreException e) { 1144 e.printStackTrace(); 1145 fail("Program did not suspend, and unable to terminate launch."); //$NON-NLS-1$ 1146 } 1147 throw new TestAgainException("Program did not suspend, launch terminated."); 1148 } 1149 setEventSet(waiter.getEventSet()); 1150 assertNotNull("Program did not suspend, launch terminated.", suspendee); //$NON-NLS-1$ 1151 return suspendee; 1152 } 1153 1154 1155 1156 /** 1157 * Launches the type with the given name, and waits for a 1158 * suspend event in that program. Returns the thread in which the suspend 1159 * event occurred. 1160 * 1161 * @param mainTypeName the program to launch 1162 * @return thread in which the first suspend event occurred 1163 */ launchAndSuspend(String mainTypeName)1164 protected IJavaThread launchAndSuspend(String mainTypeName) throws Exception { 1165 ILaunchConfiguration config = getLaunchConfiguration(mainTypeName); 1166 assertNotNull("Could not locate launch configuration for " + mainTypeName, config); //$NON-NLS-1$ 1167 return launchAndSuspend(config); 1168 } 1169 1170 /** 1171 * Launches the given configuration in debug mode, and waits for a 1172 * suspend event in that program. Returns the thread in which the suspend 1173 * event occurred. 1174 * 1175 * @param config the configuration to launch 1176 * @return thread in which the first suspend event occurred 1177 */ launchAndSuspend(ILaunchConfiguration config)1178 protected IJavaThread launchAndSuspend(ILaunchConfiguration config) throws Exception { 1179 DebugEventWaiter waiter= new DebugElementKindEventWaiter(DebugEvent.SUSPEND, IJavaThread.class); 1180 waiter.setTimeout(DEFAULT_TIMEOUT); 1181 waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); 1182 Object suspendee = launchAndWait(config, waiter); 1183 return (IJavaThread)suspendee; 1184 } 1185 1186 /** 1187 * Launches the type with the given name, and waits for a breakpoint-caused 1188 * suspend event in that program. Returns the thread in which the suspend 1189 * event occurred. 1190 * 1191 * @param mainTypeName the program to launch 1192 * @return thread in which the first suspend event occurred 1193 */ launchToBreakpoint(String mainTypeName)1194 protected IJavaThread launchToBreakpoint(String mainTypeName) throws Exception { 1195 return launchToBreakpoint(getProjectContext(), mainTypeName); 1196 } 1197 1198 /** 1199 * Launches the type with the given name, and waits for a breakpoint-caused 1200 * suspend event in that program. Returns the thread in which the suspend 1201 * event occurred. 1202 * 1203 * @param project the project the type is in 1204 * @param mainTypeName the program to launch 1205 * @return thread in which the first suspend event occurred 1206 */ launchToBreakpoint(IJavaProject project, String mainTypeName)1207 protected IJavaThread launchToBreakpoint(IJavaProject project, String mainTypeName) throws Exception { 1208 return launchToBreakpoint(project, mainTypeName, true); 1209 } 1210 1211 /** 1212 * Launches the type with the given name, and waits for a breakpoint-caused 1213 * suspend event in that program. Returns the thread in which the suspend 1214 * event occurred. 1215 * 1216 * @param mainTypeName the program to launch 1217 * @param register whether to register the launch 1218 * @return thread in which the first suspend event occurred 1219 */ launchToBreakpoint(String mainTypeName, boolean register)1220 protected IJavaThread launchToBreakpoint(String mainTypeName, boolean register) throws Exception { 1221 return launchToBreakpoint(getProjectContext(), mainTypeName, register); 1222 } 1223 1224 /** 1225 * Launches the type with the given name, and waits for a breakpoint-caused 1226 * suspend event in that program. Returns the thread in which the suspend 1227 * event occurred. 1228 * 1229 * @param mainTypeName the program to launch 1230 * @param register whether to register the launch 1231 * @return thread in which the first suspend event occurred 1232 */ launchToBreakpoint(IJavaProject project, String mainTypeName, boolean register)1233 protected IJavaThread launchToBreakpoint(IJavaProject project, String mainTypeName, boolean register) throws Exception { 1234 ILaunchConfiguration config = getLaunchConfiguration(project, mainTypeName); 1235 assertNotNull("Could not locate launch configuration for " + mainTypeName, config); //$NON-NLS-1$ 1236 return launchToBreakpoint(config, register); 1237 } 1238 1239 /** 1240 * Launches the type with the given name, and waits for a breakpoint-caused 1241 * suspend event in that program. Returns the thread in which the suspend 1242 * event occurred. 1243 * 1244 * @param mainTypeName the program to launch 1245 * @param register whether to register the launch 1246 * @return thread in which the first suspend event occurred 1247 */ launchToBreakpoint(IJavaProject project, String mainTypeName, String launchName, boolean register)1248 protected IJavaThread launchToBreakpoint(IJavaProject project, String mainTypeName, String launchName, boolean register) throws Exception { 1249 ILaunchConfiguration config = getLaunchConfiguration(project, launchName); 1250 assertNotNull("Could not locate launch configuration for " + mainTypeName, config); //$NON-NLS-1$ 1251 return launchToBreakpoint(config, register); 1252 } 1253 1254 /** 1255 * Launches the given configuration in debug mode, and waits for a breakpoint-caused 1256 * suspend event in that program. Returns the thread in which the suspend 1257 * event occurred. 1258 * 1259 * @param config the configuration to launch 1260 * @return thread in which the first suspend event occurred 1261 */ launchToBreakpoint(ILaunchConfiguration config)1262 protected IJavaThread launchToBreakpoint(ILaunchConfiguration config) throws CoreException { 1263 return launchToBreakpoint(config, true); 1264 } 1265 1266 /** 1267 * Launches the given configuration in debug mode, and waits for a breakpoint-caused 1268 * suspend event in that program. Returns the thread in which the suspend 1269 * event occurred. 1270 * 1271 * @param config the configuration to launch 1272 * @param whether to register the launch 1273 * @return thread in which the first suspend event occurred 1274 */ launchToBreakpoint(ILaunchConfiguration config, boolean register)1275 protected IJavaThread launchToBreakpoint(ILaunchConfiguration config, boolean register) throws CoreException { 1276 DebugEventWaiter waiter= new DebugElementKindEventDetailWaiter(DebugEvent.SUSPEND, IJavaThread.class, DebugEvent.BREAKPOINT); 1277 waiter.setTimeout(DEFAULT_TIMEOUT); 1278 waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); 1279 1280 Object suspendee= launchAndWait(config, waiter, register); 1281 assertTrue("suspendee was not an IJavaThread", suspendee instanceof IJavaThread); //$NON-NLS-1$ 1282 return (IJavaThread)suspendee; 1283 } 1284 1285 /** 1286 * Launches the type with the given name, and waits for a terminate 1287 * event in that program. Returns the debug target in which the suspend 1288 * event occurred. 1289 * 1290 * @param mainTypeName the program to launch 1291 * @param timeout the number of milliseconds to wait for a terminate event 1292 * @return debug target in which the terminate event occurred 1293 */ launchAndTerminate(String mainTypeName)1294 protected IJavaDebugTarget launchAndTerminate(String mainTypeName) throws Exception { 1295 ILaunchConfiguration config = getLaunchConfiguration(mainTypeName); 1296 assertNotNull("Could not locate launch configuration for " + mainTypeName, config); //$NON-NLS-1$ 1297 return launchAndTerminate(config, DEFAULT_TIMEOUT); 1298 } 1299 1300 /** 1301 * Launches the given configuration in debug mode, and waits for a terminate 1302 * event in that program. Returns the debug target in which the terminate 1303 * event occurred. 1304 * 1305 * @param config the configuration to launch 1306 * @param timeout the number of milliseconds to wait for a terminate event 1307 * @return thread in which the first suspend event occurred 1308 */ launchAndTerminate(ILaunchConfiguration config, int timeout)1309 protected IJavaDebugTarget launchAndTerminate(ILaunchConfiguration config, int timeout) throws Exception { 1310 return launchAndTerminate(config, timeout, true); 1311 } 1312 1313 /** 1314 * Launches the given configuration in debug mode, and waits for a terminate 1315 * event in that program. Returns the debug target in which the terminate 1316 * event occurred. 1317 * 1318 * @param config the configuration to launch 1319 * @param timeout the number of milliseconds to wait for a terminate event 1320 * @param register whether to register the launch 1321 * @return thread in which the first suspend event occurred 1322 */ launchAndTerminate(ILaunchConfiguration config, int timeout, boolean register)1323 protected IJavaDebugTarget launchAndTerminate(ILaunchConfiguration config, int timeout, boolean register) throws Exception { 1324 DebugEventWaiter waiter= new DebugElementKindEventWaiter(DebugEvent.TERMINATE, IJavaDebugTarget.class); 1325 waiter.setTimeout(timeout); 1326 waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); 1327 1328 Object terminatee = launchAndWait(config, waiter, register); 1329 assertNotNull("Program did not terminate.", terminatee); //$NON-NLS-1$ 1330 assertTrue("terminatee is not an IJavaDebugTarget", terminatee instanceof IJavaDebugTarget); //$NON-NLS-1$ 1331 IJavaDebugTarget debugTarget = (IJavaDebugTarget) terminatee; 1332 assertTrue("debug target is not terminated", debugTarget.isTerminated() || debugTarget.isDisconnected()); //$NON-NLS-1$ 1333 return debugTarget; 1334 } 1335 1336 /** 1337 * Launches the type with the given name, and waits for a line breakpoint suspend 1338 * event in that program. Returns the thread in which the suspend 1339 * event occurred. 1340 * 1341 * @param mainTypeName the program to launch 1342 * @param bp the breakpoint that should cause a suspend event 1343 * @return thread in which the first suspend event occurred 1344 */ launchToLineBreakpoint(String mainTypeName, ILineBreakpoint bp)1345 protected IJavaThread launchToLineBreakpoint(String mainTypeName, ILineBreakpoint bp) throws Exception { 1346 return launchToLineBreakpoint(mainTypeName, bp, true); 1347 } 1348 1349 /** 1350 * Launches the type with the given name, and waits for a line breakpoint suspend 1351 * event in that program. Returns the thread in which the suspend 1352 * event occurred. 1353 * 1354 * @param mainTypeName the program to launch 1355 * @param bp the breakpoint that should cause a suspend event 1356 * @param register whether to register the launch 1357 * @return thread in which the first suspend event occurred 1358 */ launchToLineBreakpoint(String mainTypeName, ILineBreakpoint bp, boolean register)1359 protected IJavaThread launchToLineBreakpoint(String mainTypeName, ILineBreakpoint bp, boolean register) throws Exception { 1360 ILaunchConfiguration config = getLaunchConfiguration(mainTypeName); 1361 assertNotNull("Could not locate launch configuration for " + mainTypeName, config); //$NON-NLS-1$ 1362 return launchToLineBreakpoint(config, bp, register); 1363 } 1364 1365 /** 1366 * Launches the given configuration in debug mode, and waits for a line breakpoint 1367 * suspend event in that program. Returns the thread in which the suspend 1368 * event occurred. 1369 * 1370 * @param config the configuration to launch 1371 * @param bp the breakpoint that should cause a suspend event 1372 * @return thread in which the first suspend event occurred 1373 */ launchToLineBreakpoint(ILaunchConfiguration config, ILineBreakpoint bp, boolean register)1374 protected IJavaThread launchToLineBreakpoint(ILaunchConfiguration config, ILineBreakpoint bp, boolean register) throws Exception { 1375 DebugEventWaiter waiter= new DebugElementKindEventDetailWaiter(DebugEvent.SUSPEND, IJavaThread.class, DebugEvent.BREAKPOINT); 1376 waiter.setTimeout(DEFAULT_TIMEOUT); 1377 waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); 1378 1379 Object suspendee= launchAndWait(config, waiter, register); 1380 assertTrue("suspendee was not an IJavaThread", suspendee instanceof IJavaThread); //$NON-NLS-1$ 1381 IJavaThread thread = (IJavaThread) suspendee; 1382 IBreakpoint hit = getBreakpoint(thread); 1383 assertNotNull("suspended, but not by breakpoint", hit); //$NON-NLS-1$ 1384 assertTrue("hit un-registered breakpoint", bp.equals(hit)); //$NON-NLS-1$ 1385 assertTrue("suspended, but not by line breakpoint", hit instanceof ILineBreakpoint); //$NON-NLS-1$ 1386 ILineBreakpoint breakpoint= (ILineBreakpoint) hit; 1387 int lineNumber = breakpoint.getLineNumber(); 1388 int stackLine = thread.getTopStackFrame().getLineNumber(); 1389 assertTrue("line numbers of breakpoint and stack frame do not match", lineNumber == stackLine); //$NON-NLS-1$ 1390 1391 return thread; 1392 } 1393 1394 /** 1395 * Returns the standard java launch tab group 1396 * @return the standard java launch tab group 1397 * @throws CoreException 1398 * 1399 * @since 3.3 1400 */ getJavaLaunchGroup()1401 protected ILaunchConfigurationTabGroup getJavaLaunchGroup() throws CoreException { 1402 ILaunchConfigurationType javaType = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION); 1403 ILaunchConfigurationTabGroup standardGroup = LaunchConfigurationPresentationManager.getDefault().getTabGroup(javaType, ILaunchManager.DEBUG_MODE); 1404 return standardGroup; 1405 } 1406 1407 /** 1408 * Returns an instance of the launch configuration dialog on the the specified launch mode 1409 * @param modeid the id of the mode to open the launch dialog on 1410 * @return an new instance of <code>IlaunchConfigurationDialog</code> 1411 * 1412 * @since 3.3 1413 */ getLaunchConfigurationDialog(String modeid)1414 protected ILaunchConfigurationDialog getLaunchConfigurationDialog(String modeid) { 1415 return new LaunchConfigurationsDialog(null, DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLaunchGroup(modeid)); 1416 } 1417 1418 /** 1419 * Resumes the given thread, and waits for another breakpoint-caused suspend event. 1420 * Returns the thread in which the suspend event occurs. 1421 * 1422 * @param thread thread to resume 1423 * @return thread in which the first suspend event occurs 1424 */ resume(IJavaThread thread)1425 protected IJavaThread resume(IJavaThread thread) throws Exception { 1426 return resume(thread, DEFAULT_TIMEOUT); 1427 } 1428 1429 /** 1430 * Resumes the given thread, and waits for another breakpoint-caused suspend event. 1431 * Returns the thread in which the suspend event occurs. 1432 * 1433 * @param thread thread to resume 1434 * @param timeout timeout in milliseconds 1435 * @return thread in which the first suspend event occurs 1436 */ resume(IJavaThread thread, int timeout)1437 protected IJavaThread resume(IJavaThread thread, int timeout) throws Exception { 1438 DebugEventWaiter waiter= new DebugElementKindEventDetailWaiter(DebugEvent.SUSPEND, IJavaThread.class, DebugEvent.BREAKPOINT); 1439 waiter.setTimeout(timeout); 1440 waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); 1441 1442 thread.resume(); 1443 1444 Object suspendee= waiter.waitForEvent(); 1445 setEventSet(waiter.getEventSet()); 1446 assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$ 1447 return (IJavaThread)suspendee; 1448 } 1449 1450 /** 1451 * Resumes the given thread, and waits for a suspend event caused by the specified 1452 * line breakpoint. Returns the thread in which the suspend event occurs. 1453 * 1454 * @param thread thread to resume 1455 * @return thread in which the first suspend event occurs 1456 */ resumeToLineBreakpoint(IJavaThread resumeThread, ILineBreakpoint bp)1457 protected IJavaThread resumeToLineBreakpoint(IJavaThread resumeThread, ILineBreakpoint bp) throws Exception { 1458 DebugEventWaiter waiter= new DebugElementKindEventDetailWaiter(DebugEvent.SUSPEND, IJavaThread.class, DebugEvent.BREAKPOINT); 1459 waiter.setTimeout(DEFAULT_TIMEOUT); 1460 waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); 1461 1462 resumeThread.resume(); 1463 1464 Object suspendee= waiter.waitForEvent(); 1465 setEventSet(waiter.getEventSet()); 1466 assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$ 1467 assertTrue("suspendee was not an IJavaThread", suspendee instanceof IJavaThread); //$NON-NLS-1$ 1468 IJavaThread thread = (IJavaThread) suspendee; 1469 IBreakpoint hit = getBreakpoint(thread); 1470 assertNotNull("suspended, but not by breakpoint", hit); //$NON-NLS-1$ 1471 assertTrue("hit un-registered breakpoint", bp.equals(hit)); //$NON-NLS-1$ 1472 assertTrue("suspended, but not by line breakpoint", hit instanceof ILineBreakpoint); //$NON-NLS-1$ 1473 ILineBreakpoint breakpoint= (ILineBreakpoint) hit; 1474 int lineNumber = breakpoint.getLineNumber(); 1475 int stackLine = thread.getTopStackFrame().getLineNumber(); 1476 assertTrue("line numbers of breakpoint and stack frame do not match", lineNumber == stackLine); //$NON-NLS-1$ 1477 1478 return (IJavaThread)suspendee; 1479 } 1480 1481 /** 1482 * Resumes the given thread, and waits for the debug target 1483 * to terminate (i.e. finish/exit the program). 1484 * 1485 * @param thread thread to resume 1486 */ exit(IJavaThread thread)1487 protected void exit(IJavaThread thread) throws Exception { 1488 DebugEventWaiter waiter= new DebugElementKindEventWaiter(DebugEvent.TERMINATE, IProcess.class); 1489 waiter.setTimeout(DEFAULT_TIMEOUT); 1490 waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); 1491 1492 thread.resume(); 1493 1494 Object suspendee= waiter.waitForEvent(); 1495 setEventSet(waiter.getEventSet()); 1496 assertNotNull("Program did not terminate.", suspendee); //$NON-NLS-1$ 1497 } 1498 1499 /** 1500 * Resumes the given thread, and waits the associated debug 1501 * target to terminate. 1502 * 1503 * @param thread thread to resume 1504 * @return the terminated debug target 1505 */ resumeAndExit(IJavaThread thread)1506 protected IJavaDebugTarget resumeAndExit(IJavaThread thread) throws Exception { 1507 DebugEventWaiter waiter= new DebugElementEventWaiter(DebugEvent.TERMINATE, thread.getDebugTarget()); 1508 waiter.setTimeout(DEFAULT_TIMEOUT); 1509 waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); 1510 1511 thread.resume(); 1512 1513 Object suspendee= waiter.waitForEvent(); 1514 setEventSet(waiter.getEventSet()); 1515 assertNotNull("Program did not terminate.", suspendee); //$NON-NLS-1$ 1516 IJavaDebugTarget target = (IJavaDebugTarget)suspendee; 1517 assertTrue("program should have exited", target.isTerminated() || target.isDisconnected()); //$NON-NLS-1$ 1518 return target; 1519 } 1520 1521 /** 1522 * Returns the launch configuration for the given main type 1523 * 1524 * @param mainTypeName program to launch 1525 * @see ProjectCreationDecorator 1526 */ getLaunchConfiguration(String mainTypeName)1527 protected ILaunchConfiguration getLaunchConfiguration(String mainTypeName) { 1528 return getLaunchConfiguration(getProjectContext(), mainTypeName); 1529 } 1530 1531 /** 1532 * Returns the launch configuration for the given main type 1533 * 1534 * @param mainTypeName program to launch 1535 * @see ProjectCreationDecorator 1536 */ getLaunchConfiguration(IJavaProject project, String mainTypeName)1537 protected ILaunchConfiguration getLaunchConfiguration(IJavaProject project, String mainTypeName) { 1538 IFile file = project.getProject().getFolder(LAUNCHCONFIGURATIONS).getFile(mainTypeName + LAUNCH_EXTENSION); 1539 ILaunchConfiguration config = getLaunchManager().getLaunchConfiguration(file); 1540 assertNotNull("the configuration cannot be null", config); 1541 assertTrue("Could not find launch configuration for " + mainTypeName, config.exists()); //$NON-NLS-1$ 1542 return config; 1543 } 1544 1545 /** 1546 * Returns the launch configuration in the specified folder in the given project, for the given main type 1547 * 1548 * @param project the project to look in 1549 * @param containername the name of the container in the specified project to look for the config 1550 * @param mainTypeName program to launch 1551 * @see ProjectCreationDecorator 1552 */ getLaunchConfiguration(IJavaProject project, String containername, String mainTypeName)1553 protected ILaunchConfiguration getLaunchConfiguration(IJavaProject project, String containername, String mainTypeName) { 1554 IFile file = project.getProject().getFolder(containername).getFile(mainTypeName + LAUNCH_EXTENSION); 1555 ILaunchConfiguration config = getLaunchManager().getLaunchConfiguration(file); 1556 assertNotNull("the configuration cannot be null", config); 1557 assertTrue("Could not find launch configuration for " + mainTypeName, config.exists()); //$NON-NLS-1$ 1558 return config; 1559 } 1560 1561 /** 1562 * Returns the corresponding <code>IResource</code> from the <code>IJavaElement</code> with the 1563 * specified name 1564 * @param typeName the name of the <code>IJavaElement</code> to get the resource for 1565 * @return the corresponding <code>IResource</code> from the <code>IJavaElement</code> with the 1566 * specified name 1567 * @throws Exception 1568 */ getBreakpointResource(String typeName)1569 protected IResource getBreakpointResource(String typeName) throws Exception { 1570 IJavaElement element = getProjectContext().findElement(new Path(typeName + JAVA_EXTENSION)); 1571 IResource resource = element.getCorrespondingResource(); 1572 if (resource == null) { 1573 resource = getProjectContext().getProject(); 1574 } 1575 return resource; 1576 } 1577 1578 /** 1579 * Returns the resource from the specified type or the project from the testing java project in the 1580 * event there is no resource from the specified type 1581 * @param type 1582 * @return 1583 * @throws Exception 1584 */ getBreakpointResource(IType type)1585 protected IResource getBreakpointResource(IType type) throws Exception { 1586 if (type == null) { 1587 return getProjectContext().getProject(); 1588 } 1589 IResource resource = type.getResource(); 1590 if (resource == null) { 1591 resource = type.getJavaProject().getProject(); 1592 } 1593 return resource; 1594 } 1595 1596 /** 1597 * Creates and returns a line breakpoint at the given line number in the type with the 1598 * given name. 1599 * 1600 * @param lineNumber line number 1601 * @param typeName type name 1602 */ createLineBreakpoint(int lineNumber, String typeName)1603 protected IJavaLineBreakpoint createLineBreakpoint(int lineNumber, String typeName) throws Exception { 1604 IType type = getType(typeName); 1605 assertNotNull("Could not find the requested IType: "+typeName, type); 1606 return createLineBreakpoint(type, lineNumber); 1607 } 1608 1609 /** 1610 * Creates am new java line breakpoint 1611 * @param lineNumber 1612 * @param root 1613 * @param packageName 1614 * @param cuName 1615 * @param fullTargetName 1616 * @return a new line breakpoint 1617 */ createLineBreakpoint(int lineNumber, String root, String packageName, String cuName, String fullTargetName)1618 protected IJavaLineBreakpoint createLineBreakpoint(int lineNumber, String root, String packageName, String cuName, 1619 String fullTargetName) throws Exception{ 1620 IJavaProject javaProject = getProjectContext(); 1621 ICompilationUnit cunit = getCompilationUnit(javaProject, root, packageName, cuName); 1622 assertNotNull("did not find requested Compilation Unit", cunit); //$NON-NLS-1$ 1623 IType targetType = (IType)(new MemberParser()).getDeepest(cunit,fullTargetName); 1624 assertNotNull("did not find requested type", targetType); //$NON-NLS-1$ 1625 assertTrue("did not find type to install breakpoint in", targetType.exists()); //$NON-NLS-1$ 1626 1627 return createLineBreakpoint(targetType, lineNumber); 1628 } 1629 1630 1631 /** 1632 * Creates a line breakpoint in the given type (may be a top level non public type) 1633 * 1634 * @param lineNumber line number to create the breakpoint at 1635 * @param packageName fully qualified package name containing the type, example "a.b.c" 1636 * @param cuName simple name of compilation unit containing the type, example "Something.java" 1637 * @param typeName $ qualified type name, example "Something" or "NonPublic" or "Something$Inner" 1638 * @return line breakpoint 1639 * @throws Exception 1640 */ createLineBreakpoint(int lineNumber, String packageName, String cuName, String typeName)1641 protected IJavaLineBreakpoint createLineBreakpoint(int lineNumber, String packageName, String cuName, String typeName) throws Exception { 1642 IType type = getType(packageName, cuName, typeName); 1643 assertNotNull("Could not find the requested IType: "+typeName, type); 1644 return createLineBreakpoint(type, lineNumber); 1645 } 1646 1647 /** 1648 * Creates a line breakpoint in the given type at the given line number. 1649 * 1650 * @param type type in which to install the breakpoint 1651 * @param lineNumber line number to install the breakpoint at 1652 * @return line breakpoint 1653 * @throws Exception 1654 */ createLineBreakpoint(IType type, int lineNumber)1655 protected IJavaLineBreakpoint createLineBreakpoint(IType type, int lineNumber) throws Exception { 1656 assertNotNull("You cannot create a line breakpoint for a null IType", type); 1657 IMember member = null; 1658 IJavaElement sourceElement = null; 1659 String source = null; 1660 if (type.isBinary()) { 1661 IClassFile classFile = type.getClassFile(); 1662 source = classFile.getSource(); 1663 sourceElement = classFile; 1664 } else { 1665 ICompilationUnit unit = type.getCompilationUnit(); 1666 source = unit.getSource(); 1667 sourceElement = unit; 1668 } 1669 // translate line number to offset 1670 if (source != null) { 1671 Document document = new Document(source); 1672 IRegion region = document.getLineInformation(lineNumber); 1673 if (sourceElement instanceof ICompilationUnit) { 1674 member = (IMember) ((ICompilationUnit)sourceElement).getElementAt(region.getOffset()); 1675 } else { 1676 member = (IMember) ((IClassFile)sourceElement).getElementAt(region.getOffset()); 1677 } 1678 } 1679 Map<String, Object> map = getExtraBreakpointAttributes(member); 1680 IJavaLineBreakpoint bp = JDIDebugModel.createLineBreakpoint(getBreakpointResource(type), type.getFullyQualifiedName(), lineNumber, -1, -1, 0, true, map); 1681 forceDeltas(bp); 1682 return bp; 1683 } 1684 1685 /** 1686 * Forces marker deltas to be sent based on breakpoint creation. 1687 * 1688 * @param breakpoint 1689 */ forceDeltas(IBreakpoint breakpoint)1690 private void forceDeltas(IBreakpoint breakpoint) throws CoreException { 1691 IProject project = breakpoint.getMarker().getResource().getProject(); 1692 if (project != null) { 1693 project.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null); 1694 } 1695 } 1696 1697 /** 1698 * Returns the type in the test project based on the given name. The type name may refer to a 1699 * top level non public type. 1700 * 1701 * @param packageName package name, example "a.b.c" 1702 * @param cuName simple compilation unit name within the package, example "Something.java" 1703 * @param typeName simple dot qualified type name, example "Something" or "NonPublic" or "Something.Inner" 1704 * @return associated type or <code>null</code> if none 1705 * @throws Exception 1706 */ getType(String packageName, String cuName, String typeName)1707 protected IType getType(String packageName, String cuName, String typeName) throws Exception { 1708 IPackageFragment[] packageFragments = getProjectContext().getPackageFragments(); 1709 for (int i = 0; i < packageFragments.length; i++) { 1710 IPackageFragment fragment = packageFragments[i]; 1711 if (fragment.getElementName().equals(packageName)) { 1712 ICompilationUnit compilationUnit = fragment.getCompilationUnit(cuName); 1713 String[] names = typeName.split("\\$"); //$NON-NLS-1$ 1714 IType type = compilationUnit.getType(names[0]); 1715 for (int j = 1; j < names.length; j++) { 1716 type = type.getType(names[j]); 1717 } 1718 if (type.exists()) { 1719 return type; 1720 } 1721 } 1722 } 1723 return null; 1724 } 1725 1726 /** 1727 * Creates and returns a map of java element breakpoint attributes for a breakpoint on the 1728 * given java element, or <code>null</code> if none 1729 * 1730 * @param element java element the breakpoint is associated with 1731 * @return map of breakpoint attributes or <code>null</code> 1732 * @throws Exception 1733 */ getExtraBreakpointAttributes(IMember element)1734 protected Map<String, Object> getExtraBreakpointAttributes(IMember element) throws Exception { 1735 if (element != null && element.exists()) { 1736 Map<String, Object> map = new HashMap<>(); 1737 ISourceRange sourceRange = element.getSourceRange(); 1738 int start = sourceRange.getOffset(); 1739 int end = start + sourceRange.getLength(); 1740 IType type = null; 1741 if (element instanceof IType) { 1742 type = (IType) element; 1743 } else { 1744 type = element.getDeclaringType(); 1745 } 1746 BreakpointUtils.addJavaBreakpointAttributesWithMemberDetails(map, type, start, end); 1747 return map; 1748 } 1749 return null; 1750 } 1751 1752 /** 1753 * Creates and returns a line breakpoint at the given line number in the type with the 1754 * given name and sets the specified condition on the breakpoint. 1755 * 1756 * @param lineNumber line number 1757 * @param typeName type name 1758 * @param condition condition 1759 */ createConditionalLineBreakpoint(int lineNumber, String typeName, String condition, boolean suspendOnTrue)1760 protected IJavaLineBreakpoint createConditionalLineBreakpoint(int lineNumber, String typeName, String condition, boolean suspendOnTrue) throws Exception { 1761 IJavaLineBreakpoint bp = createLineBreakpoint(lineNumber, typeName); 1762 bp.setCondition(condition); 1763 bp.setConditionEnabled(true); 1764 bp.setConditionSuspendOnTrue(suspendOnTrue); 1765 return bp; 1766 } 1767 1768 /** 1769 * Creates and returns a pattern breakpoint at the given line number in the 1770 * source file with the given name. 1771 * 1772 * @param lineNumber line number 1773 * @param sourceName name of source file 1774 * @param pattern the pattern of the class file name 1775 */ createPatternBreakpoint(int lineNumber, String sourceName, String pattern)1776 protected IJavaPatternBreakpoint createPatternBreakpoint(int lineNumber, String sourceName, String pattern) throws Exception { 1777 return JDIDebugModel.createPatternBreakpoint(getProjectContext().getProject(), sourceName, pattern, lineNumber, -1, -1, 0, true, null); 1778 } 1779 1780 /** 1781 * Creates and returns a target pattern breakpoint at the given line number in the 1782 * source file with the given name. 1783 * 1784 * @param lineNumber line number 1785 * @param sourceName name of source file 1786 */ createTargetPatternBreakpoint(int lineNumber, String sourceName)1787 protected IJavaTargetPatternBreakpoint createTargetPatternBreakpoint(int lineNumber, String sourceName) throws Exception { 1788 return JDIDebugModel.createTargetPatternBreakpoint(getProjectContext().getProject(), sourceName, lineNumber, -1, -1, 0, true, null); 1789 } 1790 1791 /** 1792 * Creates and returns a stratum breakpoint at the given line number in the 1793 * source file with the given name. 1794 * 1795 * @param lineNumber line number 1796 * @param sourceName name of source file 1797 * @param stratum the stratum of the source file 1798 */ createStratumBreakpoint(int lineNumber, String sourceName, String stratum)1799 protected IJavaStratumLineBreakpoint createStratumBreakpoint(int lineNumber, String sourceName, String stratum) throws Exception { 1800 return JDIDebugModel.createStratumBreakpoint(getProjectContext().getProject(), stratum, sourceName, null, null, lineNumber, -1, -1, 0, true, null); 1801 } 1802 1803 /** 1804 * Creates and returns a method breakpoint 1805 * 1806 * @param typeNamePattern type name pattern 1807 * @param methodName method name 1808 * @param methodSignature method signature or <code>null</code> 1809 * @param entry whether to break on entry 1810 * @param exit whether to break on exit 1811 */ createMethodBreakpoint(String typeNamePattern, String methodName, String methodSignature, boolean entry, boolean exit)1812 protected IJavaMethodBreakpoint createMethodBreakpoint(String typeNamePattern, String methodName, String methodSignature, boolean entry, boolean exit) throws Exception { 1813 return createMethodBreakpoint(getProjectContext(), typeNamePattern, methodName, methodSignature, entry, exit); 1814 } 1815 1816 /** 1817 * Creates and returns a method breakpoint 1818 * 1819 * @param project java project 1820 * @param typeNamePattern type name pattern 1821 * @param methodName method name 1822 * @param methodSignature method signature or <code>null</code> 1823 * @param entry whether to break on entry 1824 * @param exit whether to break on exit 1825 */ createMethodBreakpoint(IJavaProject project, String typeNamePattern, String methodName, String methodSignature, boolean entry, boolean exit)1826 protected IJavaMethodBreakpoint createMethodBreakpoint(IJavaProject project, String typeNamePattern, String methodName, String methodSignature, boolean entry, boolean exit) throws Exception { 1827 IMethod method= null; 1828 IResource resource = project.getProject(); 1829 if (methodSignature != null && methodName != null) { 1830 IType type = project.findType(typeNamePattern); 1831 if (type != null ) { 1832 resource = getBreakpointResource(type); 1833 method = type.getMethod(methodName, Signature.getParameterTypes(methodSignature)); 1834 } 1835 } 1836 Map<String, Object> map = getExtraBreakpointAttributes(method); 1837 IJavaMethodBreakpoint bp = JDIDebugModel.createMethodBreakpoint(resource, typeNamePattern, methodName, methodSignature, entry, exit,false, -1, -1, -1, 0, true, map); 1838 forceDeltas(bp); 1839 return bp; 1840 } 1841 1842 /** 1843 * Creates a method breakpoint in a fully specified type (potentially non public). 1844 * 1845 * @param packageName package name containing type to install breakpoint in, example "a.b.c" 1846 * @param cuName simple compilation unit name within package, example "Something.java" 1847 * @param typeName $ qualified type name within compilation unit, example "Something" or 1848 * "NonPublic" or "Something$Inner" 1849 * @param methodName method or <code>null</code> for all methods 1850 * @param methodSignature JLS method signature or <code>null</code> for all methods with the given name 1851 * @param entry whether to break on entry 1852 * @param exit whether to break on exit 1853 * @return method breakpoint 1854 * @throws Exception 1855 */ createMethodBreakpoint(String packageName, String cuName, String typeName, String methodName, String methodSignature, boolean entry, boolean exit)1856 protected IJavaMethodBreakpoint createMethodBreakpoint(String packageName, String cuName, String typeName, String methodName, String methodSignature, boolean entry, boolean exit) throws Exception { 1857 IType type = getType(packageName, cuName, typeName); 1858 assertNotNull("did not find type to install breakpoint in", type); //$NON-NLS-1$ 1859 IMethod method= null; 1860 if (methodSignature != null && methodName != null) { 1861 if (type != null ) { 1862 method = type.getMethod(methodName, Signature.getParameterTypes(methodSignature)); 1863 } 1864 } 1865 Map<String, Object> map = getExtraBreakpointAttributes(method); 1866 IJavaMethodBreakpoint bp = JDIDebugModel.createMethodBreakpoint(getBreakpointResource(type), type.getFullyQualifiedName(), methodName, methodSignature, entry, exit,false, -1, -1, -1, 0, true, map); 1867 forceDeltas(bp); 1868 return bp; 1869 } 1870 1871 1872 /** 1873 * Creates a MethodBreakPoint on the method specified at the given path. 1874 * Syntax: 1875 * Type$InnerType$MethodNameAndSignature$AnonymousTypeDeclarationNumber$FieldName 1876 * eg:<code> 1877 * public class Foo{ 1878 * class Inner 1879 * { 1880 * public void aMethod() 1881 * { 1882 * Object anon = new Object(){ 1883 * int anIntField; 1884 * String anonTypeMethod() {return "an Example";} 1885 * } 1886 * } 1887 * } 1888 * }</code> 1889 * Syntax to get the anonymous toString would be: Foo$Inner$aMethod()V$1$anonTypeMethod()QString 1890 * so, createMethodBreakpoint(packageName, cuName, "Foo$Inner$aMethod()V$1$anonTypeMethod()QString",true,false); 1891 */ createMethodBreakpoint(String root, String packageName, String cuName, String fullTargetName, boolean entry, boolean exit)1892 protected IJavaMethodBreakpoint createMethodBreakpoint(String root, String packageName, String cuName, 1893 String fullTargetName, boolean entry, boolean exit) throws Exception { 1894 1895 IJavaProject javaProject = getProjectContext(); 1896 ICompilationUnit cunit = getCompilationUnit(javaProject, root, packageName, cuName); 1897 assertNotNull("did not find requested Compilation Unit", cunit); //$NON-NLS-1$ 1898 IMethod targetMethod = (IMethod)(new MemberParser()).getDeepest(cunit,fullTargetName); 1899 assertNotNull("did not find requested method", targetMethod); //$NON-NLS-1$ 1900 assertTrue("Given method does not exist", targetMethod.exists()); //$NON-NLS-1$ 1901 IType methodParent = (IType)targetMethod.getParent();//safe - method's only parent = Type 1902 assertNotNull("did not find type to install breakpoint in", methodParent); //$NON-NLS-1$ 1903 1904 Map<String, Object> map = getExtraBreakpointAttributes(targetMethod); 1905 IJavaMethodBreakpoint bp = JDIDebugModel.createMethodBreakpoint(getBreakpointResource(methodParent), methodParent.getFullyQualifiedName(),targetMethod.getElementName(), targetMethod.getSignature(), entry, exit,false, -1, -1, -1, 0, true, map); 1906 forceDeltas(bp); 1907 return bp; 1908 } 1909 1910 /** 1911 * @param cu the Compilation where the target resides 1912 * @param target the full name of the target, as per MemberParser syntax 1913 * @return the requested Member 1914 */ getMember(ICompilationUnit cu, String target)1915 protected IMember getMember(ICompilationUnit cu, String target) { 1916 IMember toReturn = (new MemberParser()).getDeepest(cu,target); 1917 return toReturn; 1918 } 1919 1920 /** 1921 * Delegate method to get a resource with a specific name from the testing workspace 'src' folder 1922 * @param name the name of the <code>IResource</code> to get 1923 * @return the specified <code>IResource</code> or <code>null</code> if it does not exist 1924 * 1925 * @since 3.4 1926 */ getResource(String name)1927 protected IResource getResource(String name) { 1928 return ResourcesPlugin.getWorkspace().getRoot().findMember(new Path("/DebugTests/src/"+name)); 1929 } 1930 1931 /** 1932 * Creates and returns a class prepare breakpoint on the type with the given fully qualified name. 1933 * 1934 * @param typeName type on which to create the breakpoint 1935 * @return breakpoint 1936 * @throws Exception 1937 */ createClassPrepareBreakpoint(String typeName)1938 protected IJavaClassPrepareBreakpoint createClassPrepareBreakpoint(String typeName) throws Exception { 1939 return createClassPrepareBreakpoint(getType(typeName)); 1940 } 1941 1942 /** 1943 * Creates and returns a class prepare breakpoint on the type with the given fully qualified name. 1944 * 1945 * @param typeName type on which to create the breakpoint 1946 * @return breakpoint 1947 * @throws Exception 1948 */ createClassPrepareBreakpoint(String root, String packageName, String cuName, String fullTargetName)1949 protected IJavaClassPrepareBreakpoint createClassPrepareBreakpoint(String root, 1950 String packageName, String cuName, String fullTargetName) throws Exception { 1951 ICompilationUnit cunit = getCompilationUnit(getProjectContext(), root, packageName, cuName); 1952 IType type = (IType)getMember(cunit,fullTargetName); 1953 assertTrue("Target type not found", type.exists()); //$NON-NLS-1$ 1954 return createClassPrepareBreakpoint(type); 1955 } 1956 1957 /** 1958 * Creates a class prepare breakpoint in a fully specified type (potentially non public). 1959 * 1960 * @param packageName package name containing type to install breakpoint in, example "a.b.c" 1961 * @param cuName simple compilation unit name within package, example "Something.java" 1962 * @param typeName $ qualified type name within compilation unit, example "Something" or 1963 * "NonPublic" or "Something$Inner" 1964 */ createClassPrepareBreakpoint(String packageName, String cuName, String typeName)1965 protected IJavaClassPrepareBreakpoint createClassPrepareBreakpoint(String packageName, String cuName, String typeName) throws Exception { 1966 return createClassPrepareBreakpoint(getType(packageName, cuName, typeName)); 1967 } 1968 1969 /** 1970 * Creates a class prepare breakpoint for the given type 1971 * 1972 * @param type type 1973 * @return class prepare breakpoint 1974 * @throws Exception 1975 */ createClassPrepareBreakpoint(IType type)1976 protected IJavaClassPrepareBreakpoint createClassPrepareBreakpoint(IType type) throws Exception { 1977 assertNotNull("type not specified for class prepare breakpoint", type); //$NON-NLS-1$ 1978 int kind = IJavaClassPrepareBreakpoint.TYPE_CLASS; 1979 if (type.isInterface()) { 1980 kind = IJavaClassPrepareBreakpoint.TYPE_INTERFACE; 1981 } 1982 Map<String, Object> map = getExtraBreakpointAttributes(type); 1983 IJavaClassPrepareBreakpoint bp = JDIDebugModel.createClassPrepareBreakpoint(getBreakpointResource(type), type.getFullyQualifiedName(), kind, -1, -1, true, map); 1984 forceDeltas(bp); 1985 return bp; 1986 } 1987 1988 /** 1989 * Returns the Java model type from the test project with the given name or <code>null</code> 1990 * if none. 1991 * 1992 * @param typeName 1993 * @return type or <code>null</code> 1994 * @throws Exception 1995 */ getType(String typeName)1996 protected IType getType(String typeName) throws Exception { 1997 return getProjectContext().findType(typeName); 1998 } 1999 2000 /** 2001 * Creates and returns a watchpoint 2002 * 2003 * @param typeNmae type name 2004 * @param fieldName field name 2005 * @param access whether to suspend on field access 2006 * @param modification whether to suspend on field modification 2007 */ createWatchpoint(String typeName, String fieldName, boolean access, boolean modification)2008 protected IJavaWatchpoint createWatchpoint(String typeName, String fieldName, boolean access, boolean modification) throws Exception { 2009 IType type = getType(typeName); 2010 return createWatchpoint(type, fieldName, access, modification); 2011 } 2012 2013 /** 2014 * Creates and returns an exception breakpoint 2015 * 2016 * @param exName exception name 2017 * @param caught whether to suspend in caught locations 2018 * @param uncaught whether to suspend in uncaught locations 2019 */ createExceptionBreakpoint(String exName, boolean caught, boolean uncaught)2020 protected IJavaExceptionBreakpoint createExceptionBreakpoint(String exName, boolean caught, boolean uncaught) throws Exception { 2021 IType type = getType(exName); 2022 Map<String, Object> map = getExtraBreakpointAttributes(type); 2023 IJavaExceptionBreakpoint bp = JDIDebugModel.createExceptionBreakpoint(getBreakpointResource(type),exName, caught, uncaught, false, true, map); 2024 forceDeltas(bp); 2025 return bp; 2026 } 2027 2028 /** 2029 * Creates and returns a watchpoint 2030 * 2031 * @param typeNmae type name 2032 * @param fieldName field name 2033 * @param access whether to suspend on field access 2034 * @param modification whether to suspend on field modification 2035 */ 2036 /* protected IJavaWatchpoint createWatchpoint(String typeName, String fieldName, boolean access, boolean modification) throws Exception { 2037 IType type = getType(typeName); 2038 return createWatchpoint(type, fieldName, access, modification); 2039 }*/ 2040 2041 2042 /** 2043 * Creates a WatchPoint on the field specified at the given path. 2044 * Will create watchpoints on fields within anonymous types, inner types, 2045 * local (non-public) types, and public types. 2046 * @param root 2047 * @param packageName package name containing type to install breakpoint in, example "a.b.c" 2048 * @param cuName simple compilation unit name within package, example "Something.java" 2049 * @param fullTargetName - see below 2050 * @param access whether to suspend on access 2051 * @param modification whether to suspend on modification 2052 * @return a watchpoint 2053 * @throws Exception 2054 * @throws CoreException 2055 * 2056 * <p> 2057 * <pre> 2058 * Syntax example: 2059 * Type$InnerType$MethodNameAndSignature$AnonymousTypeDeclarationNumber$FieldName 2060 * eg: 2061 * public class Foo{ 2062 * class Inner 2063 * { 2064 * public void aMethod() 2065 * { 2066 * Object anon = new Object(){ 2067 * int anIntField; 2068 * String anonTypeMethod() {return "an Example";} 2069 * } 2070 * } 2071 * } 2072 * }</pre> 2073 * </p> 2074 * To get the anonymous toString, syntax of fullTargetName would be: <code>Foo$Inner$aMethod()V$1$anIntField</code> 2075 */ createNestedTypeWatchPoint(String root, String packageName, String cuName, String fullTargetName, boolean access, boolean modification)2076 protected IJavaWatchpoint createNestedTypeWatchPoint(String root, String packageName, String cuName, 2077 String fullTargetName, boolean access, boolean modification) throws Exception, CoreException { 2078 2079 ICompilationUnit cunit = getCompilationUnit(getProjectContext(), root, packageName, cuName); 2080 IField field = (IField)getMember(cunit,fullTargetName); 2081 assertNotNull("Path to field is not valid", field); //$NON-NLS-1$ 2082 assertTrue("Field is not valid", field.exists()); //$NON-NLS-1$ 2083 IType type = (IType)field.getParent(); 2084 return createWatchpoint(type, field.getElementName(), access, modification); 2085 } 2086 2087 2088 /** 2089 * Creates a watchpoint in a fully specified type (potentially non public). 2090 * 2091 * @param packageName package name containing type to install breakpoint in, example "a.b.c" 2092 * @param cuName simple compilation unit name within package, example "Something.java" 2093 * @param typeName $ qualified type name within compilation unit, example "Something" or 2094 * "NonPublic" or "Something$Inner" 2095 * @param fieldName name of the field 2096 * @param access whether to suspend on access 2097 * @param modification whether to suspend on modification 2098 */ createWatchpoint(String packageName, String cuName, String typeName, String fieldName, boolean access, boolean modification)2099 protected IJavaWatchpoint createWatchpoint(String packageName, String cuName, String typeName, String fieldName, boolean access, boolean modification) throws Exception { 2100 IType type = getType(packageName, cuName, typeName); 2101 return createWatchpoint(type, fieldName, access, modification); 2102 } 2103 2104 /** 2105 * Creates a watchpoint on the specified field. 2106 * 2107 * @param type type containing the field 2108 * @param fieldName name of the field 2109 * @param access whether to suspend on access 2110 * @param modification whether to suspend on modification 2111 * @return watchpoint 2112 * @throws Exception 2113 */ createWatchpoint(IType type, String fieldName, boolean access, boolean modification)2114 protected IJavaWatchpoint createWatchpoint(IType type, String fieldName, boolean access, boolean modification) throws Exception, CoreException { 2115 assertNotNull("type not specified for watchpoint", type); //$NON-NLS-1$ 2116 IField field = type.getField(fieldName); 2117 Map<String, Object> map = getExtraBreakpointAttributes(field); 2118 IJavaWatchpoint wp = JDIDebugModel.createWatchpoint(getBreakpointResource(type), type.getFullyQualifiedName(), fieldName, -1, -1, -1, 0, true, map); 2119 wp.setAccess(access); 2120 wp.setModification(modification); 2121 forceDeltas(wp); 2122 return wp; 2123 } 2124 2125 /** 2126 * Terminates the given thread and removes its launch 2127 */ terminateAndRemove(IJavaThread thread)2128 protected void terminateAndRemove(IJavaThread thread) { 2129 if (thread != null) { 2130 terminateAndRemove((IJavaDebugTarget)thread.getDebugTarget()); 2131 } 2132 } 2133 2134 /** 2135 * Terminates the given debug target and removes its launch. 2136 * 2137 * NOTE: all breakpoints are removed, all threads are resumed, and then 2138 * the target is terminated. This avoids defunct processes on Linux. 2139 */ terminateAndRemove(IJavaDebugTarget debugTarget)2140 protected void terminateAndRemove(IJavaDebugTarget debugTarget) { 2141 assertNotNull(getName()+" - you cannot terminate and remove a null debug target", debugTarget); 2142 ILaunch launch = debugTarget.getLaunch(); 2143 if (!(debugTarget.isTerminated() || debugTarget.isDisconnected())) { 2144 IPreferenceStore jdiUIPreferences = JDIDebugUIPlugin.getDefault().getPreferenceStore(); 2145 jdiUIPreferences.setValue(IJDIPreferencesConstants.PREF_SUSPEND_ON_UNCAUGHT_EXCEPTIONS, false); 2146 2147 DebugEventWaiter waiter = new DebugElementEventWaiter(DebugEvent.TERMINATE, debugTarget); 2148 waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); 2149 try { 2150 removeAllBreakpoints(); 2151 IThread[] threads = debugTarget.getThreads(); 2152 for (int i = 0; i < threads.length; i++) { 2153 IThread thread = threads[i]; 2154 try { 2155 if (thread.isSuspended()) { 2156 thread.resume(); 2157 } 2158 } catch (CoreException e) { 2159 } 2160 } 2161 debugTarget.getDebugTarget().terminate(); 2162 waiter.waitForEvent(); 2163 } catch (CoreException e) { 2164 } 2165 } 2166 TestUtil.waitForJobs(getName(), 100, 10000); 2167 TestUtil.runEventLoop(); 2168 getLaunchManager().removeLaunch(launch); 2169 // ensure event queue is flushed 2170 DebugEventWaiter waiter = new DebugElementEventWaiter(DebugEvent.MODEL_SPECIFIC, this); 2171 waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); 2172 DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[]{new DebugEvent(this, DebugEvent.MODEL_SPECIFIC)}); 2173 waiter.waitForEvent(); 2174 } 2175 2176 /** 2177 * Deletes all existing breakpoints 2178 */ removeAllBreakpoints()2179 protected void removeAllBreakpoints() { 2180 IBreakpoint[] bps = getBreakpointManager().getBreakpoints(); 2181 try { 2182 getBreakpointManager().removeBreakpoints(bps, true); 2183 } catch (CoreException e) { 2184 } 2185 } 2186 2187 /** 2188 * Returns the first breakpoint the given thread is suspended 2189 * at, or <code>null</code> if none. 2190 * 2191 * @return the first breakpoint the given thread is suspended 2192 * at, or <code>null</code> if none 2193 */ getBreakpoint(IThread thread)2194 protected IBreakpoint getBreakpoint(IThread thread) { 2195 IBreakpoint[] bps = thread.getBreakpoints(); 2196 if (bps.length > 0) { 2197 return bps[0]; 2198 } 2199 return null; 2200 } 2201 2202 /** 2203 * Evaluates the given snippet in the context of the given stack frame and returns 2204 * the result. 2205 * 2206 * @param snippet code snippet 2207 * @param frame stack frame context 2208 * @return evaluation result 2209 */ evaluate(String snippet, IJavaStackFrame frame)2210 protected IEvaluationResult evaluate(String snippet, IJavaStackFrame frame) throws Exception { 2211 DebugEventWaiter waiter= new DebugElementKindEventWaiter(DebugEvent.SUSPEND, IJavaThread.class); 2212 waiter.setTimeout(DEFAULT_TIMEOUT); 2213 waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); 2214 2215 IAstEvaluationEngine engine = EvaluationManager.newAstEvaluationEngine(getProjectContext(), (IJavaDebugTarget)frame.getDebugTarget()); 2216 try { 2217 engine.evaluate(snippet, frame, this, DebugEvent.EVALUATION, true); 2218 2219 Object suspendee= waiter.waitForEvent(); 2220 setEventSet(waiter.getEventSet()); 2221 if(suspendee == null) { 2222 throw new TestAgainException("Program did not suspend evaluating: \n\n"+snippet); 2223 } 2224 assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$ 2225 return fEvaluationResult; 2226 } 2227 finally { 2228 engine.dispose(); 2229 } 2230 } 2231 2232 /** 2233 * Runs an evaluation using an embedded listener and the {@link #DEFAULT_TIMEOUT} for the operation 2234 * @param snippet the snippet to evaluate 2235 * @param thread the suspended thread to run the evaluation on 2236 * @return the {@link IEvaluationResult} 2237 * @throws Exception 2238 * @since 3.1.200 2239 */ evaluate(String snippet, IJavaThread thread)2240 protected IEvaluationResult evaluate(String snippet, IJavaThread thread) throws Exception { 2241 class Listener implements IEvaluationListener { 2242 IEvaluationResult fResult; 2243 @Override 2244 public void evaluationComplete(IEvaluationResult result) { 2245 fResult= result; 2246 } 2247 } 2248 Listener listener= new Listener(); 2249 IJavaStackFrame frame = (IJavaStackFrame) thread.getTopStackFrame(); 2250 assertNotNull("There should be a stackframe", frame); 2251 ASTEvaluationEngine engine = new ASTEvaluationEngine(getProjectContext(), (IJavaDebugTarget) thread.getDebugTarget()); 2252 try { 2253 engine.evaluate(snippet, frame, listener, DebugEvent.EVALUATION_IMPLICIT, false); 2254 long timeout = System.currentTimeMillis()+DEFAULT_TIMEOUT; 2255 while(listener.fResult == null && System.currentTimeMillis() < timeout) { 2256 Thread.sleep(100); 2257 } 2258 return listener.fResult; 2259 } 2260 finally { 2261 engine.dispose(); 2262 } 2263 } 2264 2265 /** 2266 * @see IEvaluationListener#evaluationComplete(IEvaluationResult) 2267 */ 2268 @Override evaluationComplete(IEvaluationResult result)2269 public void evaluationComplete(IEvaluationResult result) { 2270 fEvaluationResult = result; 2271 } 2272 2273 /** 2274 * Performs a step over in the given stack frame and returns when complete. 2275 * 2276 * @param frame stack frame to step in 2277 */ stepOver(IJavaStackFrame frame)2278 protected IJavaThread stepOver(IJavaStackFrame frame) throws Exception { 2279 DebugEventWaiter waiter= new DebugElementKindEventDetailWaiter(DebugEvent.SUSPEND, IJavaThread.class, DebugEvent.STEP_END); 2280 waiter.setTimeout(DEFAULT_TIMEOUT); 2281 waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); 2282 2283 frame.stepOver(); 2284 2285 Object suspendee= waiter.waitForEvent(); 2286 setEventSet(waiter.getEventSet()); 2287 assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$ 2288 return (IJavaThread) suspendee; 2289 } 2290 2291 /** 2292 * Performs a step over in the given stack frame and returns when a breakpoint is hit. 2293 * 2294 * @param frame stack frame to step in 2295 */ stepOverToBreakpoint(IJavaStackFrame frame)2296 protected IJavaThread stepOverToBreakpoint(IJavaStackFrame frame) throws Exception { 2297 DebugEventWaiter waiter= new DebugElementKindEventDetailWaiter(DebugEvent.SUSPEND, IJavaThread.class, DebugEvent.BREAKPOINT); 2298 waiter.setTimeout(DEFAULT_TIMEOUT); 2299 waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); 2300 2301 frame.stepOver(); 2302 2303 Object suspendee= waiter.waitForEvent(); 2304 setEventSet(waiter.getEventSet()); 2305 assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$ 2306 return (IJavaThread) suspendee; 2307 } 2308 2309 /** 2310 * Performs a step into in the given stack frame and returns when complete. 2311 * 2312 * @param frame stack frame to step in 2313 */ stepInto(IJavaStackFrame frame)2314 protected IJavaThread stepInto(IJavaStackFrame frame) throws Exception { 2315 DebugEventWaiter waiter= new DebugElementKindEventDetailWaiter(DebugEvent.SUSPEND, IJavaThread.class, DebugEvent.STEP_END); 2316 waiter.setTimeout(DEFAULT_TIMEOUT); 2317 waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); 2318 2319 frame.stepInto(); 2320 2321 Object suspendee= waiter.waitForEvent(); 2322 setEventSet(waiter.getEventSet()); 2323 assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$ 2324 return (IJavaThread) suspendee; 2325 } 2326 2327 /** 2328 * Performs a step return in the given stack frame and returns when complete. 2329 * 2330 * @param frame stack frame to step return from 2331 */ stepReturn(IJavaStackFrame frame)2332 protected IJavaThread stepReturn(IJavaStackFrame frame) throws Exception { 2333 DebugEventWaiter waiter= new DebugElementKindEventDetailWaiter(DebugEvent.SUSPEND, IJavaThread.class, DebugEvent.STEP_END); 2334 waiter.setTimeout(DEFAULT_TIMEOUT); 2335 waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); 2336 2337 frame.stepReturn(); 2338 2339 Object suspendee= waiter.waitForEvent(); 2340 setEventSet(waiter.getEventSet()); 2341 assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$ 2342 return (IJavaThread) suspendee; 2343 } 2344 2345 /** 2346 * Performs a step into with filters in the given stack frame and returns when 2347 * complete. 2348 * 2349 * @param frame stack frame to step in 2350 */ stepIntoWithFilters(IJavaStackFrame frame)2351 protected IJavaThread stepIntoWithFilters(IJavaStackFrame frame) throws Exception { 2352 return stepIntoWithFilters(frame, true); 2353 } 2354 2355 /** 2356 * Performs a step into with filters in the given stack frame and returns when 2357 * complete. 2358 * 2359 * @param whether to step thru or step return from a filtered location 2360 * @param frame stack frame to step in 2361 */ stepIntoWithFilters(IJavaStackFrame frame, boolean stepThru)2362 protected IJavaThread stepIntoWithFilters(IJavaStackFrame frame, boolean stepThru) throws Exception { 2363 DebugEventWaiter waiter= new DebugElementKindEventWaiter(DebugEvent.SUSPEND, IJavaThread.class); 2364 waiter.setTimeout(DEFAULT_TIMEOUT); 2365 waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); 2366 2367 // turn filters on 2368 IJavaDebugTarget target = (IJavaDebugTarget) frame.getDebugTarget(); 2369 try { 2370 target.setStepFiltersEnabled(true); 2371 target.setStepThruFilters(stepThru); 2372 frame.stepInto(); 2373 Object suspendee= waiter.waitForEvent(); 2374 setEventSet(waiter.getEventSet()); 2375 assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$ 2376 return (IJavaThread) suspendee; 2377 } catch (DebugException e) { 2378 tryTestAgain(e); 2379 } finally { 2380 // turn filters off 2381 target.setStepFiltersEnabled(false); 2382 target.setStepThruFilters(true); 2383 } 2384 return null; 2385 } 2386 2387 /** 2388 * Performs a step return with filters in the given stack frame and returns when 2389 * complete. 2390 * 2391 * @param frame stack frame to step in 2392 */ stepReturnWithFilters(IJavaStackFrame frame)2393 protected IJavaThread stepReturnWithFilters(IJavaStackFrame frame) throws Exception { 2394 DebugEventWaiter waiter= new DebugElementKindEventWaiter(DebugEvent.SUSPEND, IJavaThread.class); 2395 waiter.setTimeout(DEFAULT_TIMEOUT); 2396 waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); 2397 2398 // turn filters on 2399 IJavaDebugTarget target = (IJavaDebugTarget) frame.getDebugTarget(); 2400 try { 2401 target.setStepFiltersEnabled(true); 2402 frame.stepReturn(); 2403 } catch (DebugException e) { 2404 tryTestAgain(e); 2405 } finally { 2406 // turn filters off 2407 target.setStepFiltersEnabled(false); 2408 } 2409 2410 2411 Object suspendee= waiter.waitForEvent(); 2412 setEventSet(waiter.getEventSet()); 2413 assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$ 2414 return (IJavaThread) suspendee; 2415 } 2416 2417 /** 2418 * Performs a step over with filters in the given stack frame and returns when 2419 * complete. 2420 * 2421 * @param frame stack frame to step in 2422 */ stepOverWithFilters(IJavaStackFrame frame)2423 protected IJavaThread stepOverWithFilters(IJavaStackFrame frame) throws Exception { 2424 DebugEventWaiter waiter= new DebugElementKindEventWaiter(DebugEvent.SUSPEND, IJavaThread.class); 2425 waiter.setTimeout(DEFAULT_TIMEOUT); 2426 waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); 2427 2428 // turn filters on 2429 IJavaDebugTarget target = (IJavaDebugTarget) frame.getDebugTarget(); 2430 try { 2431 target.setStepFiltersEnabled(true); 2432 frame.stepOver(); 2433 } catch (DebugException e) { 2434 tryTestAgain(e); 2435 } finally { 2436 // turn filters off 2437 target.setStepFiltersEnabled(false); 2438 } 2439 2440 2441 Object suspendee= waiter.waitForEvent(); 2442 setEventSet(waiter.getEventSet()); 2443 assertNotNull("Program did not suspend.", suspendee); //$NON-NLS-1$ 2444 return (IJavaThread) suspendee; 2445 } 2446 2447 /** 2448 * Returns the compilation unit with the given name. 2449 * 2450 * @param project the project containing the CU 2451 * @param root the name of the source folder in the project 2452 * @param pkg the name of the package (empty string for default package) 2453 * @param name the name of the CU (ex. Something.java) 2454 * @return compilation unit 2455 */ getCompilationUnit(IJavaProject project, String root, String pkg, String name)2456 protected ICompilationUnit getCompilationUnit(IJavaProject project, String root, String pkg, String name) { 2457 IProject p = project.getProject(); 2458 IResource r = p.getFolder(root); 2459 return project.getPackageFragmentRoot(r).getPackageFragment(pkg).getCompilationUnit(name); 2460 } 2461 2462 /** 2463 * Wait for builds to complete 2464 */ waitForBuild()2465 public static void waitForBuild() { 2466 boolean wasInterrupted = false; 2467 do { 2468 try { 2469 Job.getJobManager().join(ResourcesPlugin.FAMILY_AUTO_BUILD, null); 2470 Job.getJobManager().join(ResourcesPlugin.FAMILY_MANUAL_BUILD, null); 2471 // Let also all other pending jobs proceed, ignore console jobs 2472 TestUtil.waitForJobs("waitForBuild", 100, 1000, ProcessConsole.class); 2473 wasInterrupted = false; 2474 } catch (OperationCanceledException e) { 2475 e.printStackTrace(); 2476 } catch (InterruptedException e) { 2477 wasInterrupted = true; 2478 } 2479 } while (wasInterrupted); 2480 } 2481 2482 2483 /** 2484 * Finds the specified variable within the context of the specified stackframe. Returns null if a variable with 2485 * the given name does not exist 2486 * @param frame 2487 * @param name 2488 * @return the <code>IJavaVariable</code> with the given name or <code>null</code> if it 2489 * does not exist 2490 * @throws DebugException 2491 */ findVariable(IJavaStackFrame frame, String name)2492 protected IJavaVariable findVariable(IJavaStackFrame frame, String name) throws DebugException { 2493 IJavaVariable variable = frame.findVariable(name); 2494 if (variable == null) { 2495 // dump visible variables 2496 IDebugModelPresentation presentation = DebugUIPlugin.getModelPresentation(); 2497 System.out.println("Could not find variable '" + name + "' in frame: " + presentation.getText(frame)); //$NON-NLS-1$ //$NON-NLS-2$ 2498 System.out.println("Visible variables are:"); //$NON-NLS-1$ 2499 IVariable[] variables = frame.getVariables(); 2500 for (int i = 0; i < variables.length; i++) { 2501 IVariable variable2 = variables[i]; 2502 System.out.println("\t" + presentation.getText(variable2)); //$NON-NLS-1$ 2503 } 2504 if (!frame.isStatic() && !frame.isNative()) { 2505 IJavaObject ths = frame.getThis(); 2506 if (ths != null) { 2507 variables = ths.getVariables(); 2508 for (int i = 0; i < variables.length; i++) { 2509 IVariable variable2 = variables[i]; 2510 System.out.println("\t" + presentation.getText(variable2)); //$NON-NLS-1$ 2511 } 2512 } 2513 } 2514 } 2515 return variable; 2516 } 2517 2518 /** 2519 * Returns if the local filesystem is case-sensitive or not 2520 * @return true if the local filesystem is case-sensitive, false otherwise 2521 */ isFileSystemCaseSensitive()2522 protected boolean isFileSystemCaseSensitive() { 2523 return Platform.OS_MACOSX.equals(Platform.getOS()) ? false : new File("a").compareTo(new File("A")) != 0; //$NON-NLS-1$ //$NON-NLS-2$ 2524 } 2525 2526 /** 2527 * Creates a shared launch configuration for the type with the given name. 2528 */ createLaunchConfiguration(String mainTypeName)2529 protected ILaunchConfiguration createLaunchConfiguration(String mainTypeName) throws Exception { 2530 return createLaunchConfiguration(getProjectContext(), mainTypeName); 2531 } 2532 2533 /** 2534 * Creates a shared launch configuration for the type with the given name. 2535 */ createLaunchConfiguration(IJavaProject project, String mainTypeName)2536 protected ILaunchConfiguration createLaunchConfiguration(IJavaProject project, String mainTypeName) throws Exception { 2537 return createLaunchConfiguration(project, mainTypeName, false); 2538 } 2539 2540 /** 2541 * Creates a shared launch configuration for the type with the given name. 2542 * 2543 * @param clone 2544 * true if the launch config name should be different from the main type name 2545 */ createLaunchConfiguration(IJavaProject project, String mainTypeName, boolean clone)2546 protected ILaunchConfiguration createLaunchConfiguration(IJavaProject project, String mainTypeName, boolean clone) throws Exception { 2547 ILaunchConfigurationType type = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION); 2548 String configName = clone ? mainTypeName + CLONE_SUFFIX : mainTypeName; 2549 ILaunchConfigurationWorkingCopy config = type.newInstance(project.getProject().getFolder(LAUNCHCONFIGURATIONS), configName); 2550 config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, mainTypeName); 2551 config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, project.getElementName()); 2552 setEnvironment(config); 2553 Set<String> modes = new HashSet<>(); 2554 modes.add(ILaunchManager.RUN_MODE); 2555 config.setPreferredLaunchDelegate(modes, LOCAL_JAVA_APPLICATION_TYPE_ID); 2556 modes = new HashSet<>(); 2557 modes.add(ILaunchManager.DEBUG_MODE); 2558 config.setPreferredLaunchDelegate(modes, LOCAL_JAVA_APPLICATION_TYPE_ID); 2559 // use 'java' instead of 'javaw' to launch tests (javaw is problematic 2560 // on JDK1.4.2) 2561 Map<String, String> map = new HashMap<>(1); 2562 map.put(IJavaLaunchConfigurationConstants.ATTR_JAVA_COMMAND, JAVA); 2563 config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_TYPE_SPECIFIC_ATTRS_MAP, map); 2564 return config.doSave(); 2565 } 2566 2567 /** 2568 * Creates a shared launch configuration for the type with the given name. 2569 */ createLaunchConfiguration(IJavaProject project, String containername, String mainTypeName)2570 protected ILaunchConfiguration createLaunchConfiguration(IJavaProject project, String containername, String mainTypeName) throws Exception { 2571 ILaunchConfigurationType type = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION); 2572 ILaunchConfigurationWorkingCopy config = type.newInstance(project.getProject().getFolder(containername), mainTypeName); 2573 config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, mainTypeName); 2574 config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, project.getElementName()); 2575 setEnvironment(config); 2576 Set<String> modes = new HashSet<>(); 2577 modes.add(ILaunchManager.RUN_MODE); 2578 config.setPreferredLaunchDelegate(modes, LOCAL_JAVA_APPLICATION_TYPE_ID); 2579 modes = new HashSet<>(); 2580 modes.add(ILaunchManager.DEBUG_MODE); 2581 config.setPreferredLaunchDelegate(modes, LOCAL_JAVA_APPLICATION_TYPE_ID); 2582 // use 'java' instead of 'javaw' to launch tests (javaw is problematic 2583 // on JDK1.4.2) 2584 Map<String, String> map = new HashMap<>(1); 2585 map.put(IJavaLaunchConfigurationConstants.ATTR_JAVA_COMMAND, JAVA); 2586 config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_TYPE_SPECIFIC_ATTRS_MAP, map); 2587 return config.doSave(); 2588 } 2589 setEnvironment(ILaunchConfigurationWorkingCopy workingCopy)2590 private void setEnvironment(ILaunchConfigurationWorkingCopy workingCopy) { 2591 Map<String, String> env = getLaunchManager().getNativeEnvironment().entrySet().stream() 2592 .filter(e -> !"JAVA_TOOL_OPTIONS".equals(e.getKey())) 2593 .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); 2594 workingCopy.setAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, false); 2595 workingCopy.setAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, env); 2596 } 2597 2598 /** 2599 * When a test throws the 'try again' exception, try it again. 2600 * @see junit.framework.TestCase#runBare() 2601 */ 2602 @Override runBare()2603 public void runBare() throws Throwable { 2604 boolean tryAgain = true; 2605 int attempts = 0; 2606 while (tryAgain) { 2607 try { 2608 attempts++; 2609 super.runBare(); 2610 tryAgain = false; 2611 } catch (TestAgainException e) { 2612 TestUtil.log(IStatus.ERROR, getName(), "Test failed attempt " + attempts + ". Re-testing.", e); 2613 TestUtil.cleanUp(getName()); 2614 if (attempts > 4) { 2615 // the next attempt will fail 2616 break; 2617 } 2618 } 2619 } 2620 if (tryAgain) { 2621 // last attempt and if it fails then we should fail, see bug 515988 2622 super.runBare(); 2623 } 2624 } 2625 2626 @Override tearDown()2627 protected void tearDown() throws Exception { 2628 TestUtil.log(IStatus.INFO, getName(), "tearDown"); 2629 shutdownDebugTargets(); 2630 TestUtil.cleanUp(getName()); 2631 super.tearDown(); 2632 } 2633 shutdownDebugTargets()2634 protected void shutdownDebugTargets() { 2635 ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager(); 2636 IDebugTarget[] targets = launchManager.getDebugTargets(); 2637 for (IDebugTarget target : targets) { 2638 if (target instanceof JDIDebugTarget) { 2639 ((JDIDebugTarget) target).shutdown(); 2640 } 2641 } 2642 } 2643 2644 /** 2645 * Opens and returns an editor on the given file or <code>null</code> 2646 * if none. The editor will be activated. 2647 * 2648 * @param file 2649 * @return editor or <code>null</code> 2650 */ openEditor(final IFile file)2651 protected IEditorPart openEditor(final IFile file) throws PartInitException, InterruptedException { 2652 Display display = DebugUIPlugin.getStandardDisplay(); 2653 if (Thread.currentThread().equals(display.getThread())) { 2654 IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); 2655 return IDE.openEditor(page, file, true); 2656 } 2657 final IEditorPart[] parts = new IEditorPart[1]; 2658 WorkbenchJob job = new WorkbenchJob(display, "open editor") { 2659 @Override 2660 public IStatus runInUIThread(IProgressMonitor monitor) { 2661 IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); 2662 try { 2663 parts[0] = IDE.openEditor(page, file, true); 2664 } catch (PartInitException e) { 2665 return e.getStatus(); 2666 } 2667 return Status.OK_STATUS; 2668 } 2669 }; 2670 job.schedule(); 2671 job.join(); 2672 return parts[0]; 2673 } 2674 2675 /** 2676 * Opens the {@link IDebugView} with the given id, does nothing if no such view exists. 2677 * This method can return <code>null</code> 2678 * 2679 * @param viewId 2680 * @return the handle to the {@link IDebugView} with the given id 2681 * @throws PartInitException 2682 * @throws InterruptedException 2683 * @since 3.8.100 2684 */ openDebugView(final String viewId)2685 protected IDebugView openDebugView(final String viewId) throws PartInitException, InterruptedException { 2686 if(viewId != null) { 2687 Display display = DebugUIPlugin.getStandardDisplay(); 2688 if (Thread.currentThread().equals(display.getThread())) { 2689 return doShowDebugView(viewId); 2690 } 2691 final IDebugView[] view = new IDebugView[1]; 2692 WorkbenchJob job = new WorkbenchJob("Showing the debug view: "+viewId) { 2693 @Override 2694 public IStatus runInUIThread(IProgressMonitor monitor) { 2695 try { 2696 view[0] = doShowDebugView(viewId); 2697 } 2698 catch(CoreException ce) { 2699 return ce.getStatus(); 2700 } 2701 return Status.OK_STATUS; 2702 } 2703 }; 2704 job.schedule(); 2705 job.join(); 2706 return view[0]; 2707 } 2708 return null; 2709 } 2710 2711 /** 2712 * Opens a debug view 2713 * @param viewId 2714 * @return return the debug view handle or <code>null</code> 2715 * @throws PartInitException 2716 * @since 3.8.100 2717 */ doShowDebugView(String viewId)2718 private IDebugView doShowDebugView(String viewId) throws PartInitException { 2719 IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); 2720 if(window != null) { 2721 IWorkbenchPage page = window.getActivePage(); 2722 assertNotNull("We shold have found the active page to open the debug view in", page); 2723 return (IDebugView) page.showView(viewId); 2724 } 2725 return null; 2726 } 2727 2728 /** 2729 * Toggles a breakpoint in the editor at the given line number returning the breakpoint 2730 * or <code>null</code> if none. 2731 * 2732 * @param editor 2733 * @param lineNumber 2734 * @return returns the created breakpoint or <code>null</code> if none. 2735 * @throws InterruptedException 2736 */ toggleBreakpoint(final IEditorPart editor, int lineNumber)2737 protected IBreakpoint toggleBreakpoint(final IEditorPart editor, int lineNumber) throws InterruptedException { 2738 final IVerticalRulerInfo info = new VerticalRulerInfoStub(lineNumber-1); // sub 1, as the doc lines start at 0 2739 WorkbenchJob job = new WorkbenchJob(DebugUIPlugin.getStandardDisplay(), "toggle breakpoint") { 2740 @Override 2741 public IStatus runInUIThread(IProgressMonitor monitor) { 2742 ToggleBreakpointAction action = new ToggleBreakpointAction(editor, null, info); 2743 action.run(); 2744 return Status.OK_STATUS; 2745 } 2746 }; 2747 final Object lock = new Object(); 2748 final IBreakpoint[] breakpoints = new IBreakpoint[1]; 2749 IBreakpointListener listener = new IBreakpointListener() { 2750 @Override 2751 public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta) { 2752 } 2753 @Override 2754 public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta) { 2755 } 2756 @Override 2757 public void breakpointAdded(IBreakpoint breakpoint) { 2758 synchronized (lock) { 2759 breakpoints[0] = breakpoint; 2760 lock.notifyAll(); 2761 } 2762 } 2763 }; 2764 IBreakpointManager manager = DebugPlugin.getDefault().getBreakpointManager(); 2765 manager.addBreakpointListener(listener); 2766 synchronized (lock) { 2767 job.schedule(); 2768 lock.wait(DEFAULT_TIMEOUT); 2769 } 2770 manager.removeBreakpointListener(listener); 2771 return breakpoints[0]; 2772 } 2773 2774 /** 2775 * Closes all editors in the active workbench page. 2776 */ closeAllEditors()2777 protected void closeAllEditors() { 2778 Runnable closeAll = new Runnable() { 2779 @Override 2780 public void run() { 2781 IWorkbenchWindow activeWorkbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); 2782 activeWorkbenchWindow.getActivePage().closeAllEditors(false); 2783 } 2784 }; 2785 Display display = DebugUIPlugin.getStandardDisplay(); 2786 display.syncExec(closeAll); 2787 } 2788 2789 /** 2790 * Returns the version level of the class files being run, based on the system property <code>java.class.version</code> 2791 * @return the version level of the class files being run in the current VM 2792 * 2793 * @since 3.6 2794 */ getClassFileVersion()2795 protected String getClassFileVersion() { 2796 String version = System.getProperty("java.class.version"); 2797 if(version.compareTo("48.0") <= 0) { 2798 return JavaCore.VERSION_1_4; 2799 } 2800 if(version.compareTo("49.0") <= 0) { 2801 return JavaCore.VERSION_1_5; 2802 } 2803 return JavaCore.VERSION_1_6; 2804 } 2805 2806 /** 2807 * Determines if the test should be attempted again based on the error code. 2808 * See bug 297071. 2809 * 2810 * @param e Debug Exception 2811 * @throws TestAgainException 2812 * @throws DebugException 2813 */ tryTestAgain(DebugException e)2814 protected void tryTestAgain(DebugException e) throws Exception { 2815 Throwable cause = e.getCause(); 2816 if (cause instanceof InternalException) { 2817 int code = ((InternalException)cause).errorCode(); 2818 if (code == 13) { 2819 throw new TestAgainException("Retest - exception during test: "+getName()+": "+e.getMessage()); 2820 } 2821 } 2822 throw e; 2823 } 2824 2825 /** 2826 * Perform the actual evaluation (inspect) 2827 * @param thread 2828 * @return the result of the evaluation 2829 * @throws Exception 2830 */ doEval(IJavaThread thread, String snippet)2831 protected IValue doEval(IJavaThread thread, String snippet) throws Exception{ 2832 class Listener implements IEvaluationListener { 2833 IEvaluationResult fResult; 2834 2835 @Override 2836 public void evaluationComplete(IEvaluationResult result) { 2837 fResult= result; 2838 } 2839 2840 public IEvaluationResult getResult() { 2841 return fResult; 2842 } 2843 } 2844 Listener listener = new Listener(); 2845 IJavaStackFrame frame = (IJavaStackFrame) thread.getTopStackFrame(); 2846 assertNotNull("There should be a stackframe", frame); 2847 ASTEvaluationEngine engine = new ASTEvaluationEngine(getProjectContext(), (IJavaDebugTarget) thread.getDebugTarget()); 2848 try { 2849 engine.evaluate(snippet, frame, listener, DebugEvent.EVALUATION_IMPLICIT, false); 2850 long timeout = System.currentTimeMillis() + 5000; 2851 while(listener.getResult() == null && System.currentTimeMillis() < timeout) { 2852 Thread.sleep(100); 2853 } 2854 IEvaluationResult result = listener.getResult(); 2855 assertNotNull("The evaluation should have result: ", result); 2856 assertNull("Evaluation of '" + snippet + "' should not have exception : " + findCause(result.getException()), result.getException()); 2857 2858 String firstError = result.hasErrors() ? result.getErrorMessages()[0] : ""; 2859 assertFalse("The evaluation of '\" + snippet + \"' should not have errors : " + firstError, result.hasErrors()); 2860 return listener.getResult().getValue(); 2861 } 2862 finally { 2863 engine.dispose(); 2864 } 2865 } 2866 findCause(DebugException problem)2867 private static Object findCause(DebugException problem) { 2868 if (problem == null) { 2869 return null; 2870 } 2871 Throwable cause = problem.getCause(); 2872 if (cause instanceof InvocationException) { 2873 return ((InvocationException)cause).exception().toString(); 2874 } 2875 return cause; 2876 } 2877 2878 /** 2879 * @return true if the UI event loop should be proicessed during wait operations on UI thread 2880 */ enableUIEventLoopProcessingInWaiter()2881 protected boolean enableUIEventLoopProcessingInWaiter() { 2882 return false; 2883 } 2884 assertNoErrorMarkersExist()2885 protected void assertNoErrorMarkersExist() throws Exception { 2886 IJavaProject javaProject = getProjectContext(); 2887 assertNotNull("Java test project cannot be null", javaProject); 2888 IProject project = javaProject.getProject(); 2889 assertNotNull("test project cannot be null", project); 2890 IProject[] projects = { project }; 2891 assertNoErrorMarkersExist(projects); 2892 } 2893 assertNoErrorMarkersExist(IProject[] projects)2894 protected void assertNoErrorMarkersExist(IProject[] projects) throws Exception { 2895 for (IProject project : projects) { 2896 assertNoErrorMarkersExist(project); 2897 } 2898 } 2899 assertNoErrorMarkersExist(IProject project)2900 protected void assertNoErrorMarkersExist(IProject project) throws Exception { 2901 if (project.isAccessible()) { 2902 IMarker[] projectMarkers = project.findMarkers(null, false, IResource.DEPTH_INFINITE); 2903 List<IMarker> errorMarkers = Arrays.stream(projectMarkers).filter(marker -> isErrorMarker(marker)).collect(Collectors.toList()); 2904 String projectErrors = toString(errorMarkers); 2905 assertEquals("found errors on project " + project + ":" + System.lineSeparator() + projectErrors, Collections.EMPTY_LIST, errorMarkers); 2906 } 2907 } 2908 isErrorMarker(IMarker marker)2909 private static boolean isErrorMarker(IMarker marker) { 2910 return marker.getAttribute(IMarker.SEVERITY, -1) == IMarker.SEVERITY_ERROR; 2911 } 2912 toString(Collection<IMarker> markers)2913 private static String toString(Collection<IMarker> markers) { 2914 StringBuilder markersInfo = new StringBuilder(); 2915 for (IMarker marker : markers) { 2916 markersInfo.append(marker); 2917 } 2918 return markersInfo.toString(); 2919 } 2920 } 2921