[includes/hd_aprobe5-examples.htm]
Aprobe 5

10. How can I force a Java method to return a particular value?

This example shows how to create a probe on a Java method, and use its
ON_EXIT action to return a different value to the method's caller instead of
what the method would otherwise return.

The mechanism is to subclass a ProbeMethod and override its onExit
method, which returns the desired value instead.


The probe: ReturnValueProbe.java
--------------------------------------------

import com.ocsystems.probe.*;

/* A probe to modify the return value. */

public class ReturnValueProbe extends ProbeMethod
{
   /**
    * On exit we will set scalar return values to have a different value. 
    */
   public Object onExit(Object r)
   {
      // This is a generic probe that handles all the
      // various cases for testing purposes.  A real probe
      // would probably just handle the single case of the 
      // return type of the method to which it is applied.
      //
      Object returnValue = r;
      
      System.out.println("onExit return value = " + r);
      
      if (r == null)
      {
         // Nothing.
      }
      else if (r instanceof Byte)
      {
         returnValue = new Byte((byte)(((Byte)r).byteValue() + 1));
      }
      else if (r instanceof Character)
      {
         returnValue = new Character((char)(((Character)r).charValue() + 1));
      }
      else if (r instanceof Integer)
      {
         returnValue = new Integer(((Integer)r).intValue() + 1);
      }
      else if (r instanceof Long)
      {
         returnValue = new Long(((Long)r).longValue() + 1);
      }
      else if (r instanceof Float)
      {
         returnValue = new Float(((Float)r).floatValue() + 1.0);
      }
      else if (r instanceof Double)
      {
         returnValue = new Double(((Double)r).doubleValue() + 1);
      }
      // Don't do anything to Objects.

      System.out.println("onExit new return value = " + returnValue);

      return returnValue;
   }
}


Main test: ReturnValueTest.java
-------------------------------

import java.io.*;

class ReturnValueTest
{
   // All these methods will have their return value modifed.
   
   private static byte getByte()
   {
      return 1;
   }
   
   private static char getChar()
   {
      return 1;
   }
   
   private static int getInt()
   {
      return 1;
   }
   
   private static long getLong()
   {
      return 1;
   }
   
   private static float getFloat()
   {
      return (float)1.0;
   }
   
   private static double getDouble()
   {
      return 1.0;
   }
   

   public static void main(String[] args)
   {
      try 
      {
         System.out.println("byte   = " + getByte());
         System.out.println("char   = " + getChar());
         System.out.println("int    = " + getInt());
         System.out.println("long   = " + getLong());
         System.out.println("float  = " + getFloat());
         System.out.println("double = " + getDouble());
      }
      catch (Exception e)
      {
         e.printStackTrace();
      }
   }
}


Probe deployment (XML) file:
----------------------------------

<!--
   A deployment for a method probe that modifies method return values.
-->
<probe_deployment>
  <probe class="ReturnValueProbe">
    <target value="ReturnValueTest::get*"/>
  </probe>
</probe_deployment>


Configuration file for test (cfg.persistent):
---------------------------------------------

verbose
persistent:ReturnValueProbe.jar,44,ReturnValueProbe,enable


Compile the test program to create ReturnValueTest.class:
---------------------------------------------------------

javac -g -source 1.3 ReturnValueTest.java


Compile the probe to create ReturnValueProbe.class, put into a jar:
-------------------------------------------------------------------------------

javac -g -source 1.3 -classpath $PROBE_PATH:. ReturnValueProbe.java
jar cMvf ReturnValueProbe.jar ReturnValueProbe.xmj ReturnValueProbe.class


The result:
-----------

Run the ReturnValueTest program with ReturnValueProbe applied to it.
	
java $(JVMFLAGS) -classpath $(RUN_CLASSPATH) ReturnValueTest

(I) Starting the application...
(I) Installing probe module "ReturnValueProbe.jar"...
(I) Installed probe module "ReturnValueProbe(44)".
(I) Enabling probe module 44...
(I) Loading probe XML "/tmp/spj-23352/ReturnValueProbe.xmj" for "ReturnValueProbe(44)"...
(I) Adding probe bean "<anonymous>"(0)".
(I) Adding probe "ReturnValueProbe" to bean "0".
(I) Loaded probe XML "/tmp/spj-23352/ReturnValueProbe.xmj" for "ReturnValueProbe(44)"
(I) Adding probe class "ReturnValueProbe" to classpath for "ReturnValueProbe(44)...
(I) Enabling probe bean "com.ocsystems.probe.ProbeBean(0)" for "ReturnValueProbe(44)"...
(I) Enabled probe module "ReturnValueProbe(44)".
(I) Started server command thread: pid 23352, read /tmp/wrdjreq-23352, write /tmp/wrdjres-23352
(I) Activate Class Cache for pid 23352.
(I) Created class cache directory /tmp/spj-23352/cc
(I) Class Cache activated for pid 23352
onExit return value = 1
onExit new return value = 2
byte   = 2
onExit return value = 1
onExit new return value = 2
char   = ^B
onExit return value = 1
onExit new return value = 2
int    = 2
onExit return value = 1
onExit new return value = 2
long   = 2
onExit return value = 1.0
onExit new return value = 2.0
float  = 2.0
onExit return value = 1.0
onExit new return value = 2.0
double = 2.0
(I) Shutting down the application...