This lesson is part of the Module Development with the Ignition SDK course. You can browse the rest of the lessons below.

LESSON LIST

Autoplay Off

Description

Learn how to use IDE debugger breakpoints in your SDK Java source code, to trace the flow of execution of your module project.

Transcript

(open in window)

[00:00] In this lesson, we'll demonstrate how to set up some rudimentary debug of an Ignition SDK module. We'll show how to attach the IntelliJ debugger to various types of running Ignition processes so they can be run under debugger control. Our emphasis in this lesson will be on the indicated portions of the development workflow. Now that we've seen how the module code is compiled, executed, and structured, we'll likely need some way to trace its path of execution and debug it as needed. There are two ways to do this: using logger message outputs, and attaching an IDE debugger to a running Ignition SDK module. We'll consider the debugger approach here and save the other way for a separate lesson. Also, we'll confine ourselves to showing only how to attach the process, not how to actually step through the code, assuming the viewer is already somewhat familiar with those kinds of debugger mechanics. Here is a very simplified big picture view of the debug process. We are trying to establish the debug connection in the middle, between an Ignition process on the left running our SDK module code, and its attached module code in the IntelliJ debugger on the right.

[01:15] This debug connection will be established using the Java debug wire protocol or JDWP. JDWP is a Java technology, not anything specific to Ignition. There is plenty of support and documentation available for it online. So, the debug process in general will go like this. We'll set up any needed debug config info for the Ignition process, and then the same info for the IDE debugger using a remote debug profile. Then we'll invoke the relevant Ignition process by whatever means, run the corresponding remote debug profile on the IDE side. At this point, a debug connection is established and we can then run the module code in debug mode on the IDE side. Okay, first let's take a look at the specifics of this for the gateway scope.

[02:04] So for gateway scope module code, we'll do the following. For the gateway, debug config info is in the ignition.conf file, so we'll enable a few lines there. Restart the gateway to read the debug data, then create a named remote debug profile with the same debug data, and run the gateway remote debug profile to establish the debug connection, reload the module into the gateway to repeat the startup sequence, at which point we can run the gateway scoped SDK code under debugger control. Let's start by editing our Ignition installation's ignition.conf file, which is found in the Ignition installation directory, data. Please refer to the User Manual for the default Ignition installation directories for each supported operating system. For example, here I'm running on Windows, so my default install directory is C:\Program Files\Inductive Automation\Ignition.

[03:02] If we scroll down a bit, to the Java Additional Parameters section, we will uncomment these two debug lines Here we're setting the debug connection port to 8000. While it can be useful to set suspend equal to yes if trying to debug gateway scope module startup code, we'll demonstrate a different way to achieve that. And remember that the numbering of these additional parameters needs to be unique though not sequential. We're going to need some of these debug parameters for other steps. So let's copy this last part, and we'll save it off to a text file for later use. That's all that's needed, so we'll save our changes. But to read in any ignition.conf debug changes, we need to restart the gateway. So in a file browser open to the Ignition install directory, we'll start by copying this directory path. Then to restart the gateway we'll once again run the platform independent command line utility gwcmd, and we'll need to run it with admin permissions from a command line.

[04:07] So we'll do the following. On my Windows system at the lower left, I'm going to run a command prompt, right clicking to run as an admin. Then we'll change to that Ignition directory by doing cd and pasting our directory path and run the command gwcmd -r This will likely take several moments, so we'll fast forward through all the outputs. And now our config file, debug changes have been read by the gateway. Next, on the IntelliJ side, we'll set up the corresponding remote debug profile by doing Run > Edit Configurations, and then clicking on the add to add a new remote JVM debug configuration. To keep things organized, let's name this one Gateway SDK Debug and update the port only to 8000 to match the ignition.conf file.

[05:11] Then we will click OK and we are done. Then what we'll see is an additional run configuration appearing in this top dropdown. While we're in IntelliJ, let's also set ourselves one execution breakpoint in the code. If we wanted to debug the module startup process, we might set breakpoints here on setup or startup. Let's set a breakpoint on startup. Now, if our SDK module has been loaded, we are already downstream of these. However, we can force the startup lifecycle to be repeated by simply reloading our SDK module in the gateway. Now we're ready to run this code in debug mode. First, we'll run our remote debug profile Gateway SDK Debug, and in the console we see this attaches a debug connection to the already running gateway process on port 8000.

[06:07] But remember that we are already downstream of the startup method. It already ran when this module was installed into the gateway. No problem. We'll just reload the module into the gateway. Here in our Config > Modules page, we'll simply scroll down to the bottom, and for our scripting-function-g module, we will click Restart. Yes, we're sure. So now back over in IntelliJ, we see that the restart has caused us to repeat the startup cycle, and now we are paused at the breakpoint to await further stepping. And at this point, we can just stop the debug session, then remove the breakpoint for now, and we'll move onward. For designer scope module code, we'll do the following. This time we'll create a dedicated designer launcher containing the needed debug config info, then create another named remote debug profile with the same debug data. Then we'll invoke the designer using our launcher, and when it pauses to prompt for our credentials, we'll run the designer remote debug profile to establish the debug connection, at which point we can run the designer scoped SDK code under debugger control.

