Reputation: 18468
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?
Upvotes: 1
Views: 749
Reputation: 18468
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
Upvotes: 2