[Soot-list] Can't find java.lang.Error

John Jorgensen jorgnsn at lcd.uregina.ca
Sun Feb 12 00:44:30 EST 2006


>>>>> "mfh02" == Marc Hull (Imperial College) <mfh02 at doc.ic.ac.uk> writes:

    mfh02> I've got some code which examines the concrete methods
    mfh02> of a class and all superclasses, but it always throws
    mfh02> a NullPointerException when retrieving the active body
    mfh02> of Object.wait(long, int). This can be recreated
    mfh02> using:

    mfh02>         SootClass sClass = 
    mfh02> Scene.v().loadClassAndSupport("java.lang.Object");
    mfh02>         for (Object o : sClass.getMethods()) {
    mfh02>             SootMethod method = (SootMethod)o;
    mfh02>             if (method.isConcrete()) {
    mfh02>                 System.out.println(method.getSignature());
    mfh02>                 Body b = method.retrieveActiveBody();   // fails here
    mfh02>             }
    mfh02>         }
    .
    .
    .
    mfh02> Is this a bug or am I missing some initialisation step which 
    mfh02> will load the class automatically?

I'm not certain exactly what's going on in your original code,
but in the short example you've provided to reproduce the error,
the problem is indeed the absence of initialisation to load some
classes that Soot needs in order to analyze any code.

I'm not an expert on all the initializations that need to be
performed when using Soot as a library in another application,
rather than via the Soot command line, so I won't try to explain
exactly what's going on, but instead refer you to a previous
thread on soot-list, and to two documents mentioned in that thread:

 http://www.sable.mcgill.ca/pipermail/soot-list/2005-March/000172.html
 https://svn.sable.mcgill.ca/wiki/index.php/ClassResolver
 https://svn.sable.mcgill.ca/wiki/index.php/ClassResolverFAQ

Using information on the two wiki pages, I was able to get your
example to work by changing it to:

  public static void main(String[] args) {
    Scene.v().addBasicClass("java.lang.Object", SootClass.BODIES);
    Scene.v().loadNecessaryClasses();
    SootClass sClass =
      Scene.v().getSootClass("java.lang.Object");
    for (Object o : sClass.getMethods()) {
      SootMethod method = (SootMethod)o;
      if (method.isConcrete()) {
      System.out.println(method.getSignature());
      Body b = method.retrieveActiveBody();   // fails here
      }
    }
  }

Depending on what you're doing, it might be easier to write your
code as a new transformation, adding that to some soot "pack",
and then having your application's main() method call
soot.Main.main().  The implementation of soot.tools.CFGViewer
provides a fairly simple application of that technique to add a
BodyTransformer that will get called for each method
processed. I'm not sure if it is possible to add a new
SceneTransformer without modifying soot.PackManager, though.



More information about the Soot-list mailing list