[07:16] So to set up a dedicated designer launcher with the needed debug parameters, we'll do the following. We'll invoke our designer launcher by whatever means, here we'll use our taskbar icon. We've already got a default designer, but let's add a debug specific one by doing Add Designer, selecting the desired gateway, and clicking Add Designer. Now let's configure this added launcher as follows. We'll first click the three dots, then Manage. To keep the naming consistent with the prior one, let's name it Designer SDK Debug. And for the JVM arguments, let's reuse what we had in our ignition.conf file. So we'll just paste that text here, but with one change, we'll set the address to 8001, and that should do it.

[08:09] So we'll click OK, and we see our new designer launcher config. Now we can move this launcher to the lower right and resize it a bit for upcoming use. Then as before back in IntelliJ we'll set up the corresponding remote debug profile, but this time we'll copy and update our existing profile by doing: Run, Edit Configurations. And this time we'll click copy configuration and then we'll edit it as follows. To keep the naming consistent, we'll call it Designer SDK Debug, and update the port only to 8001 to match what we set up for our designer launcher. Then click OK and we are done. As before, we see our new remote debug profile added to the top dropdown. Once again, while we're in IntelliJ, let's set ourselves one execution break point in the code.

[09:09] Let's go over to our DesignerHook file and set a single break point on line 21 on the startup method. So we should see program execution halt here when we invoke our designer. So now we'll run our designer by selecting the designer SDK debug launcher and clicking Open Designer. And here we'll fast forward through the startup sequence. Eventually we'll reach this pause in the startup sequence when the designer is prompting for our login credentials. So at this point, we will go up top and run our remote debug profile for the designer. In the console we see this attaches a debug connection to the already running designer process on port 8001. Then when we do enter our login credentials, the startup sequence proceeds, we'll select the desired project, I'm going to open the sandbox one, and the designer startup sequence continues, and eventually we'll pause at the breakpoint, actually at the first executable statement inside the method, to await further debugger stepping. And again, at this point, we'll once again just stop the debug session, then remove the breakpoint for now, and move onward. Similar to before.

[10:39] for client scope module code, we'll do the following. This time we'll create a dedicated client launcher containing the needed debug config info, then create another named remote debug profile with the same debug data. Then we'll invoke the client using our launcher, run the client remote debug profile to establish the debug connection, at which point we can run the client scoped SDK code under debugger control. Finally, to set up a dedicated vision client launcher with a needed debug parameters, we'll do the following. We'll invoke our vision client launcher by whatever means, here we'll use the taskbar icon.

[11:16] We've already got other client launchers, but let's add a debug specific one by doing Add Applications, then selecting the desired gateway, and then clicking Select Gateway. Now we can select the desired project, so I will go ahead and select Ignition Prototyping on my system, then click Add Applications. Now let's configure this added launcher as follows. We'll click on the three dots, then Manage. To keep the naming inconsistent with the prior ones, let's name this one Client SDK Debug and give it a description, perhaps something like Launch client in debug mode.

[12:04] Then we can specify the Vision client project at startup. We'll leave this one as is. And finally, for the JVM arguments down at the bottom, we'll reuse what we had in our ignition.conf file. So we will paste in that text, but with one change, we'll change the address to 8002. That should do it. So we will click OK and we see our new client launcher config. So we will move this window down to the lower right and resize it a bit for upcoming use. Then as before, back in IntelliJ, we'll set up the corresponding remote debug profile. And again, we'll copy and update an existing profile by doing Run, Edit Configurations, and we will click copy configuration, and then we'll edit it as follows. To keep the naming consistent, we will name this one Client SDK Debug and update the port only to 8002 to match what we set up for our client launcher. Then we will click OK and we are done.

[13:13] And as before, we see our new remote debug profile added to the top dropdown. And once again, while we're in IntelliJ, let's set ourselves one execution breakpoint in the code. So here in our ClientScriptModule file, we'll set a single break point on line 23 on the multiplyImpl method. So we should see program execution halt here when we run our client application. So similar to before, now we'll run our client by selecting the Client SDK Debug client launcher and clicking Open. But we'll fast forward through the client's startup sequence. So similar to before, we will now run our Client SDK Debug remote debug profile, and IntelliJ shows it's connected to the target on port 8002.

[14:08] Then if we restore our client application, and enter two input values, like so, and click the button, once again, we are paused at the specified breakpoint, actually the first executable line inside the method, and awaiting further debugger stepping. In fact, you'll notice we haven't even completed the multiply operation yet, so our result value hasn't been updated yet. Execution is still awaiting user action under debugger control. So here's the overall summary of debugging SDK module code in each of the three scopes. In each case, we've demonstrated the following. First, we set up debugging parameters in either ignition.conf or a new dedicated launcher. Then we repeated those parameters in the corresponding remote debug profiles on the IDE side. We then started the applicable Ignition process, then started its companion remote debug profile, at which point a debug connection was established, execution was paused at some specified breakpoint, and the applicable SDK module code was ready to be stepped through under user control in the debugger.

[15:23] So now you should have some working knowledge of Ignition SDK debugging using breakpoints in IntelliJ.

You are editing this transcript.

Make any corrections to improve this transcript. We'll review any changes before posting them.