Launching a process in debug mode...

Hey,

I'd like to launch a java program in debug mode and connect intellij to it.  I've been able to launch the program successfully in debug mode, and now I'm trying to get IJ connecting in debug mode.  Here's some code I've managed to cobble together and it appears to *almost* work, but I can't figure out how to configure things to use the network socket:

        // sets up the runner

        JavaParameters javaParams = new JavaParameters();
        javaParams.setJdk(ProjectRootManager.getInstance(project).getProjectSdk());
        javaParams.setMainClass(GosuTester.class.getName());
        javaParams.getClassPath().add(new File("."));

        initClasspath(project, javaParams);

        javaParams.getVMParametersList().add("-Xdebug");
        javaParams.getVMParametersList().add("-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5150");

        _testerProcess = new DefaultJavaProcessHandler(javaParams);
        _testerProcess.addProcessListener(new ProcessAdapter() {
          @Override
          public void onTextAvailable(final ProcessEvent event, Key outputType) {
            SwingUtilities.invokeLater(new Runnable() {
              @Override
              public void run() {
                outputArea.print(event.getText(), ConsoleViewContentType.SYSTEM_OUTPUT);
              }
            });
          }
        });

        //cobble together a debug configuration
        GenericDebuggerRunner basicProgramRunner = new GenericDebuggerRunner();
        ProjectPropertiesComponentImpl propertiesComponent = new ProjectPropertiesComponentImpl();
        RunManagerImpl manager = new RunManagerImpl(project, propertiesComponent);
        ConfigurationFactory configFactory = RemoteConfigurationType.getInstance().getConfigurationFactories()[0];
        RemoteConfiguration remoteConfig = new RemoteConfiguration("Gosu Tester", project, configFactory);
        RunnerAndConfigurationSettingsImpl configuration = new RunnerAndConfigurationSettingsImpl(manager, remoteConfig, false);
        ExecutionEnvironment environment = new ExecutionEnvironment(basicProgramRunner, configuration, project);
        basicProgramRunner.execute(new DefaultDebugExecutor(), environment);


Anyone have any tips?

Cheers,
Carson
8 comments
Comment actions Permalink

Dunno if this is correct, but this worked for me:

        GenericDebuggerRunner basicProgramRunner = new GenericDebuggerRunner();
        ProjectPropertiesComponentImpl propertiesComponent = new ProjectPropertiesComponentImpl();
        RunManagerImpl manager = new RunManagerImpl(project, propertiesComponent);
        ConfigurationFactory configFactory = RemoteConfigurationType.getInstance().getConfigurationFactories()[0];
        RemoteConfiguration remoteConfig = new RemoteConfiguration("Gosu Tester", project, configFactory);
        remoteConfig.PORT = "5150";
        remoteConfig.HOST = "localhost";
        remoteConfig.USE_SOCKET_TRANSPORT = true;
        remoteConfig.SERVER_MODE = false;
        RunnerAndConfigurationSettingsImpl configuration = new RunnerAndConfigurationSettingsImpl(manager, remoteConfig, false);
        ExecutionEnvironment environment = new ExecutionEnvironment(basicProgramRunner, configuration, project);
        basicProgramRunner.execute(new DefaultDebugExecutor(), environment);


Lauches a socket debugger against my background process.
0
Comment actions Permalink

Hello Carson,

This looks like a rather roundabout way of accomplishing this. Why don't
you use a debugger runner with your own run configuration?

I'd like to launch a java program in debug mode and connect intellij
to it.  I've been able to launch the program successfully in debug
mode, and now I'm trying to get IJ connecting in debug mode.  Here's
some code I've managed to cobble together and it appears to almost
work, but I can't figure out how to configure things to use the
network socket:

// sets up the runner
JavaParameters javaParams = new JavaParameters();

javaParams.setJdk(ProjectRootManager.getInstance(project).getProjectSd
k());
javaParams.setMainClass(GosuTester.class.getName());
javaParams.getClassPath().add(new File("."));
initClasspath(project, javaParams);

javaParams.getVMParametersList().add("-Xdebug");

