Here we describe how the Plugins are loaded by Nx Witness Server, and how to investigate if a Plugin was not loaded correctly.
Nominal loading procedure
When Nx Witness Server starts, it looks through the contents of the following directory (examples below are given for a default Nx Witness installation):
C:\Program Files\Network Optix\Nx Witness
This directory can contain Plugins in one of the following two forms:
- A standalone dynamic library file (.dll on Windows, .so on Linux).
- This form is used by Plugins that do not need any additional files distributed along with their dynamic library file.
- A subdirectory containing a dynamic library file, and potentially other files (which are ignored by the Server).
- The name of the subdirectory must be equal to the Plugin’s libName — the name of the Plugin dynamic library without the lib prefix (on Linux) and the extension, e.g.
- This form is used by Plugins that need to include additional files along with their dynamic library file (e.g. other dynamic libraries they depend on, or some resource or configuration files that are loaded at runtime).
- This directory is called the Plugin’s home directory and can be obtained by the Plugin in runtime via calling
IUtilityProvider::homeDir()on an object supplied by the Server to IPlugin::setUtilityProvider().
Each dynamic library found according to the above rules will be attempted to be loaded as a Plugin. This procedure is performed only at the Server start-up. So, if a Plugin dynamic library is added, Nx Witness Server must be restarted.
After Nx Witness Server loads a Plugin dynamic library, it looks for a particular function exported from that library, called Entry Point Function. It can be one of the following:
- nxpl::PluginInterface* createNXPluginInstance()
- Used in Video Source SDK and Storage SDK.
- nx::sdk::IPlugin* createNxPlugin()
- Used in Metadata SDK.
- Note: When all SDKs are combined into one, this will be the proper Entry Point Function for all Plugins; and createNXPluginInstance() will be deprecated.
Nx Witness Server then calls the Entry Point Function which returns an object called a Plugin Object that implements the required interface. All further interaction with the Plugin goes through that Plugin Object.
When Nx Witness Server shuts down, it releases the Plugin Object, which effectively leads to its destruction (since this is the only reference of that object).
For a description of how to implement a Plugin Object, see the Doxygen documentation for its interface – the return type of the respective Entry Point Function.
For Analytics Plugins, the SDK offers a helper base class for the typical implementation, which handles most technical aspects and requires the derived class to implement only what is needed — nx::sdk::analytics::Plugin defined in nx/sdk/analytics/helpers/plugin.h.
Besides the nominal loading procedure described above, there are a couple of features that can be used for experimenting with Plugins:
- optional plugins — A Passlist of Plugins which must be loaded from another directory called plugins_optional,
- disabled plugins — A Blocklist of Plugins which must not be loaded.
Both features can be activated via IniConfig — vms_server_plugins.ini. For details of what the .ini files are, and where they are located, see Configuring via .ini files – IniConfig. To create this file filled with default values and documentation for its options:
- Create an empty .ini file with the proper location and name
- Restart Nx Witness Server.
- Editing the values in this file
- Restart the Server again to re-launch Plugin loading procedure using the new options.
The option enabledNxPluginsOptional in vms_server_plugins.ini defines a Passlist of optional Plugins. It can be set to the comma-separated list of each Plugin’s libName — the name of the Plugin dynamic library without the lib prefix (on Linux) and the extension; the quotes around the value and spaces after commas are optional.
Such plugins will be attempted to be loaded from the directory named plugins_optional, located next to the nominal plugins directory. The option value can be an asterisk (*) which means "load all plugins in this directory".
The Nx Witness Server installation has the plugins_optional directory present and populated with a number of Plugins, which may be helpful for experimenting and debugging. Two of them are the Metadata SDK sample Plugins called stub_analytics_plugin and sample_analytics_plugin.
For example, to load them at the Server start-up, list their names in the enabledNxPluginsOptional .ini option:
Example scenario using Passlist: You want to temporarily enable some plugins from the ‘plugins_optional’ directory. These could be plugins that came with the Nx Witness Server distribution or ones that you’ve put in. Instead of moving these dynamic libraries from `plugins_optional` to `plugins`, you can conveniently list these libraries in the Passlist.
Note: The Plugins that are included in the Nx Witness distribution in the plugins_optional directory are different from the ones which can be built via the SDK in that they are dynamically linked to certain libraries that come with the Nx Witness distribution.
For example, the binary for Stub Analytics Plugin in this directory is dynamically linked to the nx_kit library that resides with other VMS libraries, as opposed to incorporating the nx_kit library statically, which is the case when the same Plugin is built as a sample within the SDK.
The option disabledNxPlugins in vms_server_plugins.ini defines a Blocklist of non-optional Plugins. It can be set to the comma-separated list of each Plugin’s libName — the name of the Plugin dynamic library without the lib prefix (on Linux) and the extension; the quotes around the value and spaces after commas are optional.
Such plugins will NOT be attempted to be loaded from the nominal plugins directory. The option value can be an asterisk (*) which means "do not load any plugins in this directory".
For example, if you want to start Nx Witness Server without loading any plugins from the nominal plugins directory, put an asterisk in this .ini option:
Note: This option does not influence the processing of Plugins in the plugins_optional directory.
Example scenario using Blocklist: When you develop and debug a Plugin on a camera and you want to put other Plugins (that are compatible with that camera) out of your way. Instead of moving the dynamic libraries out of plugins/, you can conveniently list these libraries in the blacklist.
Linked DLL lookup on Windows
If the Plugin DLL resides in a directory with other Plugins — i.e. without a defined home directory (see above) — Nx Witness Server instructs Windows to look for DLLs which may be required for the Plugin’s DLL by using "default DLL search order" (defined by Windows), but excluding the current directory of the process.
If the Plugin DLL resides in a dedicated directory (its home directory) with other DLLs that it uses, Nx Witness Server instructs Windows to look for those DLLs in the Plugin’s home directory instead of using "default DLL search order" (defined by Windows).
If there are any issues with finding and loading the DLLs that come with the Plugin, then disable this behavior by setting the option disablePluginLinkedDllLookup in vms_server_plugins.ini:
This will revert to the "default DLL search order" (defined by Windows) but exclude the current directory of the process. This modified setting may help to eliminate errors caused by interference with WinAPI.
Example scenario on a Windows system: Your Plugin fails to load — due to issues with either the Plugin itself or the libraries it uses — and Windows provides unclear diagnostics. To start troubleshooting, you experiment with the DLL Lookup Order to see if difficulties in finding the dependencies are the culprit.
Troubleshooting Plugin loading
Detailed information about plugin loading attempts is available in the Server main log. See Logging from the Plugin for information about obtaining this log.
If it looks like Nx Witness Server does not load the Plugin correctly, e.g. the Plugin does not appear in the Nx Witness Desktop GUI where it should or the Analytics Plugin does not appear in Camera Setting, there may be many reasons for this, including the following:
- The Plugin resides in the wrong directory.
- Nx Witness Server decided not to load the Plugin due to the blacklist in vms_server_plugins.ini.
- The OS failed to load the Plugin’s dynamic library due to missing dependencies.
- The Plugin’s dynamic library was loaded by the OS, but does not conform to the requirements of Nx Witness Server to be a proper Plugin (e.g. does not export the required functions).
- The Plugin dynamic library entry point function returns an unexpected value.
- The Plugin was loaded successfully but does not appear in certain places in the Nx Witness Desktop GUI because it is not expected there, e.g. it does not claim to support the particular Camera, or it does not produce any metadata with the current Plugin Settings.
To see what exactly happened during the attempt to load a Plugin, see the Server main log messages with the tag PluginManager and the INFO and ERROR logging level.
The same information about each Plugin loading attempt is available via the REST API call:
GET /api/pluginInfo. To call it, run Nx Witness Server and open the following URL in a web browser: http://localhost:7001/ec2/pluginInfo/
Note: In the case of missing dependencies (dynamic libraries used by the Plugin’s dynamic library), the error message provided by the OS may not be informative, especially in Windows. In this case, we recommend manually checking if there are unsatisfied dependencies.
For example, you can use the Dependency Walker tool for Windows (available from a third-party software vendor at https://www.dependencywalker.com/), or ldd libmy_plugin.so command on Linux.
To see if Nx Witness Server had any issues with altering the DLL search order, see the Server main log messages with the tag PluginManager, the DEBUG and ERROR logging level, and containing the string GetDllDirectoryW.
Article is closed for comments.