I have two java files under the tests
directory.
I use the following code to set up Soot for further analysis(i.e., construct a call graph) but meet an error of are the packages set properly?
.
Main.java
:
public class Main {
static void setupSoot() {
Options.v().set_prepend_classpath(true);
Options.v().set_process_dir(Collections.singletonList("./tests"));
Options.v().set_whole_program(true);
Scene.v().loadNecessaryClasses();
}
// Following function also doesn't work and has a similar error message
//static void setupSoot() {
// Options.v().set_prepend_classpath(true);
// Options.v().set_process_dir(Collections.singletonList("./tests"));
// Scene.v().loadClassAndSupport("FooBar");
//}
public static void main(String[] args) {
setupSoot();
// ....
}
}
And I get the following error message:
Exception in thread "main" java.lang.RuntimeException: Error: couldn't find class: FooBar are the packages set properly?
at soot.JastAddInitialResolver.resolveFromJavaFile(JastAddInitialResolver.java:119)
at soot.JavaClassSource.resolve(JavaClassSource.java:69)
at soot.SootResolver.bringToHierarchyUnchecked(SootResolver.java:253)
at soot.SootResolver.bringToHierarchy(SootResolver.java:221)
at soot.SootResolver.bringToSignatures(SootResolver.java:292)
at soot.SootResolver.bringToBodies(SootResolver.java:332)
at soot.SootResolver.processResolveWorklist(SootResolver.java:171)
at soot.SootResolver.resolveClass(SootResolver.java:141)
at soot.Scene.loadClass(Scene.java:1009)
at soot.Scene.loadClassAndSupport(Scene.java:994)
at soot.Scene.loadNecessaryClasses(Scene.java:1822)
at Main.setupSoot(Main.java:18)
at Main.main(Main.java:21)
If I complie two test files into .class
files then I will get following error message:
Exception in thread "main" soot.SootResolver$SootClassNotFoundException: couldn't find class: tests.FooBar (is your soot-class-path set properly?)
at soot.SootResolver.bringToHierarchyUnchecked(SootResolver.java:245)
at soot.SootResolver.bringToHierarchy(SootResolver.java:221)
at soot.SootResolver.bringToSignatures(SootResolver.java:292)
at soot.SootResolver.bringToBodies(SootResolver.java:332)
at soot.SootResolver.processResolveWorklist(SootResolver.java:171)
at soot.SootResolver.resolveClass(SootResolver.java:141)
at soot.Scene.loadClass(Scene.java:1009)
at soot.Scene.loadClassAndSupport(Scene.java:994)
at soot.Scene.loadNecessaryClasses(Scene.java:1822)
at Main.setupSoot(Main.java:18)
at Main.main(Main.java:21)
I beleive that soot prepend_classpath
is true since it works well when two test files are not in the package (i.e., remove package tests
from both files).
Two files in tests
directory are as follows:
Pack.java
:
package tests;
public class Pack {
public static void main(String[] args) {
int s = 10;
}
}
FooBar.java
package tests;
public class FooBar {
public static void main(String[] args) {
FooBar callFooBar = new FooBar();
callFooBar.foo(10);
}
void foo(int a) {
bar(a);
}
void bar(int a) {
for (int i = 0; i < a; i++) {
i += a;
}
}
}
I solved this problem. The issue is that the path
of the test files is wrong.
Now my project structure is as follows:
-ProjectRoot
|--src
|--Main.java
|--testers
|--easycase
|--FooBar.java
|--Pack.java
and My Main.java
:
public class Main {
static void setupSoot() {
Options.v().set_prepend_classpath(true);
// Options.v().set_soot_classpath("xxxxx:xxxxx/xxxxx.jar") // For external packages
Options.v().set_process_dir(Collections.singletonList("./testers"));
Options.v().set_whole_program(true);
Scene.v().loadNecessaryClasses();
}
public static void main(String[] args) {
setupSoot();
Scene.v().loadAndSupport("esaycase.FooBar");
// Do something here
}
}
Note that the first line is package easycase;
for both test files.