35
Starting the SUT with the old connection mechanism

Note This chapter describes the old mechanism for connecting to the SUT from before QF-Test version 1.07. It should no longer be used except in case you cannot or do not want to instrument the JDK for some reason.

To accommodate different user needs there are several different ways to run an application from QF-Test. The ability to readily connect to your SUT will depend on the complexity of your application, the environment it needs, and upon whether you are on a Unix or Windows operating system.

Before you run QF-Test, make sure all environment variables your application needs are set correctly, especially CLASSPATH (but don't bother with QF-Test's jars). At least on Unix it is also a good idea to have the bin directory of your JDK on the PATH.

35.1
Four methods to start the SUT

Listed below are the four most common ways to start a Java application. Each of them is accompanied by a short description showing the steps to run the application from QF-Test.

Special variants of these methods used to launch an application with Java WebStart or an applet in the applet viewer are discussed in the following sections.

java -jar <archive>
Starting the SUT from a                    jar archive
Figure 35.1:  Starting the SUT from a jar archive
java -classpath <class-path> <starter-class>
Starting the SUT via the                    main class
Figure 35.2:  Starting the SUT via the main class
A standalone script
Starting the SUT from a                    script
Figure 35.3:  Starting the SUT from a script
A standalone executable
This is tricky. Think of it as being a script that you cannot edit. Follow the instructions above and keep your fingers crossed. If the executable employs any of the methods that prevent it from connecting to QF-Test you'll have to resort to some other method.

If you got to the end of this section and your application still refuses to be run from QF-Test or doesn't connect, you should read section 35.5 in the reference manual which contains detailed information about what is going on behind the scenes when the SUT is started. You can also try do diagnose the problem by starting QF-Test with the -dbg argument. This causes not only QF-Test itself to print additional debugging output, but also the SUT, whose output you'll find in the terminal under the »Clients« menu (see section 4.4).

35.2
Starting an application through Java WebStart

Note The old connection mechanism does not work reliably with Java WebStart. If the SUT is Java WebStart based, following the instructions in section 4.3 is your only option.

35.3
Running an applet in the appletviewer

Note The following only works with JDK 1.3 and above.

This is a special case of a 'Start Java SUT client' node. Set the 'Directory' to the directory where your applet's HTML file resides and set the 'Class name' attribute to sun.applet.Main.

Next, switch to the Class tab of the 'Parameters' attribute and enter two values: -Xnosecurity and the name of your applet's HTML file.

The following image shows some example settings.

Running an applet in the appletviewer
Figure 35.4:  Running an applet in the appletviewer
35.4
Security

There is another issue that may require modifications to your setup. If your application employs a SecurityManager, you need to grant unrestricted system access to QF-Test's classes, otherwise you'll get a SecurityException when you launch the SUT.

To grant that access, you need to modify the policy file for your application. This file is typically passed to the application as a command line argument of the form -Djava.security.policy=.... You need to locate this file and modify it, adding the following lines:

grant codeBase "file:${qftest.home}/-" {
    permission java.security.AllPermission;
  };

Note You can use the literal ${qftest.home} when starting your SUT from a 'Start Java SUT client' node or when using the qfclient helper. Otherwise replace it with the full path to QF-Test's root directory. The "/-" at the end of the codeBase is important. A forward slash must be used as file separator even on Windows systems.

35.5
Background information

This chapter provides information about what is going on behind the scenes when the SUT is launched by QF-Test with the old connection mechanism. It explains why there are different methods to run your application and how they work.

To interact with the SUT, to capture and replay events, check the state of components etc., QF-Test needs unrestricted access to some parts of the Java virtual machine. This is handled by a small class that wraps the SUT and lays itself between the SUT and the Java VM. This wrapper-class replaces the system EventQueue with one of its own and sets up an RMI connection to QF-Test before executing the starter-class of the SUT.

One of QF-Test's goals is to run with all kinds of Java applications without requiring modifications to the SUT, so it needs to set up a special environment for the SUT to work in. When the Java command for the SUT is executed, QF-Test takes care that:

There are two common ways of running a Java application:

The first case doesn't pose any problems, while the second case can get difficult, because QF-Test has no information about the start script.

To solve this problem QF-Test uses an envelope for the java program, located in its bin/envelope directory. For Unix this is a shell script, for Windows there are two executable files, java.exe and javaw.exe. These by no means replace the standard Java application launchers since Sun's license doesn't allow that. They only parse and modify the command line arguments before passing them on to the actual java or javaw program.

To ensure that this envelope is actually run, QF-Test puts the bin/envelope directory as the first directory on the PATH on startup. This has an effect only on programs started by QF-Test. Though the java envelope is completely transparent when run outside of QF-Test, you shouldn't put the bin/envelope directory on the standard PATH.

There are situations in which the java envelope is not executed by the SUT even when it is run from QF-Test. For one thing, the starter script or program of the SUT can modify PATH itself, or execute a specific java program. On Windows there are also different ways to start a program, one of which searches the Windows system directory before checking PATH. If that method is used, the java.exe or javaw.exe in the system directory will be run instead of the envelope.

To work around that problem, QF-Test comes with another helper program called qfclient in its plain bin directory. This program expects the whole command line - including the java executable - that starts the SUT as arguments. All qfclient does is call QF-Test's java envelope, tell it about the true java executable to call and let it handle the rest.

So how does all of this fit together? For a simple application that is started directly through java, create a 'Start Java SUT client' node with the correct attributes. When the node is executed, QF-Test runs qfclient to start the SUT by way of the java envelope. This level of indirection has an additional benefit. qfclient is able to change the working directory before running the java envelope, so the 'Directory' attribute has an effect even for JDK versions before 1.3, that do not support this directly.

For a complex application that is started through a script the 'Start SUT client' node is provided. When the test is run, QF-Test executes the starter script or program directly, relying on the PATH setting to cause the java envelope to be executed. If your start script does modify the PATH or launch a specific java program, the effect is that the SUT will start up fine, but no connection between it and QF-Test will be established (the record button will remain disabled). In that case you'll need to modify the start script slightly. In the case of a binary starter program you'll need to go back to a 'Start Java SUT client' node.

To modify the script, first make a copy of it for use with QF-Test. Search the script for the line where the java program is started, e.g.

/usr/local/jdk1.3.1/bin/java -Duser.language=en some.package.MainClass
or
exec /usr/local/jdk1.3.1/bin/java -Duser.language=en some.package.MainClass

and change it to

qfclient /usr/local/jdk1.3.1/bin/java -Duser.language=en some.package.MainClass
or
exec qfclient /usr/local/jdk1.3.1/bin/java -Duser.language=en some.package.MainClass

Then change the 'Executable' attribute of the 'Start SUT client' node to refer to the modified script.

One question remains. How does QF-Test pass the additional arguments for the hostname, port number and client name to the wrapper-class? Java doesn't support environment variables and QF-Test can't modify the command line of a 'Start SUT client' node, since that would confuse the SUT's start script. Hence QF-Test makes use of the standard input and output channels of the application, which it controls anyway. It writes the extra arguments to the standard input of the of the SUT where they are read by the wrapper-class before execution is passed on to the SUT's starter class. That way conflicts are avoided, unless the start script of the SUT tries to read from standard input itself, which is very uncommon for a GUI application.

If you got to the end of this section and your application still refuses to be run from QF-Test you can try do diagnose the problem by starting QF-Test with the -dbg argument. This causes not only QF-Test itself to print additional debugging output, but also the qfclient program and the java envelope. If you are still stuck, it is probably time to ask for help.