Bug 511696: [otdre] debugger needs to refresh internal cache after
redefineClasses
diff --git a/plugins/org.eclipse.objectteams.otdt.debug.adaptor/META-INF/MANIFEST.MF b/plugins/org.eclipse.objectteams.otdt.debug.adaptor/META-INF/MANIFEST.MF
index 390f579..e6e5c37 100644
--- a/plugins/org.eclipse.objectteams.otdt.debug.adaptor/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.objectteams.otdt.debug.adaptor/META-INF/MANIFEST.MF
@@ -28,6 +28,7 @@
Bundle-Activator: org.eclipse.objectteams.otdt.internal.debug.adaptor.OTDebugAdaptorPlugin
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-ActivationPolicy: lazy
-Export-Package: org.eclipse.objectteams.otdt.internal.debug.adaptor;x-internal:=true;ot-aspect-host="org.eclipse.objectteams.otdt.debug.adaptor",
- org.eclipse.objectteams.otdt.internal.debug.adaptor.actions;x-internal:=true;ot-aspect-host="org.eclipse.objectteams.otdt.debug.adaptor",
- org.eclipse.objectteams.otdt.internal.debug.adaptor.launching;x-internal:=true;ot-aspect-host="org.eclipse.objectteams.otdt.debug.adaptor"
+Export-Package: org.eclipse.objectteams.otdt.internal.debug.adaptor;ot-aspect-host="org.eclipse.objectteams.otdt.debug.adaptor";x-internal:=true,
+ org.eclipse.objectteams.otdt.internal.debug.adaptor.actions;ot-aspect-host="org.eclipse.objectteams.otdt.debug.adaptor";x-internal:=true,
+ org.eclipse.objectteams.otdt.internal.debug.adaptor.dynamic;ot-aspect-host="org.eclipse.objectteams.otdt.debug.adaptor";x-internal:=true,
+ org.eclipse.objectteams.otdt.internal.debug.adaptor.launching;ot-aspect-host="org.eclipse.objectteams.otdt.debug.adaptor";x-internal:=true
diff --git a/plugins/org.eclipse.objectteams.otdt.debug.adaptor/plugin.xml b/plugins/org.eclipse.objectteams.otdt.debug.adaptor/plugin.xml
index 29ac957..200ce84 100644
--- a/plugins/org.eclipse.objectteams.otdt.debug.adaptor/plugin.xml
+++ b/plugins/org.eclipse.objectteams.otdt.debug.adaptor/plugin.xml
@@ -74,6 +74,11 @@
class="org.eclipse.objectteams.otdt.internal.debug.adaptor.SourceLookupAdaptor"
icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
</team>
+ <team
+ activation="NONE"
+ class="org.eclipse.objectteams.otdt.internal.debug.adaptor.dynamic.RedefineClassesBPListener"
+ icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/team_obj.gif">
+ </team>
</aspectBinding>
<aspectBinding
icon="platform:/plugin/org.eclipse.objectteams.otdt.ui/icons/ot/calloutbinding_obj.gif">
diff --git a/plugins/org.eclipse.objectteams.otdt.debug.adaptor/src/org/eclipse/objectteams/otdt/internal/debug/adaptor/OTDebugAdaptorPlugin.java b/plugins/org.eclipse.objectteams.otdt.debug.adaptor/src/org/eclipse/objectteams/otdt/internal/debug/adaptor/OTDebugAdaptorPlugin.java
index 2eb31bf..a0956c3 100644
--- a/plugins/org.eclipse.objectteams.otdt.debug.adaptor/src/org/eclipse/objectteams/otdt/internal/debug/adaptor/OTDebugAdaptorPlugin.java
+++ b/plugins/org.eclipse.objectteams.otdt.debug.adaptor/src/org/eclipse/objectteams/otdt/internal/debug/adaptor/OTDebugAdaptorPlugin.java
@@ -42,4 +42,9 @@
public static void logError(String msg) {
instance.getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, msg));
}
+
+
+ public static void logException(String msg, Exception ex) {
+ instance.getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, msg, ex));
+ }
}
diff --git a/plugins/org.eclipse.objectteams.otdt.debug.adaptor/src/org/eclipse/objectteams/otdt/internal/debug/adaptor/dynamic/RedefineClassesBPListener.java b/plugins/org.eclipse.objectteams.otdt.debug.adaptor/src/org/eclipse/objectteams/otdt/internal/debug/adaptor/dynamic/RedefineClassesBPListener.java
new file mode 100644
index 0000000..7d8f654
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.debug.adaptor/src/org/eclipse/objectteams/otdt/internal/debug/adaptor/dynamic/RedefineClassesBPListener.java
@@ -0,0 +1,170 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ *
+ * Copyright 2017 GK Software AG
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ *
+ * Contributors:
+ * Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otdt.internal.debug.adaptor.dynamic;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.IBreakpointManager;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.core.model.IDebugTarget;
+import org.eclipse.debug.core.model.IStackFrame;
+import org.eclipse.debug.core.model.IValue;
+import org.eclipse.debug.core.model.IVariable;
+import org.eclipse.jdi.internal.ReferenceTypeImpl;
+import org.eclipse.jdi.internal.ValueCache;
+import org.eclipse.jdi.internal.jdwp.JdwpReferenceTypeID;
+import org.eclipse.jdt.core.dom.Message;
+import org.eclipse.jdt.debug.core.IJavaArray;
+import org.eclipse.jdt.debug.core.IJavaBreakpoint;
+import org.eclipse.jdt.debug.core.IJavaBreakpointListener;
+import org.eclipse.jdt.debug.core.IJavaDebugTarget;
+import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
+import org.eclipse.jdt.debug.core.IJavaObject;
+import org.eclipse.jdt.debug.core.IJavaThread;
+import org.eclipse.jdt.debug.core.IJavaType;
+import org.eclipse.jdt.debug.core.IJavaValue;
+import org.eclipse.jdt.debug.core.JDIDebugModel;
+import org.eclipse.objectteams.otdt.core.ext.WeavingScheme;
+import org.eclipse.objectteams.otdt.debug.internal.breakpoints.ClassRedefinitionBreakpoint;
+import org.eclipse.objectteams.otdt.internal.debug.adaptor.OTDebugAdaptorPlugin;
+
+import com.sun.jdi.VirtualMachine;
+
+import base org.eclipse.jdi.internal.VirtualMachineImpl;
+
+/**
+ * Listen to breakpoint hits on InstrumentationImpl.redefineClasses in order to
+ * <ul>
+ * <li>create obsolete {@link ReferenceTypeImpl} from internal cache
+ * <li>refresh breakpoints in the affected type
+ * </ul>
+ * Implemented as a team only to gain access to the cache inside {@link VirtualMachineImpl}.
+ */
+@SuppressWarnings("restriction")
+public team class RedefineClassesBPListener implements IJavaBreakpointListener {
+
+ /**
+ * Conditionally get a breakpoint listener for class redefinition events (only for OTDRE).
+ */
+ public static IJavaBreakpointListener get(WeavingScheme scheme) {
+ if (scheme == WeavingScheme.OTDRE)
+ return new RedefineClassesBPListener();
+ return null;
+ }
+
+ @Override
+ public int breakpointHit(IJavaThread thread, IJavaBreakpoint breakpoint) {
+ if (!breakpoint.getMarker().exists())
+ return DONT_CARE;
+ try {
+ if (ClassRedefinitionBreakpoint.isRedefineClassesBreakpoint(breakpoint)) {
+ handleClassRedefinition(thread);
+ return IJavaBreakpointListener.DONT_SUSPEND;
+ }
+ }
+ catch (Exception ex) {
+ OTDebugAdaptorPlugin.logException("RedefineClassesBPListener can't read infos from debugTarget anymore. Disconnected?", ex); //$NON-NLS-1$
+ // if something fails, let the debugger go on
+ return IJavaBreakpointListener.DONT_SUSPEND;
+ }
+
+ return IJavaBreakpointListener.DONT_CARE;
+ }
+
+ private void handleClassRedefinition(IJavaThread thread) throws DebugException {
+ IStackFrame frame = thread.getTopStackFrame();
+ IVariable[] variables = frame.getVariables();
+ IValue values = variables[2].getValue();
+ if (values instanceof IJavaArray) {
+ IJavaValue[] arrayValues = ((IJavaArray) values).getValues();
+ for (IJavaValue value : arrayValues) {
+ if (value instanceof IJavaObject) {
+ IJavaValue clazz = ((IJavaObject) value).sendMessage("getDefinitionClass", "()Ljava/lang/Class;", null, thread, false);
+ IJavaValue name = ((IJavaObject) clazz).sendMessage("getName", "()Ljava/lang/String;", null, thread, false);
+ String className = name.getValueString();
+ VirtualMachine vm = ((org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget) thread.getDebugTarget()).getVM();
+ removeTypeFromCache((org.eclipse.jdi.internal.VirtualMachineImpl) vm, className);
+ updateBreakpoints(thread.getDebugTarget(), className);
+ }
+ }
+ }
+ }
+
+ private void removeTypeFromCache(VirtualMachineImpl as VM vm, String typeName) {
+ vm.removeTypeFromCache(typeName);
+ }
+
+ /**
+ * Gateway to inaccessible cache of ReferenceTypeImpl
+ */
+ protected class VM playedBy VirtualMachineImpl {
+ @SuppressWarnings("decapsulation")
+ ValueCache getCachedReftypes() -> get ValueCache fCachedReftypes;
+
+ protected void removeTypeFromCache(String typeName) {
+ List<JdwpReferenceTypeID> found = new ArrayList<>();
+ ValueCache cache = getCachedReftypes();
+ for (Object value : cache.values()) {
+ if (value instanceof ReferenceTypeImpl) {
+ ReferenceTypeImpl refType = (ReferenceTypeImpl) value;
+ if (refType.name().equals(typeName))
+ found.add(refType.getRefTypeID());
+ }
+ }
+ /* alternative to above loop (but involves a JDWP request:
+ List<ReferenceType> classes = target.jdiClassesByName(name);
+ */
+ for (JdwpReferenceTypeID id : found) {
+ cache.remove(id);
+ }
+ }
+ }
+
+ private void updateBreakpoints(IDebugTarget debugTarget, String className) {
+ // cf. JavaHotCodeReplaceManager.redefineTypesJDK() -> target.reinstallBreakpointsIn()
+ IBreakpointManager breakpointManager = DebugPlugin.getDefault().getBreakpointManager();
+ IBreakpoint[] breakpoints = breakpointManager.getBreakpoints(JDIDebugModel.getPluginIdentifier());
+ for (IBreakpoint breakpoint : breakpoints) {
+ if (breakpoint instanceof IJavaLineBreakpoint) {
+ IJavaLineBreakpoint lineBreakpoint = (IJavaLineBreakpoint) breakpoint;
+ try {
+ if (lineBreakpoint.getTypeName().equals(className)) {
+ debugTarget.breakpointRemoved(lineBreakpoint, null);
+ debugTarget.breakpointAdded(lineBreakpoint);
+ }
+ } catch (CoreException e) {
+ OTDebugAdaptorPlugin.logException("Failed to update breakpoint", e);
+ }
+ }
+ }
+ }
+
+ // --- empty implementation of unused hooks: ---
+ @Override
+ public int installingBreakpoint(IJavaDebugTarget target, IJavaBreakpoint breakpoint, IJavaType type) {
+ return IJavaBreakpointListener.DONT_CARE;
+ }
+
+ @Override public void addingBreakpoint(IJavaDebugTarget target, IJavaBreakpoint breakpoint) { }
+ @Override public void breakpointInstalled(IJavaDebugTarget target, IJavaBreakpoint breakpoint) { }
+ @Override public void breakpointRemoved(IJavaDebugTarget target, IJavaBreakpoint breakpoint) { }
+ @Override public void breakpointHasRuntimeException(IJavaLineBreakpoint breakpoint, DebugException exception) { }
+ @Override public void breakpointHasCompilationErrors(IJavaLineBreakpoint breakpoint, Message[] errors) { }
+}
diff --git a/plugins/org.eclipse.objectteams.otdt.debug.adaptor/src/org/eclipse/objectteams/otdt/internal/debug/adaptor/launching/JDTLaunchingAdaptor.java b/plugins/org.eclipse.objectteams.otdt.debug.adaptor/src/org/eclipse/objectteams/otdt/internal/debug/adaptor/launching/JDTLaunchingAdaptor.java
index 29edddf..1172980 100644
--- a/plugins/org.eclipse.objectteams.otdt.debug.adaptor/src/org/eclipse/objectteams/otdt/internal/debug/adaptor/launching/JDTLaunchingAdaptor.java
+++ b/plugins/org.eclipse.objectteams.otdt.debug.adaptor/src/org/eclipse/objectteams/otdt/internal/debug/adaptor/launching/JDTLaunchingAdaptor.java
@@ -34,6 +34,7 @@
import org.eclipse.objectteams.otdt.debug.OTDebugPlugin;
import org.eclipse.objectteams.otdt.debug.OTVMRunnerAdaptor;
import org.eclipse.objectteams.otdt.debug.TeamBreakpointInstaller;
+import org.eclipse.objectteams.otdt.internal.debug.adaptor.dynamic.RedefineClassesBPListener;
import org.eclipse.pde.internal.ui.IPDEUIConstants;
import base org.eclipse.jdt.launching.AbstractJavaLaunchConfigurationDelegate;
@@ -147,11 +148,14 @@
this.fAdaptor = null;
return;
}
- this.fAdaptor = new OTVMRunnerAdaptor(getJavaProject(config));
+ IJavaProject javaProject = getJavaProject(config);
+ this.fAdaptor = new OTVMRunnerAdaptor(javaProject);
this.fAdaptor.setAdaptationArgs(config, mode, launch);
// install OT-breakpoints
- if (ILaunchManager.DEBUG_MODE.equals(mode))
- TeamBreakpointInstaller.installTeamBreakpoints(getJavaProject(config));
+ if (ILaunchManager.DEBUG_MODE.equals(mode)) {
+ TeamBreakpointInstaller.installTeamBreakpoints(javaProject,
+ RedefineClassesBPListener.get(this.fAdaptor.getWeavingScheme()));
+ }
}
// --- VM Arguments: ---
diff --git a/plugins/org.eclipse.objectteams.otdt.debug.adaptor/src/org/eclipse/objectteams/otdt/internal/debug/adaptor/launching/PDELaunchingAdaptor.java b/plugins/org.eclipse.objectteams.otdt.debug.adaptor/src/org/eclipse/objectteams/otdt/internal/debug/adaptor/launching/PDELaunchingAdaptor.java
index e008838..0c35cbd 100644
--- a/plugins/org.eclipse.objectteams.otdt.debug.adaptor/src/org/eclipse/objectteams/otdt/internal/debug/adaptor/launching/PDELaunchingAdaptor.java
+++ b/plugins/org.eclipse.objectteams.otdt.debug.adaptor/src/org/eclipse/objectteams/otdt/internal/debug/adaptor/launching/PDELaunchingAdaptor.java
@@ -25,6 +25,7 @@
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.internal.core.util.Util;
import org.eclipse.objectteams.otdt.core.ext.OTREContainer;
@@ -33,6 +34,7 @@
import org.eclipse.objectteams.otdt.debug.TeamBreakpointInstaller;
import org.eclipse.objectteams.otdt.internal.debug.adaptor.DebugMessages;
import org.eclipse.objectteams.otdt.internal.debug.adaptor.OTDebugAdaptorPlugin;
+import org.eclipse.objectteams.otdt.internal.debug.adaptor.dynamic.RedefineClassesBPListener;
import org.eclipse.objectteams.otequinox.TransformerPlugin;
import org.eclipse.osgi.util.NLS;
import org.eclipse.pde.core.plugin.IPluginModelBase;
@@ -125,13 +127,15 @@
* Installs breakpoints needed for the TeamMonitor into org.objectteams.Team.
* Needs to find a project with OTJavaNature to do this.
*/
- static void installOOTBreakpoints(IProject[] projects) throws CoreException
+ static void installOOTBreakpoints(IProject[] projects, String weavingMode) throws CoreException
{
if (projects != null)
for (IProject project : projects)
// find org.objectteams.Team in any OT/J Project:
if (project.getNature(JavaCore.OTJ_NATURE_ID) != null) {
- TeamBreakpointInstaller.installTeamBreakpoints(JavaCore.create(project));
+ IJavaProject javaProject = JavaCore.create(project);
+ TeamBreakpointInstaller.installTeamBreakpoints(javaProject,
+ RedefineClassesBPListener.get(WeavingScheme.valueOf(weavingMode)));
return; // good, done.
}
logException(null, Status.WARNING, DebugMessages.OTLaunching_no_OTJ_project_found);
@@ -166,9 +170,9 @@
if (isOTLaunch(configuration))
try {
IProject[] projects = getProjectsForProblemSearch(configuration, mode);
- if (ILaunchManager.DEBUG_MODE.equals(mode))
- PDELaunchingAdaptor.installOOTBreakpoints(projects);
determineWeavingMode(projects);
+ if (ILaunchManager.DEBUG_MODE.equals(mode))
+ PDELaunchingAdaptor.installOOTBreakpoints(projects, weavingMode);
} catch (DebugException dex) {
throw dex;
} catch (CoreException ex) {
diff --git a/plugins/org.eclipse.objectteams.otdt.debug/src/org/eclipse/objectteams/otdt/debug/OTVMRunnerAdaptor.java b/plugins/org.eclipse.objectteams.otdt.debug/src/org/eclipse/objectteams/otdt/debug/OTVMRunnerAdaptor.java
index a7c53f8..a6c9c2b 100644
--- a/plugins/org.eclipse.objectteams.otdt.debug/src/org/eclipse/objectteams/otdt/debug/OTVMRunnerAdaptor.java
+++ b/plugins/org.eclipse.objectteams.otdt.debug/src/org/eclipse/objectteams/otdt/debug/OTVMRunnerAdaptor.java
@@ -66,6 +66,10 @@
this.weavingScheme = OTJavaNature.getWeavingScheme(javaProject);
}
+ public WeavingScheme getWeavingScheme() {
+ return this.weavingScheme;
+ }
+
/**
* Store the original arguments as passed to {@link ILaunchConfigurationDelegate#launch(ILaunchConfiguration, String, ILaunch, org.eclipse.core.runtime.IProgressMonitor)}
* @param configuration see first argument of {@link ILaunchConfigurationDelegate#launch(ILaunchConfiguration, String, ILaunch, org.eclipse.core.runtime.IProgressMonitor) launch(..)}
diff --git a/plugins/org.eclipse.objectteams.otdt.debug/src/org/eclipse/objectteams/otdt/debug/TeamBreakpointInstaller.java b/plugins/org.eclipse.objectteams.otdt.debug/src/org/eclipse/objectteams/otdt/debug/TeamBreakpointInstaller.java
index 923c052..d46b1d4 100644
--- a/plugins/org.eclipse.objectteams.otdt.debug/src/org/eclipse/objectteams/otdt/debug/TeamBreakpointInstaller.java
+++ b/plugins/org.eclipse.objectteams.otdt.debug/src/org/eclipse/objectteams/otdt/debug/TeamBreakpointInstaller.java
@@ -32,9 +32,12 @@
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.debug.core.IJavaBreakpointListener;
import org.eclipse.jdt.debug.core.IJavaDebugTarget;
-import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
+import org.eclipse.jdt.debug.core.JDIDebugModel;
+import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
+import org.eclipse.objectteams.otdt.debug.internal.breakpoints.ClassRedefinitionBreakpoint;
import org.eclipse.objectteams.otdt.debug.internal.breakpoints.OOTBreakpoints;
/**
@@ -48,15 +51,22 @@
*/
public class TeamBreakpointInstaller
{
- private static Hashtable<String, IBreakpoint> OT_BREAKPOINTS = new Hashtable<String, IBreakpoint>(5);
+ private static Hashtable<String, IBreakpoint> OT_BREAKPOINTS = new Hashtable<String, IBreakpoint>(5);
+
+ /** Optional listener for Instrumentation.redefineClasses (when running under OTDRE). */
+ private static IJavaBreakpointListener dynListener;
/**
* Request breakpoints to be installed once a new launch fires.
* @param project used for lookup of org.objectteams.Team, i.e., this class must be in the projects classpath.
* @throws CoreException various reasons, like could not find class org.objectteams.Team or could not create a breakpoint.
*/
- public static void installTeamBreakpoints(IJavaProject project) throws CoreException
+ public static void installTeamBreakpoints(IJavaProject project, /*Nullable*/IJavaBreakpointListener dynListener)
+ throws CoreException
{
+ TeamBreakpointInstaller.dynListener = dynListener;
+ if (dynListener != null)
+ JDIDebugModel.addJavaBreakpointListener(dynListener);
DebugPlugin.getDefault().addDebugEventListener(new IDebugEventSetListener() {
// since we want to avoid using the breakpoint manager (thus hiding synthetic breakpoints from the UI),
// we have to track creation of the debug target in order to manually install our breakpoints into the target:
@@ -82,7 +92,10 @@
}
});
try
- {
+ {
+ if (dynListener != null && !OT_BREAKPOINTS.containsKey(ClassRedefinitionBreakpoint.BREAKPOINT_REDEFINE_CLASSES))
+ OT_BREAKPOINTS.put(ClassRedefinitionBreakpoint.BREAKPOINT_REDEFINE_CLASSES,
+ ClassRedefinitionBreakpoint.createRedefineClassesBreakpoint(project));
IType oot = project.findType(new String(IOTConstants.STR_ORG_OBJECTTEAMS_TEAM));
if (oot != null)
{
@@ -115,7 +128,11 @@
/** Unregister any previously installed breakpoints, so that the next launch will be without. */
public static void uninstallTeamBreakpoints() throws CoreException
- {
+ {
+ if (dynListener != null) {
+ JDIDebugModel.removeJavaBreakpointListener(dynListener);
+ dynListener = null;
+ }
OT_BREAKPOINTS.clear();
}
}
diff --git a/plugins/org.eclipse.objectteams.otdt.debug/src/org/eclipse/objectteams/otdt/debug/internal/breakpoints/ClassRedefinitionBreakpoint.java b/plugins/org.eclipse.objectteams.otdt.debug/src/org/eclipse/objectteams/otdt/debug/internal/breakpoints/ClassRedefinitionBreakpoint.java
new file mode 100644
index 0000000..78dfc60
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt.debug/src/org/eclipse/objectteams/otdt/debug/internal/breakpoints/ClassRedefinitionBreakpoint.java
@@ -0,0 +1,66 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ *
+ * Copyright 2017 GK Software AG
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ *
+ * Contributors:
+ * Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otdt.debug.internal.breakpoints;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.debug.core.IJavaBreakpoint;
+import org.eclipse.objectteams.otdt.debug.OTDebugPlugin;
+
+public class ClassRedefinitionBreakpoint {
+
+ public static final String BREAKPOINT_REDEFINE_CLASSES = OTDebugPlugin.PLUGIN_ID + "InstrumentationBreakpoint.redefineClasses"; //$NON-NLS-1$
+
+ static final String OT_SYNTHETIC_BREAKPOINT = OTDebugPlugin.PLUGIN_ID + "InstrumentationBreakpoint"; //$NON-NLS-1$
+
+ static final String INSTRUMENTATION_IMPL = "sun.instrument.InstrumentationImpl"; //$NON-NLS-1$
+ static final String REDEFINE_CLASSSES = "redefineClasses"; //$NON-NLS-1$
+ static final String REDEFINE_CLASSSES_SIGNATURE = "([Ljava/lang/instrument/ClassDefinition;)V"; //$NON-NLS-1$
+
+ public static IJavaBreakpoint createRedefineClassesBreakpoint(IJavaProject project) throws CoreException {
+
+ try {
+ IType instrumentation = project.findType(INSTRUMENTATION_IMPL);
+ if (instrumentation != null) {
+ Map<String, Object> attributes = getBreakpointAttributes();
+ attributes.put(BREAKPOINT_REDEFINE_CLASSES, Boolean.TRUE);
+ return OOTBreakpoints.createMethodBreakpoint(instrumentation, REDEFINE_CLASSSES, REDEFINE_CLASSSES_SIGNATURE, false, -1, attributes);
+ }
+ }
+ catch (JavaModelException ex) {
+ throw new CoreException(new Status(IStatus.WARNING, OTDebugPlugin.PLUGIN_ID, IStatus.OK, "Cannot set breakpoints for tracking class redefinition", ex)); //$NON-NLS-1$
+ }
+ return null;
+ }
+
+ public static final boolean isRedefineClassesBreakpoint(IBreakpoint breakpoint) throws CoreException {
+ return breakpoint.getMarker().getAttribute(BREAKPOINT_REDEFINE_CLASSES) != null;
+ }
+
+ private static Map<String, Object> getBreakpointAttributes() {
+ Map<String, Object> attrs = new HashMap<>();
+ attrs.put(OT_SYNTHETIC_BREAKPOINT, Boolean.TRUE);
+ return attrs;
+ }
+}
diff --git a/plugins/org.eclipse.objectteams.otdt.debug/src/org/eclipse/objectteams/otdt/debug/internal/breakpoints/OOTBreakpoints.java b/plugins/org.eclipse.objectteams.otdt.debug/src/org/eclipse/objectteams/otdt/debug/internal/breakpoints/OOTBreakpoints.java
index 4c7fb38..e867478 100644
--- a/plugins/org.eclipse.objectteams.otdt.debug/src/org/eclipse/objectteams/otdt/debug/internal/breakpoints/OOTBreakpoints.java
+++ b/plugins/org.eclipse.objectteams.otdt.debug/src/org/eclipse/objectteams/otdt/debug/internal/breakpoints/OOTBreakpoints.java
@@ -56,6 +56,8 @@
public static final String ATTR_OT_BREAKPOINT_IMPLICIT_ACT = OTDebugPlugin.PLUGIN_ID + ".TeamBreakpoint.ImplicitActivateMethod";
public static final String ATTR_OT_BREAKPOINT_IMPLICIT_DEACT = OTDebugPlugin.PLUGIN_ID + ".TeamBreakpoint.ImplicitDeactivateMethod";
+ private static final String FINALIZE = "finalize";
+ private static final String EMPTY_SIGNATURE = "()V";
//associated with "public Team() {}"
public static int getTeamConstructorLineNumber()
@@ -112,7 +114,8 @@
{
Map<String, Boolean> finalizeMethodAttributes = getBreakpointAttributes();
finalizeMethodAttributes.put(OOTBreakpoints.ATTR_OT_BREAKPOINT_FINALIZE, Boolean.TRUE);
- return createOOTMethodBreakpoint(oot, getFinalizeMethodLineNumber(), finalizeMethodAttributes);
+ return createMethodBreakpoint(oot, FINALIZE, EMPTY_SIGNATURE, true,
+ getFinalizeMethodLineNumber(), finalizeMethodAttributes);
}
public static IBreakpoint createOOTActivateBreakpoint(IType oot)throws CoreException
@@ -158,16 +161,17 @@
return breakpoint;
}
- public static IBreakpoint createOOTMethodBreakpoint(IType oot, int linenumber, Map attributes)
+ public static IJavaBreakpoint createMethodBreakpoint(IType type, String selector, String signature,
+ boolean entry, int linenumber, Map attributes)
throws CoreException
{
- IResource teamResource = oot.getJavaProject().getResource();
+ IResource resource = type.getJavaProject().getResource();
IJavaBreakpoint breakpoint = JDIDebugModel.createMethodBreakpoint(
- teamResource,
- oot.getFullyQualifiedName(),
- "finalize",
- "()V",
- true /*entry*/, false /*exit*/, false /*native*/,
+ resource,
+ type.getFullyQualifiedName(),
+ selector,
+ signature,
+ entry, !entry, false /*native*/,
linenumber,
-1, -1, 0,
false /*register*/,
diff --git a/plugins/org.eclipse.objectteams.otdt.pde.ui/src/org/eclipse/objectteams/otdt/internal/pde/ui/OTEquinoxCommonLaunching.java b/plugins/org.eclipse.objectteams.otdt.pde.ui/src/org/eclipse/objectteams/otdt/internal/pde/ui/OTEquinoxCommonLaunching.java
deleted file mode 100644
index 742981b..0000000
--- a/plugins/org.eclipse.objectteams.otdt.pde.ui/src/org/eclipse/objectteams/otdt/internal/pde/ui/OTEquinoxCommonLaunching.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/**********************************************************************
- * This file is part of "Object Teams Development Tooling"-Software
- *
- * Copyright 2004, 2006 Fraunhofer Gesellschaft, Munich, Germany,
- * for its Fraunhofer Institute for Computer Architecture and Software
- * Technology (FIRST), Berlin, Germany and Technical University Berlin,
- * Germany.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- * $Id: OTEquinoxCommonLaunching.java 23470 2010-02-05 19:13:24Z stephan $
- *
- * Please visit http://www.eclipse.org/objectteams for updates and contact.
- *
- * Contributors:
- * Fraunhofer FIRST - Initial API and implementation
- * Technical University Berlin - Initial API and implementation
- **********************************************************************/
-package org.eclipse.objectteams.otdt.internal.pde.ui;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.debug.core.ILaunchManager;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.objectteams.otdt.debug.OTDebugPlugin;
-import org.eclipse.objectteams.otdt.debug.TeamBreakpointInstaller;
-
-/**
- * Shared implementation of OTEclipseApplicationLaunchConfiguration and OTEquinoxLaunchConfiguration
- *
- * @author stephan
- * @since OTDT 1.1.3
- */
-public class OTEquinoxCommonLaunching
-{
- static final String HOOK_CONFIGURATOR = "-Dosgi.hook.configurators.include=org.eclipse.objectteams.otequinox.hook.HookConfigurator";//$NON-NLS-1$
- static final String CLASSLOADER_LOCKING = "-Dosgi.classloader.lock=classname"; //$NON-NLS-1$
- static final String REPOSITORY_WORKAROUND = "-Dot.equinox"; //$NON-NLS-1$ // this causes the WORKAROUND_REPOSITORY flag being set to true in OTRE.
- static final String OT_DEBUG_VMARG = "-Dot.debug"; //$NON-NLS-1$
- static final String[] OT_VM_ARGS = { HOOK_CONFIGURATOR, CLASSLOADER_LOCKING, REPOSITORY_WORKAROUND };
- static final String[] OT_VM_DEBUG_ARGS = { HOOK_CONFIGURATOR, CLASSLOADER_LOCKING, REPOSITORY_WORKAROUND, OT_DEBUG_VMARG };
-
- static String[] extendVMArguments(String[] args, String mode) {
- String[] otArgs = OT_VM_ARGS;
- if (mode != null && mode.equals(ILaunchManager.DEBUG_MODE))
- otArgs = OT_VM_DEBUG_ARGS;
-
- if (args == null || args.length == 0)
- return otArgs;
-
- String[] combinedArgs = new String[args.length + otArgs.length];
- System.arraycopy(args, 0, combinedArgs, 0, args.length);
- System.arraycopy(otArgs, 0, combinedArgs, args.length, otArgs.length);
- return combinedArgs;
- }
-
- static void installOOTBreakpoints(IProject[] projects)
- throws CoreException
- {
- IJavaProject jp = null;
- if (projects != null) {
- for (IProject project : projects) {
- // find org.objectteams.Team in any OT/J Project:
- if (project.getNature(JavaCore.OTJ_NATURE_ID) != null) {
- jp = JavaCore.create(project);
- TeamBreakpointInstaller.installTeamBreakpoints(jp);
- break;
- }
- }
- }
- if (jp == null)
- OTDebugPlugin.getDefault().getLog().log(
- new Status(Status.WARNING,
- OTPDEUIPlugin.PLUGIN_ID,
- 0,
- OTPDEUIMessages.NoOTJPluginProject,
- null));
- }
-}