This page is a draft; the content does not yet properly describe the current state of Soot. In particular some changes still need to be checked in to make it true.

This page is supposed to be a set of quick-and-easy answers to commonly asked questions about the Soot resolver. For more details, or if something doesn't make sense, see the full description at ClassResolver.

Q: Why are loadClass/loadClassAndSupport deprecated? What should I do instead?

A: The Soot resolver is designed to load classes only during a specific startup phase of Soot, predictably enough known as the "resolving" phase. As a result, users are discouraged from trying to load classes at arbitrary times. Given a call to loadClass or loadClassAndSupport, you should either 1) use getSootClass instead if you need the return value, or 2) remove the call altogether if you don't. In either case you must take steps to ensure the class will have been loaded during the resolving phase.

Q: I used loadClass/loadClassAndSupport anyway and I got an exception. Why?

A: Your call happened after resolving was finished, and the class that was passed as an argument hadn't already been loaded. Please fix your use as described elsewhere in this FAQ.

Q: How do I get a SootClass object given the name of a class?

A: Make sure that the class will have been loaded during resolving, and use Scene.v().getSootClass(String)

Q: How do I make sure that a class will have been loaded during resolving?

A: There are several cases to consider.

1) The class is part of some external library that you intend to insert calls or references to into the program being transformed by Soot. In this case, you should call addBasicClass(classname, level) before calling Soot's main function. "level" should be one of SootClass.HIERARCHY, SootClass.SIGNATURES or SootClass.BODIES. These are successively higher levels, so SIGNATURES implies HIERARCHY too, for example. HIERARCHY is appropriate if you will only be introducing variables of this type, but not calling any of its methods or referencing any of its fields. SIGNATURES is appropriate if you will be referring to fields or methods of the class. BODIES is appropriate if you also need to process the body of the class.

2) The class is part of the application you are processing. In this case Soot should have already loaded it.

3) The class is referred to by the application you are processing, either directly or indirectly. If all you are doing is processing the body of a class in the application and just inspecting references to other classes, Soot should already have loaded enough of the other classes for this. If on the other hand you want to process the bodies of classes that are not in the application, then you need to make sure that Soot is running in "full resolver" mode. The most common ways to do this are to ensure that the -w or -full-resolver flags are passed to Soot on startup. As an alternative, you can use the -app option to cause all non-Library application classes to get resolved to the Bodies level.

Q: What do I do if I don't call soot.Main.main at all?

A: You must call one of Scene.v().loadNecessaryClasses() or Scene.v().loadBasicClasses(). The former is appropriate if you have setup classes and other command-line arguments for Soot manually and want these to be processed so the classes are loaded, and the latter is appropriate otherwise.

Q: I've made a new optimisation or analysis pass for Soot and I need to call addBasicClass(...) for some classes I need for it. When should I do this?

A: There's currently no good answer for this, unfortunately. The best thing to do for now is to call it from a static { } block and hope that your optimisation class gets loaded before Soot resolving has finished. In future hopefully a hook will be added to the Transformer class to ensure that this happens at the right time.

Q: I've made a new optimisation or analysis pass for Soot and I need certain classes loaded conditionally on the options given to the pass. What should I do?

A: The situation here is even worse, sadly. For now your best bet would be to load the classes in static { } anyway if you know their names. If they don't exist, or do exist and load fine but aren't needed, then nothing bad will happen, but if they do exist but cause some kind of resolving error then you're out of luck. It seems like a Transformer method that gets called before the resolving phase would be a good solution here.