1

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?

Jayan
  • 18,003
  • 15
  • 89
  • 143

1 Answers1

1

The solution was to use a btrace script.

The installer process is Java process that can be queried by JVM tools like (jps, jstack)

  1. Install JDK (JVisualVM comes with it)
  2. Start VisualVM and Install btrace plugin

enter image description here

  1. Right click on process (LAX) Start 'btrace'

enter image description here

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. enter image description here

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

Jayan
  • 18,003
  • 15
  • 89
  • 143
  • FYI: The active BTrace project location is GitHub (https://github.com/jbachorik/btrace) – JB- Aug 31 '15 at 17:40
  • :) and that is yours? – Jayan Sep 01 '15 at 02:58
  • Well, both are mine :) It's just that Kenai.com is really not supported anymore and I decided to move the project to GitHub not to become marooned when they decide to pull the plug. – JB- Sep 01 '15 at 08:53
  • @ J.B: Great. your btrace is a super-cool and super-useful for any Java developer.. – Jayan Sep 01 '15 at 09:15
  • @ J.B: I guess my answer is not complete. If you can provide an answer for "how to print all argument" that will make this page more useful. I will then change the answer to yours.. – Jayan Sep 01 '15 at 11:04