|
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...
|