Skip to content

Commit

Permalink
Use custom debug model
Browse files Browse the repository at this point in the history
Signed-off-by: Adam Wisniewski <[email protected]>
  • Loading branch information
Adam Wisniewski authored and Adam Wisniewski committed Oct 3, 2023
1 parent fe956b1 commit e407c69
Show file tree
Hide file tree
Showing 15 changed files with 646 additions and 109 deletions.
11 changes: 10 additions & 1 deletion bundles/io.openliberty.tools.eclipse.ui/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,21 @@ Bundle-SymbolicName: io.openliberty.tools.eclipse.ui;singleton:=true
Bundle-Version: 23.0.9.qualifier
Bundle-Activator: io.openliberty.tools.eclipse.LibertyDevPlugin
Export-Package: io.openliberty.tools.eclipse;x-friends:="io.openliberty.tools.eclipse.tests",
io.openliberty.tools.eclipse.debug;x-friends:="io.openliberty.tools.eclipse.tests",
io.openliberty.tools.eclipse.ui.dashboard;x-friends:="io.openliberty.tools.eclipse.tests",
io.openliberty.tools.eclipse.ui.launch;x-friends:="io.openliberty.tools.eclipse.tests",
io.openliberty.tools.eclipse.ui.launch.shortcuts;x-friends:="io.openliberty.tools.eclipse.tests",
io.openliberty.tools.eclipse.ui.preferences;x-friends:="io.openliberty.tools.eclipse.tests"
Require-Bundle: org.eclipse.ui,
org.eclipse.equinox.preferences
org.eclipse.equinox.preferences,
org.eclipse.jdt.debug,
org.eclipse.debug.ui,
org.eclipse.jdt.launching,
org.eclipse.swt,
org.eclipse.wst.server.core,
org.eclipse.m2e.core,
org.eclipse.m2e.maven.runtime,
org.eclipse.buildship.core
Bundle-RequiredExecutionEnvironment: JavaSE-17
Automatic-Module-Name: io.openliberty.tools.eclipse.ui
Bundle-ActivationPolicy: lazy
Expand Down
19 changes: 18 additions & 1 deletion bundles/io.openliberty.tools.eclipse.ui/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -373,14 +373,31 @@
</command>
</menuContribution>
</extension>

<extension point="org.eclipse.debug.core.sourceLocators">
<sourceLocator
name="Liberty Source Lookup Director"
class="io.openliberty.tools.eclipse.debug.LibertySourceLookupDirector"
id="io.openliberty.tools.eclipse.debug.libertySourceLookupDirector">
</sourceLocator>
</extension>

<extension point="org.eclipse.debug.core.sourcePathComputers">
<sourcePathComputer
class="io.openliberty.tools.eclipse.debug.LibertySourcePathComputer"
id="io.openliberty.tools.eclipse.debug.libertySourcePathComputer">
</sourcePathComputer>
</extension>

<!-- Launch configuration -->
<extension point="org.eclipse.debug.core.launchConfigurationTypes">
<launchConfigurationType
name="Liberty"
delegate="io.openliberty.tools.eclipse.ui.launch.LaunchConfigurationDelegateLauncher"
modes="run, debug"
id="io.openliberty.tools.eclipse.launch.type">
id="io.openliberty.tools.eclipse.launch.type"
sourceLocatorId="io.openliberty.tools.eclipse.debug.libertySourceLookupDirector"
sourcePathComputerId="io.openliberty.tools.eclipse.debug.libertySourcePathComputer">
</launchConfigurationType>
</extension>
<extension point="org.eclipse.debug.ui.launchConfigurationTypeImages">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jface.viewers.ISelection;
Expand All @@ -46,6 +47,7 @@

