Skip to content

Support running command before attaching debugger #120

Description

@fbricon

It's possible to debug tests running from a Maven build by calling mvn -Dmaven.surefire.debug test, then attaching the debugger to a remote Java process on port 5005, like

{
    "type": "java",
    "name": "Debug (Attach) to Maven tests",
    "request": "attach",
    "hostName": "localhost",
    "port": 5005
}

So this requires 2 separate actions from the user. Ideally, one would define a new 'surefire-debug' task for mvn -Dmaven.surefire.debug test and add "preLaunchTask": "surefire-debug" to the launch configuration. The problem is running that command doesn't return an exit code, since it's waiting for a debugger to attach, so the prelaunch task never finishes and the debugger never kicks in: you're stuck.
So it'd be nice if the debugger detected port 5005 is responding, before the preLaunchTask finishes.
If preLaunchTasks absolutely must finish before the debugger kicks in, then we might need to have a preLaunchCommand (or whatever better name) instead. Debugger bootstrap waits until port 5005 responds following execution of preLaunchCommand, then proceeds.

Activity

  1. fbricon commented on Oct 30, 2017

    @fbricon
    CollaboratorAuthor

    Martin Aeschlimann (@aeschli) does it make sense to generalize that feature request to vscode itself?

    cc Gorkem Ercan (@gorkem)

  2. gorkem commented on Oct 30, 2017

    @gorkem
    Collaborator

    We probably need a new a concept like debugTask on the launch that can delegate the running of the debugged application to a task. /cc Andre Weinand (@weinand)

  3. testforstephen commented on Nov 2, 2017

    @testforstephen
    Contributor

    Fred Bricon (@fbricon) Gorkem Ercan (@gorkem)
    duplicate with #33, the preLaunchTask works with mvnDebug tomcat7:run, but it seems you need click the debug button twice.

    1. click the first time it will show Listening for transport dt_socket at address: 8000,
    2. click the second time the debugger will attach to the port and the mvn process will continue to run.
  4. weinand commented on Nov 2, 2017

    @weinand

    For node.js debugging we've solved the problem by allowing any program/script to be used in a launch configuration. The only requirement is that the program/script opens a debug port at the end and then the debugger can attach to it.

    Example:

    first a regular config for a node.js program:

            {
                "type": "node",
                "request": "launch",
                "name": "Launch test.js",
                "program": "${workspaceFolder}/test.js"
            }

    Here program is a node.js program passed to a runtimeExecutable. If the runtimeExecutable is not specified we assume "node.exe".

    And in the following we set runtimeExecutable to a command "mocha" that runs node.js tests:

            {
                "type": "node",
                "request": "launch",
                "name": "Launch mocha tests",
                "runtimeExecutable": "mocha"
            }

    (you can find this in our docu here)

    So we have basically generalised the launch config to support two phases:

    • first a program is launched in debug mode and serves a debug port
    • then the debugger attaches to that port

    Maybe you could use a similar approach for Java, e.g. something like this:

    {
        "type": "java",
        "name": "Debug Maven tests",
        "request": "launch",
        "runtimeExecutable": "mvn",
        "runtimeArgs": [ "-Dmaven.surefire.debug", "test" ],
        "port": 5005
    }
  5. testforstephen commented on Nov 3, 2017

    @testforstephen
    Contributor

    Andre Weinand (@weinand) Thanks for the suggestion. Got it.

    if java debugger sends mvn -Dmaven.surefire.debug test command by runInTerminalRequest to vscode, vscode will execute it in integrated terminal. But because the mvn command doesn't return an exit code, vscode doesn't need wait the process to exit and will send the process id back. The debugger itself need poll the debug port to see if the launching operation is ready. Right?

  6. weinand commented on Nov 3, 2017

    @weinand

    Yes, your understanding is correct. Here are some additional details:

    There are basically two ways a DA can run a target (the mvn -Dmaven.surefire.debug test in this case):

    • it can run the target directly as a sub-process of the DA and track the exit code, process ID, and any output itself (this is the default behaviour used in the node-debug when no console attribute is specified).
    • it can use the runInTerminalRequest to delegate the execution to VS Code (and use the user configured shell etc.). In theory the process ID is returned from VS Code to the DA, but it practice VS Code does not know the process ID and it doesn't know the exit code either.

    This means the DA cannot really know whether the launching of the target was successful and whether the target is ready for debugging. For this reason the DA starts trying repeatedly to attach to the debug port (and it times out after 20 seconds).

    Please note that the DA makes no difference between launching a regular java runtime (e.g. java ...) and launching of a command like mvn -Dmaven.surefire.debug test. So for node-debug there was no additional code needed for supporting arbitrary tools like test runners.

  7. testforstephen commented on Nov 3, 2017

    @testforstephen
    Contributor

    Understand, i think i got the answer. Thanks again.
    Currently we have taken the first way to launch normal java program. And plan to try the second way for those programs with input/output requirement.

  8. removed this from the 0.4.0 milestone on Mar 5, 2018
  9. added this to the 0.7.0 milestone on Mar 5, 2018
  10. testforstephen commented on Apr 3, 2018

    @testforstephen
    Contributor

    find no resource to finish it yet, add it to backlog.

  11. Eskibear commented on Aug 30, 2018

    @Eskibear
    Member

    Any updates? Here is a scenario that by specifying prelaunchtask to execute "mvnDebug" in the "attach" config, I want to debug in one-click. But prelaunchTask seems not to work with background command, as mentioned in microsoft/vscode-maven#49 (comment)

    And any ideas about the use case for mvnDebug users?

  12. testforstephen commented on Aug 30, 2018

    @testforstephen
    Contributor

    If the preLaunchTask points to a server mode or background task, you should use problemMatcher filter to tell VSCode it's ready. Then the Java debugger has the chance to attach to the mvnDebug port.

    Below is the tasks.json spring-boot sample:

            {
                "label": "mvnDebug",
                "type": "shell",
                "command": "mvnDebug spring-boot:run",
                "isBackground": true,
                "problemMatcher": [{
                    "pattern": [{
                        "regexp": "\\b\\B",
                        "file": 1,
                        "location": 2,
                        "message": 3
                    }],
                    "background": {
                        "activeOnStart": true,
                        "beginsPattern": "^.*Preparing to execute Maven in debug mode.*",
                        "endsPattern": "^.*Listening for transport dt_socket at address.*"
                    }
                }]
            }
    

    And launch.json sample:

            {
                "type": "java",
                "name": "Debug (Attach)",
                "request": "attach",
                "hostName": "localhost",
                "port": "8000",
                "preLaunchTask": "mvnDebug"
            }
    
  13. IcedAnt commented on Dec 5, 2019

    @IcedAnt

    This is a good workaround but there's still the issue of the VS Code popup telling you that errors exist and you have to click "Debug Anyway" to continue.

    Maybe we can get a "successMatcher" instead, that attaches the debugger automatically when it matches "endsPattern"?

  14. github-actions commented on Nov 12, 2025

    @github-actions

    Hi Fred Bricon (@fbricon), I'm an AI Support assistant here to help with your issue. While the team reviews your request, I wanted to provide some possible tips and documentation that might help you in the meantime.

    Use a background task with a problem matcher so VS Code knows when the JVM is listening on 5005:

    • In .vscode/tasks.json, define a task with isBackground = true and a problemMatcher that watches for the “Listening for transport dt_socket at address” line:

    {
      "version": "2.0.0",
      "tasks": [
        {
          "label": "surefire-debug",
          "type": "shell",
          "command": "mvn -Dmaven.surefire.debug test",
          "isBackground": true,
          "problemMatcher": {
            "pattern": [],
            "background": {
              "activeOnStart": true,
              "beginsPattern": "^.*Debugging in suspended mode.*$",
              "endsPattern": "^.*Listening for transport dt_socket at address (?<port>\\d+).*$"
            }
          }
        }
      ]
    }

    • In launch.json, attach after that task signals readiness:

    {
      "type": "java",
      "name": "Debug (Attach) to Maven tests",
      "request": "attach",
      "hostName": "localhost",
      "port": 5005,
      "preLaunchTask": "surefire-debug"
    }

    This way, the preLaunchTask ends when the JVM is ready (port 5005 open) rather than when Maven exits.

    High-confidence reference:

    • spring-boot-dashboard issue #296 — shows how to use isBackground and a problem matcher to detect when mvn debug is listening:
    microsoft/vscode-spring-boot-dashboard#296 (comment)

    Other references with low confidence

    • vscode-maven issue #49 (comment) — demonstrates a similar mvnDebug preLaunchTask approach:
    microsoft/vscode-maven#49 (comment)

    The team will respond to your issue shortly. I hope these suggestions are helpful in the meantime. If this comment helped you, please give it a 👍. If the suggestion was not helpful or incorrect, please give it a 👎. Your feedback helps us improve!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions