Bug 463236: Scrapbook evaluations fail in pre-1.7 projects
diff --git a/org.eclipse.jdt.debug.ui/Snippet Support/org/eclipse/jdt/internal/debug/ui/snippeteditor/ScrapbookMain.java b/org.eclipse.jdt.debug.ui/Snippet Support/org/eclipse/jdt/internal/debug/ui/snippeteditor/ScrapbookMain.java
index 23d226f..b3c379f 100644
--- a/org.eclipse.jdt.debug.ui/Snippet Support/org/eclipse/jdt/internal/debug/ui/snippeteditor/ScrapbookMain.java
+++ b/org.eclipse.jdt.debug.ui/Snippet Support/org/eclipse/jdt/internal/debug/ui/snippeteditor/ScrapbookMain.java
@@ -23,10 +23,7 @@
/**
* Support class for launching a snippet evaluation.
* <p>
- * CAUTION 1: If you touch this class, you need to make sure the line number of the {@link #nop()} method's statement gets updated in
- * {@link org.eclipse.jdt.internal.debug.ui.snippeteditor.ScrapbookLauncher#createMagicBreakpoint()}.
- * <p>
- * CAUTION 2: This class gets compiled with target=jsr14, see scripts/buildExtraJAR.xml. Don't use URLClassLoader#close() or other post-1.4 APIs!
+ * CAUTION: This class gets compiled with target=jsr14, see scripts/buildExtraJAR.xml. Don't use URLClassLoader#close() or other post-1.4 APIs!
*/
public class ScrapbookMain {
@@ -61,9 +58,14 @@
method.invoke(null, new Object[] {ScrapbookMain.class});
}
+ /**
+ * The magic "no-op" method, where {@link org.eclipse.jdt.internal.debug.ui.snippeteditor.ScrapbookLauncher#createMagicBreakpoint(String)} sets a
+ * breakpoint.
+ * <p>
+ */
public static void nop() {
try {
- Thread.sleep(100); // TODO: The line number of this statement needs to be updated in ScrapbookLauncher#createMagicBreakpoint()!
+ Thread.sleep(100);
} catch(InterruptedException e) {
}
}
diff --git a/org.eclipse.jdt.debug.ui/snippetsupport.jar b/org.eclipse.jdt.debug.ui/snippetsupport.jar
index bcb9938..2b871e7 100644
--- a/org.eclipse.jdt.debug.ui/snippetsupport.jar
+++ b/org.eclipse.jdt.debug.ui/snippetsupport.jar
Binary files differ
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/ScrapbookLauncher.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/ScrapbookLauncher.java
index dc3876d..12e9feb 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/ScrapbookLauncher.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/ScrapbookLauncher.java
@@ -29,8 +29,10 @@
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IDebugEventSetListener;
@@ -44,6 +46,12 @@
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.ToolFactory;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.util.IClassFileReader;
+import org.eclipse.jdt.core.util.ICodeAttribute;
+import org.eclipse.jdt.core.util.ILineNumberAttribute;
+import org.eclipse.jdt.core.util.IMethodInfo;
import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
import org.eclipse.jdt.debug.core.JDIDebugModel;
import org.eclipse.jdt.debug.ui.IJavaDebugUIConstants;
@@ -130,7 +138,8 @@
}
List<IRuntimeClasspathEntry> cp = new ArrayList<IRuntimeClasspathEntry>(3);
- IRuntimeClasspathEntry supportEntry = JavaRuntime.newArchiveRuntimeClasspathEntry(new Path(jarURL.getFile()));
+ String jarFile = jarURL.getFile();
+ IRuntimeClasspathEntry supportEntry = JavaRuntime.newArchiveRuntimeClasspathEntry(new Path(jarFile));
cp.add(supportEntry);
// get bootpath entries
try {
@@ -142,14 +151,14 @@
}
IRuntimeClasspathEntry[] classPath = cp.toArray(new IRuntimeClasspathEntry[cp.size()]);
- return doLaunch(javaProject, page, classPath);
+ return doLaunch(javaProject, page, classPath, jarFile);
} catch (CoreException e) {
JDIDebugUIPlugin.errorDialog("Unable to launch scrapbook VM", e); //$NON-NLS-1$
}
return null;
}
- private ILaunch doLaunch(IJavaProject p, IFile page, IRuntimeClasspathEntry[] classPath) {
+ private ILaunch doLaunch(IJavaProject p, IFile page, IRuntimeClasspathEntry[] classPath, String jarFile) {
try {
if (fVMsToScrapbooks.isEmpty()) {
// register for debug events if a scrapbook is not currently running
@@ -230,7 +239,7 @@
ILaunch launch = config.launch(ILaunchManager.DEBUG_MODE, null);
if (launch != null) {
IDebugTarget dt = launch.getDebugTarget();
- IBreakpoint magicBreakpoint = createMagicBreakpoint();
+ IBreakpoint magicBreakpoint = createMagicBreakpoint(jarFile);
fScrapbookToVMs.put(page, dt);
fVMsToScrapbooks.put(dt, page);
fVMsToBreakpoints.put(dt, magicBreakpoint);
@@ -245,18 +254,35 @@
}
/**
- * Creates an "invisible" line breakpoint.
+ * Creates an "invisible" line breakpoint.
+ *
+ * @param jarFile
+ * path to the snippetsupport.jar file
* @return the new 'magic' breakpoint
- * @throws CoreException if an exception occurs
+ * @throws CoreException
+ * if an exception occurs
*/
- IBreakpoint createMagicBreakpoint() throws CoreException {
- // set a breakpoint on the "Thread.sleep(100);" line of the no-op method of ScrapbookMain
+ IBreakpoint createMagicBreakpoint(String jarFile) throws CoreException {
+ // set a breakpoint on the "Thread.sleep(100);" line of the "ScrapbookMainnop()" method
String typeName = "org.eclipse.jdt.internal.debug.ui.snippeteditor.ScrapbookMain"; //$NON-NLS-1$
- int lineNumber = 66; // TODO: This line number needs to be adjusted when ScrapbookMain is modified.
- fMagicBreakpoint = JDIDebugModel.createLineBreakpoint(ResourcesPlugin.getWorkspace().getRoot(), typeName, lineNumber, -1, -1, 0, false, null);
- fMagicBreakpoint.setPersisted(false);
- return fMagicBreakpoint;
+ IClassFileReader reader = ToolFactory.createDefaultClassFileReader(jarFile, typeName.replace('.', '/')
+ + ".class", IClassFileReader.METHOD_INFOS | IClassFileReader.METHOD_BODIES); //$NON-NLS-1$
+ IMethodInfo[] methodInfos = reader.getMethodInfos();
+ for (IMethodInfo methodInfo : methodInfos) {
+ if (!CharOperation.equals("nop".toCharArray(), methodInfo.getName())) {//$NON-NLS-1$
+ continue;
+ }
+ ICodeAttribute codeAttribute = methodInfo.getCodeAttribute();
+ ILineNumberAttribute lineNumberAttribute = codeAttribute.getLineNumberAttribute();
+ int[][] lineNumberTable = lineNumberAttribute.getLineNumberTable();
+ int lineNumber = lineNumberTable[0][1];
+
+ fMagicBreakpoint = JDIDebugModel.createLineBreakpoint(ResourcesPlugin.getWorkspace().getRoot(), typeName, lineNumber, -1, -1, 0, false, null);
+ fMagicBreakpoint.setPersisted(false);
+ return fMagicBreakpoint;
+ }
+ throw new CoreException(new Status(IStatus.ERROR, JDIDebugUIPlugin.getUniqueIdentifier(), IJavaDebugUIConstants.INTERNAL_ERROR, "An error occurred creating the evaluation breakpoint location.", null)); //$NON-NLS-1$
}
/**