We use InstallAnywhere to create installers. Recently an installer created using it started failing with StackOverFlow error (in silent installation).. Error stack has thousands of lines like below.
java.lang.StackOverflowError
at com.zerog.ia.installer.util.VariableManager.substitute(Unknown Source)
at com.zerog.ia.installer.util.VariableFacade.substitute(Unknown Source)
at com.zerog.ia.installer.util.VariableFacade.substitute(Unknown Source)
at com.zerog.ia.installer.util.magicfolders.MagicFolder.getPath(Unknown Source)
at com.zerog.ia.installer.util.magicfolders.MagicFolder.toString(Unknown Source)
at com.zerog.ia.installer.util.VariableManager.getValueOfVariable(Unknown Source)
at com.zerog.ia.installer.util.IAVariableStringResolver.getValueOfVariable(Unknown Source)
at com.zerog.ia.installer.util.VariableManager.substitute(Unknown Source)
VariableManager.substitute is very common API, it takes a string argument and return substituted(evaluted) value. How can I see the argument passed to it in the real JVM process?
The solution was to use a btrace script.
The installer process is Java process that can be queried by JVM tools like (jps, jstack)
Copy following btrace script to btrace console
package com.sun.btrace.samples;
import com.sun.btrace.BTraceUtils;
import com.sun.btrace.Profiler;
import com.sun.btrace.annotations.*;
import com.sun.btrace.*;
@BTrace class Profiling {
@Property
Profiler swingProfiler = BTraceUtils.Profiling.newProfiler();
@OnMethod(
clazz="com.zerog.ia.installer.util.VariableFacade",
method="/.*substitute.*/")
void entry( String probeMethod) {
BTraceUtils.print("Entry" );
BTraceUtils.println(BTraceUtils.timestamp() );
BTraceUtils.println(probeMethod);
}
@OnMethod(
clazz="com.zerog.ia.installer.*",
method="/.*/")
void entry2( @ProbeMethodName(fqn=true) String probeMethod ) {
BTraceUtils.print("Entry" );
BTraceUtils.println(BTraceUtils.timestamp() );
BTraceUtils.println(probeMethod);
}
@OnMethod(clazz = "com.zerog.ia.installer.*", method = "/.*/", location = @Location(Kind.RETURN))
void onPrepareReturn(AnyType arg) {
if (arg != null) {
BTraceUtils.println(arg);
}
}
}
Start btrace by clicking "start" icon.
Watch output for logs.
Btrace is extremely powerful tool to quickly check inside the JVM. Checkout more at Btrace Kenai project
Edit-comment from @J.B Btrace is now at github