Project

General

Profile

Running the Client

Introduction

The client can be launched from command line in the installation directory using a command such as this:

java -XX:+HeapDumpOnOutOfMemoryError -Djava.library.path=../lib/ -classpath ../lib/p2j.jar::../lib/*.jar com.goldencode.p2j.main.ClientDriver net:server:host=localhost net:connection:secure=true net:server:secure_port=3333 client:driver:type=gui_swing deploy/client/client.xml

Assumming that java binary directory is added to PATH operating system environment variable, all client binaries reside into current directory and the server is running on the standard port on local machine. Because of the multitude of application options and JVM parameters usually the client application is launched by a shell script named client.sh that automates the client's startup. The sample projects have deploy/client/client*.sh examples that simplify the execution. The scripts handle all JVM command-line parameters detailed below and also the FWD parameters and options.

JVM Command Line Parameters

The JVM can be customized to load and fit the needs of the running client application. The general syntax for launching the client application is:

java [jvm_options] com.goldencode.p2j.main.ClientDriver [parameters_and_options]

where:

  • jvm_options - command line options given to the JVM to define the parameters in which the JVM will function and additional features
  • com.goldencode.p2j.main.ClientDriver is the application's main class,
  • parameters_and_options - arguments passed to the FWD client (ClientDriver.main() method)

CLASSPATH Setup

To be able to load the application JVM needs to know how to find the various FWD .jar files. The FWD client code is packaged in the p2j.jar file. This archive MUST be added to JVM's class path in order to be loaded:

-classpath <relative_path_to>/p2j.jar

That p2j.jar file has a manifest which automatically adds its .jar file dependencies at runtime. This means that the other .jar files on which it depends need to be in the same location as the p2j.jar.

Native Library Location Setup

As the client loads native compiled code using JNI, it must have access and be informed where libp2j.so (or p2j.dll on Windows) shared library is located. The Java environment variable java.library.path is used to specify the location. By default java.library.path is uninitialized so it must be explicitly added to command line using -Djava.library.path parameter.

Heapsize

In order to load the application, the JVM has to know how much memory to reserve. The default heap size in JVM 6 is 25% of the amount of free physical memory in the system. Most ChUI clients can run in 16MB or 32MB. GUI clients will need 64MB or 128MB. Use a heap which is large enough to fit the application but try to keep it as small as possible. A heap that is too large will cause longer garbage collection pauses because there is more heap to scan. If the session is going to be long running, then it is a good practice to enable the java "server" compiler. This trades usage of a little more memory and a small startup delay in exchange for faster performance.

If the JVM runs out of memory you can increase the heap size to compensate (assuming it is not a memory leak in teh FWD code). To capture a heap dump for later analysis and debugging use -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError='./stack_dump.sh %p'.

Debugging the Application

To enable source level debugging add the following to the command line:

-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=2080,server=y,suspend=n

After the process has started you can use a debugger to attach to the running process on port 2080. If you want to debug the very early FWD client startup process, then set suspend=y.

Command Line Syntax and Options

The syntax accepted by the client is the following:

java ClientDriver [-?] [config1 [-p config1_file_password]] [config2 [-p config2_file_password]] [-d initial_debug_level] [parameter_overrides]

Each line is optional and is detailed in the next table:

Parameter Description
-? Displays the help screen (including syntax and a brief description).
If present, it must always be the first and any other argument is ignored.
config_1 The (relative or absolute) file path to first bootstrap configuration file. May be in xml/plain text format or encrypted for advanced security. Please see the “Bootstrap Configuration” chapter for details.
config_1_file_password The password to use to decrypt the first bootstrap configuration if file is encrypted. Use '?' to force an interactive password prompt.
config_2 The (relative or absolute) file path to second bootstrap configuration file if using a split bootstrap configuration.
config_2_file_password The password to use to decrypt the second bootstrap configuration if file is encrypted. Use '?' to force an interactive password prompt.
initial_debug_level An integer value that specifies the logging level that should be used before server's main configuration (in the directory) can be read
parameter_overrides Configuration values that add to or replace values that can be specified in the bootstrap configuration; the override must take one of three forms:
     category:group:key=value
     group:key=value
     key=value
The shorter forms will use the most recently specified category and/or group as needed. See the “Bootstrap Configuration” chapter for details.

All arguments can be specified in any order except -? which must always appear first. The first password (if specified) will be used with
the first config file specified and likewise with the second password and config file respectively.

Client Logging and Output

When running in application mode, the output of the client application can be captured and redirected to a log file. The devices STDIN or STDOUT cannot be used for redirection because the output will interfere with the console CHUI driver. So the proper way of capturing the application log to a file is using STDERR.

The sample shell script client.sh uses $P2J_LOG_DIR environment variable to locate the destination where log files will be placed. The name of an individual file will be client_<userid>_<pid>.log where the <userid> is found via the program whoami and the pid is the process ID of the shell process.

The log output is enabled by application's configuration boolean item logging:debug:enable, the verbosity level is found on server and until retrieving it the value of -d application value is used. Enable this settings only for debugging sessions as it is very verbose and this can slow down a production installation.

Client Drivers

As mentioned earlier in the “Client Installation”:/projects/p2j/wiki/Client_Installation chapter, the client can be started using:

  • ChUI Clients
    • native ChUI terminal emulator driver
    • Swing ChUI driver
    • Web ChUI driver
  • Batch Client
  • GUI Clients
    • Web GUI driver
    • Swing GUI driver

Selecting the appropriate driver can be done in the client's bootstrap configuration file or by a bootstrap configuration override parameter (see parameter_overrides above).

ChUI Clients

There are 3 interactive ChUI clients.

Native CHUI Client

The native CHUI driver is fully compliant with original 4GL user interface. The main advantage of this ChUI driver is that it is the only solution for customers that still use hardware terminals. This is the default setting. If you want to explicitly configure the client application set the client:driver:type = chui_native as the bootstrap configuration value. In the sample Hotel ChUI project this is used in the deploy/client/client-terminal.sh shell script. Use this client when running on a remote server via ssh or telnet.

Running the Swing CHUI Driver

This provides a Swing-based CHUI client as an alternative to using the native CHUI client. This non-native client "driver" is fully functional with only minor limitations. It works great for FWD testcases and even works well for larger applications! The Swing client starts a standalone JVM process that accesses the graphical desktop of the user's system. This means you cannot use it on servers accessed via ssh or telnet since you can't start an X session for Swing there! But it will work great on your local system.

For the this driver, use the client:driver:type=swing_chui_frame bootstrap configuration value.

Web ChUI Client

The character mode (ChUI) web client can be accessed from any browser supporting HTML5, Web Sockets and AJAX requests. Details about these clients (setup, configuration, installation) can be found in the dedicated Web Client Setup chapter of this book.

Batch Process Clients

The batch process clients are FWD clients which mimic the legacy batch program behavior. These clients are allowed to be started in the same way as the legacy batch program was started; this includes:

  • runtime awareness if the standard INPUT/OUTPUT was redirected
  • configuration to set the client in “background” mode, via the client:driver:background@=true@ bootstrap configuration. This setting will allow a FWD client to act the same way as a legacy batch program for which its associated system process is in background.

Technically, this is really just a non-interactive ChUI client. For all batch programs, it is needed to set the client:mode:batch=true configuration and the client's driver also needs to always be set to client:driver:type=chui_batch.

A batch process can also be ran via the ServerDriver's -b <process-id> argument, with a command like:

java com.goldencode.p2j.main.ServerDriver -b <process-id>

TBD: document how to specify the process_id value.

In this case, the runtime will take care of automatically setting the batch mode and the driver type, to the appropriate values. For the setup needed to use this feature, see the Spawner Setup and Configuration chapter of this book.

GUI Clients

There are 2 interactive GUI clients.

Web GUI Client

TBD

Swing GUI Client

TBD

Accessing Environment Variables

Some 4GL programs read environment variables and act accordingly. FWD does provide access to the environment variables set into the process environment when it is launched. These can be read using OS-GETENV() just as in the 4GL. In addition, if an environment variable is not found in the native process environment, then FWD will read the Java system properties to see if a property of the same name exists. If this is needed the original environment variables must be known in advance and should be coded as properties on the JVM command line using -D<environment_var_name>=<value> as in:

java -DTOOL_CHAIN=/opt/something/tool ...

Here the $TOOL_CHAIN variable is 'passed' set as a system property in the JVM in order to be accessible by the converted application.

Connecting to the FWD Server

The client is only a 'thin' presentation engine. It does not contain any code converted from the original 4GL application. To execute the code, the client connects to the FWD Server where the converted 4GL code executes. As usual in a multi-tier system, to connect to a server the client side needs to know the host on which the server application is running and the port it has open to accept connections. Another important thing in communication is the protocol, in this case we have two cases: insecure and SSL-secured connections.

On the client side, these connectivity settings are provided as bootstrap configuration values.

  • net:server:host (hostname or IP address of the server, defaults to localhost)
  • net:server:secure_port (SSL port of the server)
  • net:server:insecure_port (non-SSL port of the server)
  • net:connection:secure (true to use SSL, false to use non-SSL)

Here is an example:

java ... com.goldencode.p2j.main.ClientDriver net:server:host=localhost net:connection:secure=true net:server:secure_port=3333 ...

The sample project client.sh scripts hide this calculation using a concept of a "server instance number":#server-instance-number-support.

In order to use a secured connection a certificate is needed by the SSL handshake protocol between the client and server. See the security dedicated chapters (Certificate Authority, Loading Known Certificates, Key-Stores and Trust-Stores, Cryptography Setup Helper) for more informations on this topic. Depending on how the certificates are configured, this information needs to be added to the bootstrap configuration file:

TBD: show an example here.

For increased security the bootstrap configuration file that contains the passwords should be encrypted (see the Bootstrap Configuration chapter for this topic).

Any security configuration set in the bootstrap configuration will override the directory's security configuration (related to private keys, trust-store and encryption password for these private keys).

Server Instance Number Support

On systems where multiple application server instances will be started, the server.sh and client.sh use the concept of a "server instance number". Each FWD server process will get an “instance number” from 0 to 9. This number is used to assign a different port for each server instance. The startup scripts use the value for the secure port which would be defined by either a -i<instance_num> parameter or the -p<port> parameter. The -i might calculate the secure port as 3333 + the <instance_number>. The -p might calculate the secure port as equal to <port>. Once the secure port is known the insecure port will be calculated by adding or subtracting some number to the secure port.

To connect to a given FWD server, the client.sh is passed the instance number using the -i parameter. See the “Running the Server”:/projects/p2j/wiki/Running_the_Server chapter for details on this concept.

If the server does not request any kind of authentication then the application code will be executed as soon as the client session is created. If the server is configured with authentication by password the client will prompt you for your username and password before proceeding with running the actual application:

Entering a correct set of credentials will allow you to continue and run the application while entering a bad combination will quit the process.

Another kind of authentication is based on security certificates. If configured so, the server will only accept clients that have valid certificated and added to bootstrap configuration file(s). As this does not need the user to enter a password, it is well suited for batch programs that run in background periodically (E.g. a daily task that might be scheduled to run each day, at a fixed time using cron daemon). Special care must be taken here as the daemon might run under different credentials and the respective user must have needed needed permissions to read the application's binary files, write logs and other streams and, of course, open two-way communication with the server.

Stopping interactive clients is done using CTRL+C keystroke combination. However, if the 4GL code contains some retry clauses the effect may be different, some loop structures may restart the last iteration or the entire application can be restarted. An alternative way of stopping any kind of clients is by terminating their session from within the administration applet (see the “Accessing the Administration Client” chapter) which will lead to end of the process too. Of course, there is always the option of using unix/linux kill command to stop such a process, and this is also the solution for stopping non-interactive clients that run in background and do not have a “visible” console.

Specifying the Startup Program

By default, the p2j-entry value associated with an account in the directory.xml will be the program that is executed when the ClientDriver starts its session with the FWD Server. This value might be set as a default for all clients using /server/default/runtime/default/p2j-entry or it might be set at a group or per-account level. The value would be in the form of com.acme.myapplication.module.SomeConvertedProgramName.execute. This means that the fully qualified converted Java class name needs to be known.

There is also an easy way to override this on the command line using bootstrap configuration value client:cmd-line-option:startup-procedure. The value is specified as the 4GL program name relative to the legacy propath. If some/path/my-program.p can be found in the propath on the legacy system, then client:cmd-line-option:startup-procedure=some/path/my-program.p would work in FWD. This assumes that you have configured the propath in the directory.xml so that the converted code can be mapped properly. See 4GL Runtime Compatibility for more details about the propath.

Job Control and FWD Client

In environments where interactive shells provide job control, some special care should be taken when providing custom shell scripts that launch FWD clients. An example of such an environment is the bash shell on Linux. The job control feature makes it possible to stop the client process at an arbitrary (user-specified) time by typing CTRL-Z on the terminal. The operating system suspends the FWD client process and the bash shell regains control, which would differ from a typical Progress environment. Below is the explanation of when and why this may happen and how to avoid it.

When CTRL-Z is typed in the terminal, bash, being the parent of the client JVM process, receives a SIGTSTP signal from the tty driver in the kernel, if the controlling terminal is not in “raw” mode. The kernel sends this signal to all processes in the foreground process group in the bash session. bash itself is in the group.

Under normal conditions, the FWD client will have set the controlling terminal into raw mode. When in raw mode, the SIGTSTP signal is not sent and there is no problem. However, every time the JVM launches an interactive child process, the terminal is restored to the regular “cooked” mode. If the user presses CTRL-Z while interacting with this child process, the kernel will generate the SIGTSTP signal.

In response, the JVM safely ignores the signal. Unfortunately, bash still receives the signal and then performs a "service" for us. It reacts to the signal by sending the SIGSTOP signal to the current processes in the foreground job. This latter signal cannot be caught, blocked or ignored. Thanks to bash, the JVM process stops unconditionally and bash displays the command prompt.

Disengaging the JVM from the parent bash won't help, since bash would display the command prompt immediately and the user would be able to interact with the same terminal in which the JVM is operating. This would create a situation where there is concurrent use of the same terminal, quickly resulting in screen corruption or hangs.

The solution is not to allow bash receive the SIGTSTP. One of the two known ways is the TRAP instruction. Another, more efficient way is to use exec to invoke JVM process instead of eval. This causes the parent bash to go away leaving no parent of the JVM process which can process the job control signals.

This issue only affects the NCURSES-based CHUI driver, since the swing-based driver does not run inside a terminal or shell environment.


© 2004-2021 Golden Code Development Corporation. ALL RIGHTS RESERVED.