javaParams.getVMParametersList().add("-Xrunjdwp:transport=dt_socket,se
rver=y,suspend=n,address=5150");
_testerProcess = new DefaultJavaProcessHandler(javaParams);
_testerProcess.addProcessListener(new ProcessAdapter() {
@Override
public void onTextAvailable(final ProcessEvent event, Key
outputType) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
outputArea.print(event.getText(),
ConsoleViewContentType.SYSTEM_OUTPUT);
}
});
}
});
//cobble together a debug configuration
GenericDebuggerRunner basicProgramRunner = new
GenericDebuggerRunner();
ProjectPropertiesComponentImpl propertiesComponent = new
ProjectPropertiesComponentImpl();
RunManagerImpl manager = new RunManagerImpl(project,
propertiesComponent);
ConfigurationFactory configFactory =
RemoteConfigurationType.getInstance().getConfigurationFactories()[0];
RemoteConfiguration remoteConfig = new
RemoteConfiguration("Gosu Tester", project, configFactory);
RunnerAndConfigurationSettingsImpl configuration = new
RunnerAndConfigurationSettingsImpl(manager, remoteConfig, false);
ExecutionEnvironment environment = new
ExecutionEnvironment(basicProgramRunner, configuration, project);
basicProgramRunner.execute(new DefaultDebugExecutor(),
environment);
Anyone have any tips?

Cheers,
Carson
---
Original message URL:
http://devnet.jetbrains.net/message/5302784#5302784


--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"


0
Comment actions Permalink

Dmitry,

Let me describe the functionality I'm shooting for and maybe that will explain my approach:

I'm implementing a tester window, where you can enter snippets of Gosu and execute/evaluate them.  (This is functionality that we had in our old internally built IDE)

The way that I've implemented this in IntelliJ is to start up a background process and pipe gosu programs to it, then listen on std out for the results.  This isolates the gosu code from IJ and allows me to avoid starting up a JVM (and Gosu environment) every time the user wants to evaluate some code.  So a user might edit the script any number of times and pipe it over to the tester process for compilation and evaluation.

I also want the user to be able to debug the script by simply pressing a different button, which is why I chose to create a remote debug configruation *if* the user clicks on a debug button, connect to the tester JVM and then pass the code across to be evaluated.

Does that sound sane to you, or do you still think a runner is the right way to go?

Cheers,
Carson

0
Comment actions Permalink

Another perhaps stupid question:

How can I find out the state of a GenericDebuggerRunner or DefaultDebugExecutor?  I want to detect if the debugger is currently running or not.

Thanks,
Carson

0
Comment actions Permalink

Hi Carson,

What you want is the LanguageConsole functionality, which is new in IDEA X. It allows you to have a REPL, basically, which it sounds like is what you want. It'll give you history, editing, highlighting etc. For an example from Jetbrains, check out the Clojure plugin.

Shameless plug - you could also check out my Scheme plugin (see: https://github.com/cmf/schemely/tree/master/src/schemely/repl). I modified (and hopefully improved) their functionality a fair amount, although I had to duplicate some core functionality in the plugin to do it.

The main changes I made are:

1. The REPL runs in a proper tool window, so the user can choose the side of the screen they want to see it on.
2. I abstracted it a bit to allow different types of REPL - by default it's very tied to an external process. Mine currently works with either an external process or an in-process one, which it sounds like is what you want.
3. I have a normal splitter between the editor window and the results pane - I found the dynamic resizing very annoying.
4. I made some fixes to the history functionality.

I plan to add a telnet REPL and I'd also like a debugging one. I'm also  toying with the idea of running a REPL inside the actual editor  instance to allow hot-updating of the plugin, but I'm not sure to what  extent that will be possible. There are a couple of plugins that allow similar functionality, I think it could be really useful.

BTW you might have some problems here with the parsing, as I commented to you off-list - I'm almost certain these sorts of transient editors aren't stubs.

One thing I haven't looked into is debugging - I'm about to try to add debugging support for implementations that allow it (Kawa, basically), but I'm not sure how this would work with the console. My pipe dream is a debugging REPL that would allow single-stepping of code snippets, but I'm not sure that's even possible, I'm not that familiar with the JVMTI interface.

Cheers,
Colin

0
Comment actions Permalink

Hello Carson,

There is no such state. You can have multiple debugger sessions of different
types running at the same time, so the question doesn't really make sense.

How can I find out the state of a GenericDebuggerRunner or
DefaultDebugExecutor?  I want to detect if the debugger is currently
running or not.


--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"


0
Comment actions Permalink

I probably have my objects mixed up then, sorry, I'm stumbling around here a bit.

What object represents a given debugger session?  

I see com.intellij.execution.configurations.RunProfileState, but haven't yet dug up where the connection is actually managed.

Basically, what I want to do is enable/disable the existing debugger session, depending on which button the user clicks for our tester.

Thanks,
Carson

0
Comment actions Permalink

Colin,

Thanks, I'll look a that today.

Cheers,
Carson

0

Please sign in to leave a comment.