JDK instrumentation background

Introduced in QF-Test version 1.07, instrumentation of the JDK or JRE on which the SUT will run is now the primary method of providing a way for QF-Test to interact with the SUT. This chapter explains the technical details of what's going on behind the scenes when the JDK is instrumented and when the SUT is started in an instrumented JDK.

3.1.4+ Normally you don't need to instrument standard JDKs because QF-Test passes the same information to the SUT's JDK via environment variables. However, for special cases instrumentation may be required anyway and the information in this chapter is still valid.

Modifications to the JDK

When Instrumenting the JDK, QF-Test makes use of the official accessibility interface which is provided by Java for just this purpose. It can be used by accessibility and capture replay tools to interact with Java applications without those applications knowing about it and without requiring any changes to those applications.

To activate this interface, QF-Test creates or modifies the file .../lib/ in the JDK installation and adds the class de.qfs.apps.qftest.start.Connector to the property "assistive_technologies". This has the effect that this class will be instantiated whenever the AWT toolkit is initialized in any Java application or applet that is run in this Java VM.

To make sure that this class can always be found without modifications to the CLASSPATH, the file qfconnect.jar, which contains the Connector class, is placed in the Java extensions directory .../lib/ext.

When de-instrumenting the JDK, QF-Test first removes its entry from the assistive_technologies property in so the Connector class will no longer be used. Next QF-Test tries to remove qfconnect.jar from the .../lib/ext directory. On Windows systems this will not work if QF-Test is running inside the same Java VM, so the file should be removed by hand. However, this is not essential because it won't affect the JDK in any way after has been updated.

Effects of the instrumentation

When the class de.qfs.apps.qftest.start.Connector is instantiated during AWT toolkit initialization of a Java application, the first thing it does is check whether the application was launched by QF-Test, i.e. whether it is a System Under Test or a plain application. In the latter case, the connector terminates immediately and doesn't affect the application in any way.

In case of an SUT, the connector sets up a special class loader that will load the classes required for QF-Test's SUT wrapper, then set up and initialize that wrapper which will finally connect to QF-Test over RMI, just as the old wrapper used to.

This technique differs from the old technique of modifying the SUT's command line in a number of subtle ways:

  • The SUT process is launched directly by QF-Test without interim qfclient and java envelopes.
  • The classes of the QF-Test wrapper around the SUT are all loaded through the special class loader, so they are separated completely from the SUT's classes. So even if the SUT uses some software that QF-Test also uses and the required versions differ, this shouldn't cause any problems.
  • The class loader automatically ensures that the QF-Test wrapper has all the necessary permissions. No explicit permission grants or changes to the policy file are required.
  • This technique makes it possible to test applications launched directly from an executable file. Java WebStart based applications can be tested without the need to modify jnlp files and even applets that run in the Java plugin inside a web browser.