import io.openliberty.tools.eclipse.CommandBuilder.CommandNotFoundException;
import io.openliberty.tools.eclipse.Project.BuildType;
import io.openliberty.tools.eclipse.debug.DebugModeHandler;
import io.openliberty.tools.eclipse.logging.Logger;
import io.openliberty.tools.eclipse.logging.Trace;
import io.openliberty.tools.eclipse.messages.Messages;
Expand Down Expand Up @@ -151,7 +153,7 @@ public static DevModeOperations getInstance() {
* @param javaHomePath The configuration java installation home to be set in the terminal running dev mode.
* @param mode The configuration mode.
*/
public void start(IProject iProject, String parms, String javaHomePath, String mode) {
public void start(IProject iProject, String parms, String javaHomePath, ILaunch launch, String mode) {

if (Trace.isEnabled()) {
Trace.getTracer().traceEntry(Trace.TRACE_TOOLS, new Object[] { iProject, parms, javaHomePath, mode });
Expand Down Expand Up @@ -232,13 +234,13 @@ public void start(IProject iProject, String parms, String javaHomePath, String m
+ "does not appear to be a Maven or Gradle built project.");
}

// Start a terminal and run the application in dev mode.
startDevMode(cmd, projectName, projectPath, javaHomePath);

// If there is a debugPort, start the job to attach the debugger to the Liberty server JVM.
if (debugPort != null) {
debugModeHandler.startDebugAttacher(project, debugPort);
debugModeHandler.startDebugAttacher(project, launch, debugPort);
}

// Start a terminal and run the application in dev mode.
startDevMode(cmd, projectName, projectPath, javaHomePath);
} catch (CommandNotFoundException e) {
String msg = "Maven or Gradle command not found for project " + projectName;
if (Trace.isEnabled()) {
Expand Down Expand Up @@ -266,7 +268,7 @@ public void start(IProject iProject, String parms, String javaHomePath, String m
* @param javaHomePath The configuration java installation home to be set in the terminal running dev mode.
* @param mode The configuration mode.
*/
public void startInContainer(IProject iProject, String parms, String javaHomePath, String mode) {
public void startInContainer(IProject iProject, String parms, String javaHomePath, ILaunch launch, String mode) {

if (Trace.isEnabled()) {
Trace.getTracer().traceEntry(Trace.TRACE_TOOLS, new Object[] { iProject, parms, javaHomePath, mode });
Expand Down Expand Up @@ -349,7 +351,7 @@ public void startInContainer(IProject iProject, String parms, String javaHomePat

// If there is a debugPort, start the job to attach the debugger to the Liberty server JVM.
if (debugPort != null) {
debugModeHandler.startDebugAttacher(project, debugPort);
debugModeHandler.startDebugAttacher(project, launch, debugPort);
}

// Start a terminal and run the application in dev mode.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
* Contributors:
* IBM Corporation - initial implementation
*******************************************************************************/
package io.openliberty.tools.eclipse;
package io.openliberty.tools.eclipse.debug;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.ConnectException;
import java.net.ServerSocket;
import java.net.Socket;
Expand All @@ -31,6 +32,7 @@
import java.util.stream.Stream;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
Expand All @@ -43,7 +45,11 @@
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.jdi.Bootstrap;
import org.eclipse.jdi.TimeoutException;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.debug.core.JDIDebugModel;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Display;
Expand All @@ -53,6 +59,15 @@
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;

import com.sun.jdi.VirtualMachine;
import com.sun.jdi.connect.AttachingConnector;
import com.sun.jdi.connect.Connector;
import com.sun.jdi.connect.Connector.Argument;
import com.sun.jdi.connect.IllegalConnectorArgumentsException;

import io.openliberty.tools.eclipse.DevModeOperations;
import io.openliberty.tools.eclipse.LibertyDevPlugin;
import io.openliberty.tools.eclipse.Project;
import io.openliberty.tools.eclipse.Project.BuildType;
import io.openliberty.tools.eclipse.logging.Trace;
import io.openliberty.tools.eclipse.messages.Messages;
Expand Down Expand Up @@ -205,15 +220,108 @@ public String calculateDebugPort(Project project, String inputParms) throws Exce

}

public static AttachingConnector getAttachingConnector() {
List<?> connectors = Bootstrap.virtualMachineManager().attachingConnectors();
for (int i = 0; i < connectors.size(); i++) {
AttachingConnector c = (AttachingConnector) connectors.get(i);
if ("com.sun.jdi.SocketAttach".equals(c.name()))
return c;
}

return null;
}

/**
* Configure the connector properties.
*
* @param map argument map
* @param host the host name or IP address
* @param portNumber the port number
*/
public static void configureConnector(Map map, String host, int portNumber) {
Connector.StringArgument hostArg = (Connector.StringArgument) map.get("hostname");
hostArg.setValue(host);

Connector.IntegerArgument portArg = (Connector.IntegerArgument) map.get("port");
portArg.setValue(portNumber);

Connector.IntegerArgument timeoutArg = (Connector.IntegerArgument) map.get("timeout");
if (timeoutArg != null) {
// NOTE: We could get the timeout value form the platform preferences, but for now we will just hardcode a value
// int timeout = Platform.getPreferencesService().getInt(
// "org.eclipse.jdt.launching",
// JavaRuntime.PREF_CONNECT_TIMEOUT,
// JavaRuntime.DEF_CONNECT_TIMEOUT,
// null);
timeoutArg.setValue(60000);
}
}

public IDebugTarget createRemoteJDTDebugTarget(ILaunch launch, int remoteDebugPortNum, String hostName,
AttachingConnector connector, Map map) throws CoreException {
if (launch == null || hostName == null || hostName.length() == 0) {
return null;
}
VirtualMachine remoteVM = null;
Exception ex = null;
IDebugTarget debugTarget = null;
try {
remoteVM = attachJVM(hostName, remoteDebugPortNum, connector, map, 10000);
} catch (Exception e) {
ex = e;
}
if (remoteVM == null) {
throw new CoreException(
new Status(IStatus.ERROR, this.getClass(), IJavaLaunchConfigurationConstants.ERR_CONNECTION_FAILED, "", ex));
}
debugTarget = JDIDebugModel.newDebugTarget(launch, remoteVM, hostName + ":" + remoteDebugPortNum, null, false, true, true);
return debugTarget;
}

public VirtualMachine attachJVM(String hostName, int port, AttachingConnector connector, Map map, int timeout) {
VirtualMachine vm = null;
int timeOut = timeout;
try {
try {
vm = connector.attach(map);
} catch (IOException e) {
if (Trace.isEnabled()) {
Trace.getTracer().trace(Trace.TRACE_UI,
"Error occured while trying to connect to the remote virtual machine " + e.getMessage(), e);
}
} catch (TimeoutException e2) {
// do nothing
}

while (vm == null && timeOut > 0) {
try {
Thread.sleep(100);
} catch (Exception e) {
// do nothing
}
timeOut = timeOut - 100;
try {
vm = connector.attach(map);
} catch (IOException e) {
// do nothing
}
}
} catch (IllegalConnectorArgumentsException e) {
// Do nothing, return vm as null if it fails
}
return vm;
}

/**
* Starts the job that will attempt to connect the debugger with the server's JVM.
*
* @param project The project for which the debugger needs to be attached.
* @param launch The launch to which the debug target will be added.
* @param debugPort The debug port to use to attach the debugger to.
*
* @throws Exception
*/
public void startDebugAttacher(Project project, String debugPort) {
public void startDebugAttacher(Project project, ILaunch launch, String debugPort) {
String projectName = project.getIProject().getName();

Job job = new Job("Attaching Debugger to JVM...") {
Expand All @@ -229,7 +337,13 @@ protected IStatus run(IProgressMonitor monitor) {
return Status.CANCEL_STATUS;
}

createRemoteJavaAppDebugConfig(project, DEFAULT_ATTACH_HOST, portToConnect, monitor);
AttachingConnector connector = getAttachingConnector();
Map<String, Argument> map = connector.defaultArguments();
configureConnector(map, DEFAULT_ATTACH_HOST, Integer.parseInt(portToConnect));
IDebugTarget debugTarget = createRemoteJDTDebugTarget(launch, Integer.parseInt(portToConnect), DEFAULT_ATTACH_HOST,
connector, map);

launch.addDebugTarget(debugTarget);

} catch (Exception e) {
return new Status(IStatus.ERROR, LibertyDevPlugin.PLUGIN_ID, JOB_STATUS_DEBUGGER_CONN_ERROR,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.openliberty.tools.eclipse.debug;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupDirector;
import org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant;
import org.eclipse.jdt.launching.sourcelookup.containers.JavaSourceLookupParticipant;

public class LibertySourceLookupDirector extends AbstractSourceLookupDirector {

@Override
public void initializeParticipants() {
final List<ISourceLookupParticipant> participants = new ArrayList<>();

participants.add(new JavaSourceLookupParticipant());

addParticipants(participants.toArray(new ISourceLookupParticipant[participants.size()]));
}
}
Loading

0 comments on commit e407c69

Please sign in to comment.