Project

General

Profile

Debugging FWD projects with VS Code

Scope of this guide

This is a short guide on how to setup the debugger in VS Code for debugging FWD.

Such a guide for Eclipse can be found on Debugging Techniques. This guide pertains the use of the Java debugger provided by ONLY this VS Code extension. The link also contains the documentation for the extension. Details about setting up VS Code are here. General documentation about debugging with VS Code can be found here

Understanding the server.sh script.

To launch a FWD for an application, the server.sh script gathers options and environment variables and then executes a final command that is parametric, using the information gathered. The final command formed in the script is:

eval $prog -ea $hprof $maxheap $srvr $dtxt $spi $cpath $lpath -Djava.system.class.loader=com.goldencode.p2j.classloader.MultiClassLoader com.goldencode.p2j.main.ServerDriver $mode $batch $cfg $port "$@" 1>$outlog 2>$errlog

This command calls java with some JVM options (command line switches, heap size, server mode, debugger mode, SPI specification, classpath information, library path, classloader class), the main server driver class of FWD, the server driver's argument and passes output to files.

The launch.json file

To debug an application using FWD we need to replicate the above command in the debugger configuration file, so that the debugger launches the server the same way the script does but with added debugging functionality. To do this, the VS Code extension needs a proper launch.json file that specifies the debugger configuration. This launch.json file should be located inside a .vscode directory at the root of the application directory. The .vscode dir contains VS Code configuration that is specific to the project. That means .vscode should NOT be submitted to version control. Of course, that holds only until we start shipping standard debugging configuration in the FWD trunk. To generate launch.json, one can do it manually or let VS Code take care of that (the latter is preferred, because the manual way will not contain the boilerplate lines generated by the automatic way).

  • Manual way, starting at the root of the application project:
    mkdir .vscode && cd .vscode && touch launch.json
    
  • Automatic way:

Menu > Run > Add Configuration

and then select Java in the pop up asking what kind of debugging configuration should be generated.

If all goes smoothly, VS Code should open the launch.json file in the editor with some template already inside. You can use VS Code's Intellisense (keyboard shortcut is CTRL+Space) to get suggestions about available configuration options.

Getting the configuration correct

To make sure your launch.json works you need to get the values of the configuration options to be correct. These options and their values can change depending on what trunk revision you have. Keep in mind that future project revisions may do things a bit differently so don't just copy-paste the examples. To see those values, one easy trick is to make a copy of server.sh. In that copy, the final parametric command should be found and instead of evaluating it, an echo of it should be done. That means that for example this line in the script:

eval $prog -ea $hprof $maxheap $srvr $dtxt $spi $cpath $lpath -Djava.system.class.loader=com.goldencode.p2j.classloader.MultiClassLoader com.goldencode.p2j.main.ServerDriver $mode $batch $cfg $port "$@" 1>$outlog 2>$errlog

will turn into this:

echo $prog -ea $hprof $maxheap $srvr $dtxt $spi $cpath $lpath -Djava.system.class.loader=com.goldencode.p2j.classloader.MultiClassLoader com.goldencode.p2j.main.ServerDriver $mode $batch $cfg $port "$@" 
exit

The output of the altered script should look like this:

java -ea -XX:StringTableSize=1000003 -Xmx8192m -server -Djava.locale.providers=SPI,JRE -Djava.ext.dirs=/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext:/usr/java/packages/lib/ext:../lib/spi -classpath <list-of-paths-to-jars> -Djava.library.path=../lib/ -Djava.system.class.loader=com.goldencode.p2j.classloader.MultiClassLoader com.goldencode.p2j.main.ServerDriver server.xml net:connection:secure=true net:server:secure_port=3333 net:server:insecure_port=3433

Translating the output to VS Code debugger options

Getting the JVM options

The bash command line options for java EXCEPT THE CLASSPATH before com.goldencode.p2j.main.ServerDriver (the server driver class) are all JVM arguments. These should be put into the vmArgs array in the launch.json file. Of course, you should adjust according to the above command output you see on your screen

"vmArgs": [
                "-ea",
                "-XX:StringTableSize=1000003",
                "-Xmx8192m",
                "-server",
                "-Djava.locale.providers=SPI,JRE",
                "-Djava.ext.dirs=/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext:/usr/java/packages/lib/ext:../lib/spi",
                "-Djava.library.path=../lib/",
                "-Djava.system.class.loader=com.goldencode.p2j.classloader.MultiClassLoader" 
            ]

Getting the classpath

Each version of the FWD might depend on different jar files from the previous or the next. We need to ensure that we specify the full and accurate list of jars used in the current FWD version and their paths to the debugger classpath. To get the list of the paths, one can inspect the server.log generated by a normal (non-debugger) server startup. The full list of the jar paths is the array value of java.class.path inside JVM Properties that is logged at the very beginning of the server startup log. Example:

"classPaths": <json array that contains our jar list> [':../myjar.jar:../myjar2.jar']

Getting the target class right

The mainClass option should be the server driver class:

"mainClass": "com.goldencode.p2j.main.ServerDriver" 

Getting the server driver arguments

The server driver arguments are the arguments after com.goldencode.p2j.main.ServerDriver:

"args": [
                "server.xml",
                "net:connection:secure=true",
                "net:server:secure_port=3333",
                "net:server:insecure_port=3433", 
            ],

Setting the current working directory

We should be launching the debugger from the correct dir (the same as server.sh) for the relative links to work correctly:

"cwd": "deploy/server",

A sample launch.json using the above

You should get something like this:

{

    "configurations": [
        {
            "type": "java",
            "name": "<app-name> Debug",
            "request": "launch",
            "mainClass": "com.goldencode.p2j.main.ServerDriver",
            "args": [
                "server.xml",
                "net:connection:secure=true",
                "net:server:secure_port=3333",
                "net:server:insecure_port=3433", 
            ],
            "cwd": "deploy/server",
            "vmArgs": [
                "-ea",
                "-XX:StringTableSize=1000003",
                "-Xmx8192m",
                "-server",
                "-Djava.locale.providers=SPI,JRE",
                "-Djava.ext.dirs=/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext:/usr/java/packages/lib/ext:../lib/spi",
                "-Djava.library.path=../lib/",
                "-Djava.system.class.loader=com.goldencode.p2j.classloader.MultiClassLoader" 
            ],
            "classPaths": <json array that contains our jar list>
        }
    ]
}

2.png (14.6 KB) Thanasis Giannakopoulos, 03/17/2023 09:27 PM

1.png (64.2 KB) Thanasis Giannakopoulos, 03/17/2023 09:27 PM