Skip to content

Commit

Permalink
Enables Expression Evaluator for remote debugging
Browse files Browse the repository at this point in the history
The project classpath needs to be set for Debugger machine as well.
In other case it is not possible to evaluate instances on Debugger
side and send the output to Debugee machine.

Fixes #1002439
  • Loading branch information
wpopielarski committed Oct 12, 2015
1 parent ce8edc0 commit a04f664
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 17 deletions.
10 changes: 10 additions & 0 deletions org.scala-ide.sdt.debug/plugin.xml
Expand Up @@ -64,6 +64,16 @@
sourcePathComputerId="org.eclipse.jdt.launching.sourceLookup.javaSourcePathComputer"
type="org.eclipse.jdt.junit.launchconfig">
</launchDelegate>
<launchDelegate
delegate="org.scalaide.debug.internal.launching.ScalaRemoteApplicationLaunchConfigurationDelegate"
delegateDescription="The Scala Remote Launcher supports debugging Scala applications"
id="scala.remote.new"
modes="debug"
name="Scala Remote"
sourceLocatorId="org.eclipse.jdt.launching.sourceLocator.JavaSourceLookupDirector"
sourcePathComputerId="org.eclipse.jdt.launching.sourceLookup.javaSourcePathComputer"
type="org.eclipse.jdt.launching.remoteJavaApplication">
</launchDelegate>
</extension>
<extension
point="org.eclipse.ui.preferencePages">
Expand Down
@@ -0,0 +1,26 @@
package org.scalaide.debug.internal.launching

import java.util.{ Map => JMap }

import org.eclipse.core.runtime.IProgressMonitor
import org.eclipse.debug.core.ILaunch
import org.eclipse.debug.core.ILaunchConfiguration
import org.eclipse.jdt.internal.launching.JavaRemoteApplicationLaunchConfigurationDelegate
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants
import org.scalaide.core.internal.launching.ClasspathGetterForLaunchDelegate

object ScalaRemoteApplicationLaunchConfigurationDelegate {
val DebugeeProjectClasspath = "DebugeeProjectClasspath"
val DebugeeProjectClasspathSeparator = ","
}

class ScalaRemoteApplicationLaunchConfigurationDelegate extends JavaRemoteApplicationLaunchConfigurationDelegate
with ClasspathGetterForLaunchDelegate {
import ScalaRemoteApplicationLaunchConfigurationDelegate._

override def launch(configuration: ILaunchConfiguration, mode: String, launch: ILaunch, monitor: IProgressMonitor): Unit = {
val argMap = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_CONNECT_MAP, null.asInstanceOf[JMap[String, String]])
argMap.put(DebugeeProjectClasspath, getClasspath(configuration).mkString(DebugeeProjectClasspathSeparator))
super.launch(configuration, mode, launch, monitor)
}
}
Expand Up @@ -16,6 +16,7 @@ import org.scalaide.debug.internal.model.ScalaDebugTarget
import java.io.IOException
import com.sun.jdi.connect.TransportTimeoutException
import org.eclipse.jdi.TimeoutException
import org.eclipse.debug.core.ILaunchConfiguration

/**
* Attach connector creating a Scala debug session.
Expand All @@ -27,7 +28,7 @@ class SocketAttachConnectorScala extends IVMConnector with SocketConnectorScala
override def connector(): AttachingConnector = {
import scala.collection.JavaConverters._
Bootstrap.virtualMachineManager().attachingConnectors().asScala.find(_.name() == SocketAttachName).getOrElse(
throw ScalaDebugPlugin.wrapInCoreException("Unable to find JDI AttachingConnector", null))
throw ScalaDebugPlugin.wrapInCoreException("Unable to find JDI AttachingConnector", null))
}

// from org.eclipse.jdt.launching.IVMConnector
Expand All @@ -42,13 +43,14 @@ class SocketAttachConnectorScala extends IVMConnector with SocketConnectorScala
override def getName(): String = "Scala debugger (Socket Attach)"

override def connect(params: JMap[String, String], monitor: IProgressMonitor, launch: ILaunch): Unit = {

import scala.collection.JavaConverters._
val arguments = generateArguments(params)

try {
// connect and create the debug session
val virtualMachine = connector.attach(arguments)
val target = ScalaDebugTarget(virtualMachine, launch, null, allowDisconnect = true, allowTerminate = allowTerminate(launch))
val target = ScalaDebugTarget(virtualMachine, launch, null, allowDisconnect = true,
allowTerminate = allowTerminate(launch), extractProjectClasspath(params.asScala.toMap))
target.attached() // tell the debug target to initialize
} catch {
case e: TimeoutException =>
Expand All @@ -57,7 +59,4 @@ class SocketAttachConnectorScala extends IVMConnector with SocketConnectorScala
throw ScalaDebugPlugin.wrapInCoreException("Unable to connect to the remote VM", e)
}
}

// ------------

}
}
Expand Up @@ -82,5 +82,8 @@ trait SocketConnectorScala extends IVMConnector {
arguments
}


}
def extractProjectClasspath(params: Map[String, String]): Option[Seq[String]] = {
import ScalaRemoteApplicationLaunchConfigurationDelegate._
params.get(DebugeeProjectClasspath).map { _.split(DebugeeProjectClasspathSeparator).toSeq }
}
}
Expand Up @@ -3,8 +3,9 @@ package org.scalaide.debug.internal.launching
import java.io.IOException
import java.util.{ List => JList }
import java.util.{ Map => JMap }
import org.scalaide.debug.internal.ScalaDebugPlugin
import org.scalaide.debug.internal.model.ScalaDebugTarget

import scala.collection.JavaConverters

import org.eclipse.core.runtime.IProgressMonitor
import org.eclipse.core.runtime.IStatus
import org.eclipse.core.runtime.Status
Expand All @@ -15,10 +16,13 @@ import org.eclipse.debug.core.ILaunch
import org.eclipse.debug.core.model.IProcess
import org.eclipse.debug.core.model.IStreamsProxy
import org.eclipse.jdi.Bootstrap
import org.eclipse.jdt.launching.IVMConnector
import org.scalaide.debug.internal.ScalaDebugPlugin
import org.scalaide.debug.internal.model.ScalaDebugTarget

import com.sun.jdi.connect.Connector
import com.sun.jdi.connect.ListeningConnector
import com.sun.jdi.connect.TransportTimeoutException
import org.eclipse.jdt.launching.IVMConnector

/**
* Listen connector creating a Scala debug session.
Expand All @@ -30,7 +34,7 @@ class SocketListenConnectorScala extends IVMConnector with SocketConnectorScala
override def connector(): ListeningConnector = {
import scala.collection.JavaConverters._
Bootstrap.virtualMachineManager().listeningConnectors().asScala.find(_.name() == SocketListenName).getOrElse(
throw ScalaDebugPlugin.wrapInCoreException("Unable to find JDI ListeningConnector", null))
throw ScalaDebugPlugin.wrapInCoreException("Unable to find JDI ListeningConnector", null))
}

// from org.eclipse.jdt.launching.IVMConnector
Expand Down Expand Up @@ -60,7 +64,7 @@ class SocketListenConnectorScala extends IVMConnector with SocketConnectorScala
val process = ListenForConnectionProcess(launch, port)

// Start a job to wait for VM connections
val job = new ListenForConnectionJob(launch, process, connector(), arguments);
val job = new ListenForConnectionJob(launch, process, connector(), arguments, extractProjectClasspath(params.asScala.toMap))
job.setPriority(Job.SHORT)

job.schedule()
Expand Down Expand Up @@ -170,7 +174,8 @@ class ListenForConnectionProcess private (launch: ILaunch, port: Int) extends IP
* Job waiting for a VM to connect.
* If it is successful, it creates a debug target, otherwise an error message is displayed in the debug view.
*/
class ListenForConnectionJob(launch: ILaunch, process: ListenForConnectionProcess, connector: ListeningConnector, arguments: JMap[String, Connector.Argument]) extends Job("Scala debugger remote connection listener") {
class ListenForConnectionJob(launch: ILaunch, process: ListenForConnectionProcess, connector: ListeningConnector, arguments: JMap[String, Connector.Argument], projectClasspath: Option[Seq[String]])
extends Job("Scala debugger remote connection listener") {
import SocketConnectorScala._

// -- from org.eclipse.core.runtime.jobs.Job
Expand All @@ -181,7 +186,7 @@ class ListenForConnectionJob(launch: ILaunch, process: ListenForConnectionProces
val virtualMachine = connector.accept(arguments)
connector.stopListening(arguments)

ScalaDebugTarget(virtualMachine, launch, null, true, allowTerminate(launch))
ScalaDebugTarget(virtualMachine, launch, null, true, allowTerminate(launch), projectClasspath)

connectionSuccesful()
Status.OK_STATUS
Expand All @@ -208,4 +213,4 @@ class ListenForConnectionJob(launch: ILaunch, process: ListenForConnectionProces
process.failed(message)
}

}
}

0 comments on commit a04f664

Please sign in to comment.