How to Correlate Scripts - Java Scripts - Serialization

In RMI and some cases of CORBA, the client AUT creates a new instance of a Java object using the java.io.serializable interface. It passes this instance as a parameter for a server invocation. In the following segment, the instance p is created and passed as a parameter.

// AUT code:
java.awt.Point p =  new java.awt.Point(3,7); 
map.set_point(p);

The automatic correlation mechanism is ineffective here, since the object did not return from any previous call. In this case, VuGen activates the serialization mechanism and stores the object being passed as a parameter. It saves the information to a binary data file under the user folder. Additional parameters are saved as new binary data files, numbered sequentially. VuGen generates the following code:

public class Actions {
  // Public function: init 
      public int init() throws Throwable {
          java.awt.Point p = (java.awt.Point)lr.deserialize(0, false);
          map.set_point(p);
      }
}

The integer passed to lr.deserialize represents the number of binary data files in the Vuser folder.

To parameterize the recorded value, use the Java setLocation method (for information, see https://docs.oracle.com/en/java/). The following example uses the setLocation method to set the value of the object, p.

public class Actions {
  // Public function: init 
      public int init() throws Throwable {
          java.awt.Point p = (java.awt.Point)lr.deserialize(0, false);
          p.setLocation(2,9);
          map.set_point(p);
      }
}

In certain instances the public method of setLocation is not applicable. As an alternative, you can use the API of your class that incorporate get or set accessor methods. If you are working with AUT classes that do not have get/set methods or use private methods, or if you are unfamiliar with the classes' API, you can use VuGen's built-in serialization mechanism. This mechanism allows you to expand objects in their ASCII representation and manually parameterize the script. You enable this mechanism in the Recording Options dialog box. For details, see Recording Properties > Serialization Options - Recording Options.

VuGen generates an lr.deserialize method that deserializes the data or displays complex data structures as serial strings. Once the structure is broken down to its components, it is easier to parameterize. The lr.deserialize method receives two arguments, a string and an integer. The string is the parameter's value that is to be substituted during replay. The integer is the index number of binary file to load.

If you choose not to expand objects in your script by clearing the Unfold Serialized Objects check box, you can control the serialization mechanism by passing arguments to the lr.deserialize method. The first argument is an integer indicating the number of binary files to load. The second integer is a boolean value:

true
Use VuGen's serialization mechanism.
false
Use the standard Java serialization mechanism.

The following segment shows a generated script in which the serialization mechanism was enabled.

public class Actions {
  // Public function: init 
      public int init() throws Throwable {
          _string = "java.awt.Point __CURRENT_OBJECT = {" +
                     "int x = "#5#" +
                     "int y = "#8#" +
          "}";
          java.awt.Point p = (java.awt.Point)lr.deserialize(_string,0);
          map.set_point(p);
      }
}

The string values are placed between delimiters. The default delimiter is "#". You can change the delimiter in the Serialization tab of the recording options. Delimiters are used to speed up the parsing of the string during replay.

When modifying the string, you must maintain the following rules:

  • Order of lines may not be changed. The parser reads the values one-by-one—not the member names.

  • Only values between two delimiters may be modified.

  • Object references may not be modified. Object references are indicated only to maintain internal consistency.

  • "_NULL_" can appear as a value, representing the Java null constant. You can replace it with string type values only.

  • Objects may be deserialized anywhere in the script. For example, you can deserialize all objects in the init method and use the values in the action method.

  • Maintain internal consistency for the objects. For example, if a member of a vector is element count and you add an element, you must modify the element count.

In the following segment, a vector contains two elements:

public class Actions {
  // Public function: init 
      public int init() throws Throwable {
          _string = "java.util.Vector CURRENTOBJECT = {" +
                     "int capacityIncrement = "#0#" +
                     "int elementCount = #2#" +
                     "java/lang/Object elementData[] = {" +
                            "elementData[0] = #First Element#" +
                            "elementData[1] = #Second Element#" +
                            "elementData[2] = _NULL_" +
                             ....
                            "elementData[9] = _NULL_" +
                     "}" +
          "}";
          _vector = (java.util.Vector)lr.deserialize(_string,0);
          map.set_vector(_vector);
      }
}

In the following example, one of the vector's elements was changed—a "_NULL_" value was changed to "Third element". In coordination with the addition of the new element, the elementCount member was modified to 3.

public class Actions {
  // Public function: init 
      public int init() throws Throwable {
          _string = "java.util.Vector CURRENTOBJECT = {" +
                     "int capacityIncrement = "#0#" +
                     "int elementCount =  #3# " +
                     "java/lang/Object elementData[] = {" +
                            "elementData[0] = #First Element#" +
                            "elementData[1] = #Second Element#" +
                            "elementData[2] =  #Third Element#" +
                              ....
                            "elementData[9] = _NULL_" +
                     "}" +
          "}";
          _vector = (java.util.Vector)lr.deserialize(_string,0);
          map.set_vector(_vector);
      }
}

Due to the complexity of the serialization mechanism, which opens up the objects to ASCII representation, opening large objects while recording may increase the time required for script generation. To decrease this time, you can specify flags which will improve the performance of the serialization mechanism.

When adding lr.deserialize to your script, we recommend that you add it to the init method—not the action method. This will improve performance since VuGen will only deserialize the strings once. If it appears in the action method, VuGen will deserialize strings for every iteration.

Back to top