Event Handler Troubleshooting
There are a variety of options available to test and debug event handlers.
See the event handler API documentation for more information.
Validating and Testing Event Objects
The Validator, available on the Debug menu, confirms that libraries associated with event handlers are up to date. It is good practice to confirm that the event handler is returning the results you expect.
-
Click Connection Events Test on the Debug menu to confirm that the life cycle event handlers and model event handlers you have added to your model are performing as you expect.
-
Click Execute on the Operation tab of the Entity window to test operation events.
-
Test events that include recordset and recordset field events using the Recordset Test option on the Debug menu.
-
Use the Procedure Test option, available from the Debug menu, to test the procedures for a table.
-
Click Attributes Test on the Debug menu to test any event handler that uses Write Attributes.
-
Use Web Builder, if debugging on the server is required. You must configure the server properties to enable debugging. Event Handler options are configured on the Server Properties panel.
Stream Output
You can view the output your Java or .NET event handler code sends to the System.out (stdout) and System.error (stderr) standard streams. The output also includes the trap exception stack dump for unhandled exceptions, which can be useful if your event handler code is calling other third-party packages or assemblies.
Design Tool
Output is displayed in Debug > Event Handler Console and is written to the console even when the console is hidden. You can open the console after unexpected behavior occurs. To display the console when the Design Tool is run, open Settings > Event Handlers > Debugging and select Show when Design Tool starts.
About the Event Handler Console
To open the Event Handler Console, click the button on the Event Handler toolbar or click Event Handler Console on the Debug menu.
The Event Handler Console displays the output that event handlers have sent to the System.out and System.err streams. You can use the remote debugging features in your Java development environment to set breakpoints, step through code, and view runtime status.
Host Integrator writes to the console even when it is hidden, so you can open it for information after some unexpected behavior occurs. Any unhandled exception that is not an ApptrieveException or EventTimeoutException causes a stack dump to be written here.
-
Configuring and Using the Console
You can open the console window yourself, or you can choose to open the console automatically when the Design Tool starts.
Each Design Tool instance (or Session Server instance) sends output to a distinct console window. When you are debugging your event handlers, use Alt+Tab to review console output.
-
Console Options
-
Wrap Lines— By default, output lines are wrapped at the right window edge. Select the Wrap lines check box to change this option.
-
Session Server Debug Settings - In a production environment, the standard output or standard error stream information will, by default, be thrown away. You can use the script.properties file to designate a file where this information should be directed. Manual reduction of this file must be performed periodically.
Session Server
To provide maximum performance of the runtime session server, by default, the standard output and standard error stream information is discarded. However, you can redirect this information to a text file.
-
For Java event handlers, edit the
<vhi>/etc/script.properties file, setting the vhi.script.output.file
property to true. See property files for more information. -
For .NET event handlers, edit
<VHI>\lib\dotnet\clrscriptserver.exe.config,
setting RecordOutput to true.
By default, the file, handlers.out is generated in the RocketSoftware/Verastream/HostIntegrator/etc/output
directory. However, you can set a different name with the vhi.script.output.filename
property (Java) or OutputFilename setting (.NET).
No management is provided for any of the output generated by these properties. Any output recorded is simply appended to whatever content already exists in the output file.
See Guidelines for Developing Event Handlers for detailed information on event handlers in general and specifically on limiting the use of output streams to ensure performance efficiency.
Remote Debugging
Remote debugging enables you to use your IDE to set breakpoints in your event handler source code, step through code execution, and inspect variable values.
Load your event handler source code into the editor and set a breakpoint. Trigger the event and the breakpoint will be hit. Now you can step through the code and inspect the values of your variables.
Java
- Verify that the debug port is enabled on the Java virtual machine that hosts the script manager. In the Design Tool, it is already enabled. For the Session Server, you must enable script manager debugging in the Administrative Console (server properties > General > Events) and restart the server.
- Note which port number is used. In Design Tool, see the Debug port assigned on the Settings > Event Handlers > Debugging tab. For the Session Server, see the Assigned event handler debug port in server properties. If the requested port is in use (such as when running multiple instances of Design Tool), an increment is used.
- Connect your Java IDE to this debug port
.NET
To debug a .NET script in the session server or Design Tool, attach the Microsoft Visual Studio debugger to the script server. The name of the .NET script server process is clrscriptserver.exe. In Visual Studio, you can attach to this process using Debug > Attach to process.
In a development environment, you typically have two instances of clrscriptserver.exe, one for the session server and one for the Design Tool. The script server for the session server runs as user SYSTEM. To select it, make sure you check the Show processes from all users check box. The script server for the Design Tool is running as the same user as the Design Tool.
Event Handler Timeouts
When timeouts are enabled (the default), if you leave execution suspended at a breakpoint for too long, you may trigger a timeout condition.
Disabling event handler timeouts
You can disable event handler timeouts in both the Session Server and the Design Tool. When event handler timeouts are disabled, all timers used to calculate timeouts (for a single session) are suspended whenever that session has fired an event to the script manager. Once the script manager returns a response to the Design Tool or Session Server, the suspended timers will resume.
-
In the Design Tool, to temporarily suspend all timeouts, click Events > Disable Timeout, or use the Disable Timeout button on the Event Handler toolbar.
-
For the Session Server, you can disable event handler timeouts in Administrative Console (Server properties > General > Events).
Testing event handler timeouts
Use these steps to test event handler timeouts, when they have been left enabled in Design Tool.
- Place a breakpoint in the event handler code activated by an event.
- Set the event handler timeout and client timeouts to a value larger than the time expected for the event handler activity.
- Cause the event to fire and stop execution at the breakpoint.
-
Click Cancel while the event is in progress to force a timeout exception to be sent to the event handler.
When an event takes more than a half second to complete, a progress window with a Cancel button displays. This is the same dialog box used for tracking the progress of procedures and operations. In some cases, this dialog box may already be open when the event handling condition occurs. 5. Begin single-stepping through the event handler code to determine how the event handler reacts to the timeout.
Note
You may encounter a problem attempting to reset the script manager after a breakpoint is encountered. After you click Events > Reload Handlers, you may see the following error: "[VHI 4302] Error connecting to the script manager. It is likely that the script manager's TCP Listening port (9654) is in use by a third-party application." To resolve this issue, resume execution at the breakpoint in the debugger before you reload handlers.
More information
Event Handler Communications Errors
While requesting a build of an event handler, the following message may be displayed if the script manager could not start:
An error occurred while communicating with the script manager.
Socket Error - Socket not connected.
If you are debugging an event handler and the debugger stops at a breakpoint, you can resume the debugger and retry the communication. Otherwise, press Abort to restart the script manager.
If you press Abort and continue to see this error, it is usually due to a port conflict. The default port for the Script Manager is 9653, with a range of 9653 - 9669. Change the port number and try the event handler build again.
Connection Events Test Options
The Connection Events Test dialog box tests sequences of events that require a reset of the terminal session: loading a model, connecting to the host, and establishing a client connection. The startup and shutdown sequences below illustrate the differences between each of the test otions.
Dedicated Session: New Client
This option simulates the sequence of one client application disconnecting and another client connecting to this model using the Connect To Model method:
- The Client Disconnected event is fired.
- The terminal session navigates to the home entity, which could involve Execute Operation events.
- The logout process is executed, which could involve firing the Execute Logout event.
- The host session is disconnected from the host.
- Steps 1-7 of standard reset processing are executed.
- The host session is connected to the host.
- The login process is executed, which could involve firing the Execute Login event.
- The terminal session navigates to the home entity, which could involve Execute Operation events.
- The Client Connected event is fired.
Steps 1-4 can also be accessed by pressing the logout button, while steps 5-9 can be accessed by pressing the login button on the same toolbar.
Pooled Session: New Session
The New Session option simulates destroying and creating a pooled session, then connecting to the session using ConnectToSession method.
With this option, a session pool host session is created, connected to the host, and logged in before a client session is actually created. This simulates the real-world behavior of a session pool session.
- The Client Disconnectedevent is fired.
- The terminal session navigates to the home entity, which could involve Execute Operation events.
- The logout process is executed, which could involve firing the Execute Logout event.
- The host session is disconnected from the host.
- The Client Session Destroyed event is fired.
- The Host Session Destroyed event is fired.
- The Host Session Created event fires.
- The login process is executed, which could involve firing the Execute Login event.
- The terminal session navigates to the home entity, which could involve Execute Operation events.
- The Client Connected event is fired.
- The Authenticate User event is fired, with any resulting errors displayed in the Event Handler Console.
- The Client Session Created event is fired.
Pooled Session: New Client
This option simulates the sequence of one client application disconnecting and another client reconnecting to this model using the ConnectToSession method.
In this case, only the client session events are fired because a session pool host session is not normally logged out or destroyed between client invocations.
- The Client Disconnected event is fired.
- The terminal session is navigated home, which could involve Execute Operation events.
- The Client Session Destroyed event is fired.
- An Authenticate User event is fired.
- The Client Session Created event is fired. The Client Connected event is fired.
Event Handler Update Needed
The Design Tool detects when the contents of the model-specific script libraries (in the scripts\lib directory)
have changed.
If you have enabled the option to automatically reload event handler libraries when libraries change, on the Settings menu > Building tab, the Design Tool responds to a change by reloading the event handler JAR files (Java) or assembly files (.NET). There are cases when the reload does not occur:
- The script manager is unable to respond to a Design Tool request (for example, if it is stopped at a breakpoint)
- An operation or event is in progress
- Automatic event handler reloading has been disabled.
The Design Tool displays a Update Needed indicator () in the status window. This symbol indicates that the event handler JAR/assembly files stored on disk no longer match what is being used by the script manager (in memory).
Click Reload Handlers on the Events menu. Clicking Rebuild also updates the event handler libraries.
Additional Event Handler Troubleshooting Options
As you develop event handlers, use the debugging options in the Design Tool to identify problems. Here are additional conditions you may need to address when developing or maintaining models that have event handlers associated with them.
Debugging tools show results that do not match the objects definition
Event handler name is displayed in red
Reset or Update Needed icon is displayed on the status bar
Error message: An error occurred while communicating with the script manager
Callback method is not allowed within an event handler
Java startup synchronization problems when additional JAR files are in scripts\lib
folder
NET Runtime errors result from crossing domain boundaries
Model is not recognizing source files that have been imported
Deployment error with saved model
Problems with Web Builder applications event handlers for recordsets and attributes
Debugging tools show results that do not match the model objects definition
This is not a event handler error, and may in fact be the appropriate behavior if an object has an event handler attached to it. Check to see if a lightning bolt () is displayed next to the object in question. This event handler may include logic that overrides or extends the object's behavior as defined in the Design Tool. For example, the recordset test used in the event handler example returns values that include a dollar sign not defined within the recordset itself.
Event handler name is displayed in red
The name of an event handler is displayed in red if a model object has an event handler attached, but the event handler no longer exists (for example, the JAR or assembly file containing the handler has been removed, a class file is missing, or the source file was not available when handlers were rebuilt).
You cannot deploy a model with this problem, although the model itself can be saved. If the JAR file or the assembly file is the problem, simply rebuild the event handlers.
Reset or Update Needed
Under certain conditions, you may see one of the following symbols on the Design Tool status bar:
[Update Needed] The event handler JAR or assembly files stored on disk no longer match what is being used by the script manager (in memory).
Click (Reload Event Handlers) to update the JAR files.
The script manager cannot respond. If this condition occurs on the Host Integrator Server, the Server initiates a shutdown process. No manual reset is needed.
Error message
An error occurred while communicating with the script manager
If this event handler communication error is displayed while building event handlers, there may be a problem with the port being used by the script manager. Other problem sources are the version of the JRE or the JAR file being used by the script manager (Java), or an equivalent version discrepancy with .NET assembly files.
When a script manager communication error occurs on the Host Integrator Server, this information is sent to the log file and to the client application.
Script manager does not start
The script manager is implemented as a separate process, and is required for normal server operation. The Design Tool and the Session Server each require a separate instance of the script manager, and the handling of script manager problems in each case differs.
Startup
-
Session Server - If the script manager fails to start when the Session Server starts, the Session Server writes an error log message and exits.
-
Design Tool - If the script manager fails to start with the Design Tool, a dialog box will indicate that the script manager failed to start. The Reset needed icon will also be displayed on the Design Tool status line.
Runtime
-
Session Server - If the script manager fails at some time after startup, the Session Server will:
- Log an error message describing the problem.
- Terminate any sessions and models that need script manager services.
- Refuse new client connections.
- Wait up to 60 seconds for existing client connections to terminate.
- Exit to the operating system. The exit status will indicate "normal termination" so that systems that can restart services will do so.
-
Design Tool - If the script manager fails after having started successfully, the Design Tool will display a Reset Needed indicator on the status line. This condition may occur as part of a debugging process. Operations that require communication with the script server will display a message indicating that the operation is being aborted because the script manager is not available and must be reset.
Java startup synchronization problems
For a given model, all JAR files or in the scripts\lib
directory will be introspected for available event handlers using the Java reflection API, an introspection utility for Java classes. JAR files that do not contain event handler classes can be placed on the user class path, not in the model's scripts\lib
directory, to avoid the overhead of introspection. Introspecting more than 1 MB of JAR files in the model's event handler directory may cause startup synchronization problems.
NET Runtime errors result from crossing domain boundaries
When using .NET Event Handlers, objects you store and retrieve from VHI contexts must be made effectively serializable due to the .NET remoting that occurs over application domains.
The script server dynamically loads and unloads the event handler classes using an Application Domain. In the event handler API, you can store arbitrary objects in six contexts: host session, client session, model context, RecordSet, Record, RecordLocation. Each of these expose Set...StateObject, Get...StateObject, and Is...StateObject methods. The values that you pass to these Set...StateObject methods cross from the event handler AppDomain to the script server AppDomain. Later, if you use Get...StateObject, the value passes back to the event handler AppDomain.
If you store an object using these methods, you could see an exception similar to these:
[VHI 4309] An unhandled System.Runtime.Serialization.SerializationException exception occurred in the
abbreviations.LifeCycleHandler.ModelLoaded() event handler: Type 'yourType' in
Assembly 'example, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.
[VHI 4309] An unhandled System.IO.FileNotFoundException exception occurred in the
abbreviations.LifeCycleHandler.ModelLoaded() event handler: Could not load file or
assembly 'example, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its
dependencies. The system cannot find the file specified.
These exceptions occur because the Common Language Runtime uses remoting to pass values between AppDomains. All values must either be serializable or a reference (a subclass of MarshalByRefObject). Follow the guidelines below to avoid this problem:
- Types that are built in to .NET, such as integers and strings, and collections of those types, such as a list of strings, can be stored without a problem, since they are inherently serializable.
- Third-party types that are serializable can be used, but the definition of the class must be known on both sides. The assembly for the serializable class must be in both the model's
scripts\lib
and in the%VHI_ROOT%\lib\dotnet\
folder. A class that is defined inside your vhi_model.dll can never be succesfully serialized, because the assembly name is the same for all models. - Types that are a subclass of MarshalByRefObject can be used. To prevent the object from being handled prematurely for garbage collection, you will may need to override the InitializeLifetimeService(). It is possible to define a subclass of MarshalByRefObject inside your vhi_model.dll. This approach is demonstrated in the Abbreviations example.
- You can avoid the problem by creating a static member or singleton object inside your event handler code to store your state.
- When using mutable serializable objects, remember that changes made to the original object are not reflected in the remote copy. Refresh the copy after changing your original, or use a MarshalByRefObject if you need mutable semantics.
- Exceptions are also objects, and throwing a third-party exception in an event handler might seem likely to produce a SerializationException here as well. However, in the case of exceptions, there is a catch clause in the event handler AppDomain that prevents the SerializationException. This catch clause translates the exception into a special ApptrieveException, which is serializable and known on both sides.
Model is not recognizing source files for imported event handlers
You can import event handlers from another model. Copying the source files requires a rebuild so that they can be added to the model JAR file.
Deployment error with saved model
Resave a model if you make changes to one or more of the event handler files in the model package, even though you have not made changes to the model itself. Reload the model in the Design Tool, validate, and then save the model and redeploy or re-create the package for deployment. Event handler files are automatically included when you deploy a model.
Problems with Web Builder application's event handlers for recordsets and attributes
If you use Web Builder to create web applications, there are limitations on recordset and attribute event handlers.