<div dir="ltr">I have 1,000+ methods that will be used as custom entry points to generate a call graph.  They have different classes and what not.  I&#39;ve tried a few different things which I will list below, after I discuss my general approach and shed some more light on exactly what I&#39;m trying to do.<div><br></div><div>As I said I have N-number of methods that I want to generate a call graph for.  They are in the following format:</div><div><br></div><div>android.accessibilityservice.IAccessibilityServiceClient$Stub$Proxy.onAccessibilityEvent,<br></div><div>android.accounts.IAccountAuthenticator$Stub.confirmCredentials,<br></div><div>android.app.admin.IDevicePolicyManager$Stub.setMaximumFailedPasswordsForWipe, etc.<br></div><div><br></div><div>The class is actually an interface that contains a static inner class (`$Stub`) that contains an inner class (`$Proxy`, which implements said interface).  So `android.accessibilityservice.IAccessibilityServiceClient` is an interface, `$Stub` is a static inner class to `android.accessibilityservice.IAccessibilityServiceClient` and `$Proxy` is an inner class to `$Stub`.</div><div><br></div><div>My logic for solving this is as follows:</div><div>// get records from disk...</div><div>while(records.hasNextRecord()) {</div><div><pre style="color:rgb(169,183,198);font-family:Menlo;font-size:12pt;background-color:rgb(43,43,43)"><span style="color:rgb(204,120,50)">// get records from disk
while(records.hasNextRecord()) {
if</span>(!setArgs) {<br>    Options.<span style="font-style:italic">v</span>().parse(args)<span style="color:rgb(204,120,50)">;<br></span><span style="color:rgb(204,120,50)">    </span>setArgs = <span style="color:rgb(204,120,50)">true;<br></span>}<br><br>SootClass sootClass = Scene.<span style="font-style:italic">v</span>().forceResolve(record.getClassName()<span style="color:rgb(204,120,50)">, </span>SootClass.<span style="color:rgb(152,118,170);font-style:italic">BODIES</span>)<span style="color:rgb(204,120,50)">;<br></span>sootClass.setApplicationClass()<span style="color:rgb(204,120,50)">;<br></span>Scene.<span style="font-style:italic">v</span>().loadNecessaryClasses()<span style="color:rgb(204,120,50)">;<br></span>SootMethod sootMethod = sootClass.getMethodByName(record.getMethodName())<span style="color:rgb(204,120,50)">;<br></span>List&lt;SootMethod&gt; entryPoints = <span style="color:rgb(204,120,50)">new </span>ArrayList&lt;SootMethod&gt;()<span style="color:rgb(204,120,50)">;<br></span>entryPoints.add(sootMethod)<span style="color:rgb(204,120,50)">;<br></span>Scene.<span style="font-style:italic">v</span>().setEntryPoints(entryPoints)<span style="color:rgb(204,120,50)">;<br></span>PackManager.<span style="font-style:italic">v</span>().runPacks()<span style="color:rgb(204,120,50)">;<br></span><span style="color:rgb(204,120,50)"><br></span>soot.jimple.toolkits.callgraph.CallGraph callgraph = Scene.<span style="font-style:italic">v</span>().getCallGraph()<span style="color:rgb(204,120,50)">;<br></span>System.<span style="color:rgb(152,118,170);font-style:italic">out</span>.println(<span style="color:rgb(106,135,89)">&quot;[TestSpark] Call graph size &quot; </span>+ callgraph.size())<span style="color:rgb(204,120,50)">;<br></span><span style="color:rgb(204,120,50)"><br></span>System.<span style="color:rgb(152,118,170);font-style:italic">out</span>.println(String.<span style="font-style:italic">format</span>(<span style="color:rgb(106,135,89)">&quot;It took: %d seconds to generate a callgraph for: %s&quot;</span><span style="color:rgb(204,120,50)">,<br></span><span style="color:rgb(204,120,50)">        </span>TimeUnit.<span style="color:rgb(152,118,170);font-style:italic">MILLISECONDS</span>.toSeconds(System.<span style="font-style:italic">currentTimeMillis</span>() - start)<span style="color:rgb(204,120,50)">,<br></span><span style="color:rgb(204,120,50)">        </span>record.getClassName() + <span style="color:rgb(106,135,89)">&quot;.&quot; </span>+ record.getMethodName()))<span style="color:rgb(204,120,50)">;<br></span><span style="color:rgb(204,120,50)"><br></span>System.<span style="color:rgb(152,118,170);font-style:italic">out</span>.println(<span style="color:rgb(106,135,89)">&quot;=====================================&quot;</span>);
<span style="font-size:12pt">}</span></pre>This allows me to generate the callgraph from the custom entry point.  After the second iteration I get the following exception:</div><div><div><br></div><div>Exception in thread &quot;main&quot; java.lang.ClassCastException: soot.baf.internal.BIdentityInst cannot be cast to soot.jimple.Stmt</div><div><span class="" style="white-space:pre">        </span>at soot.jimple.toolkits.callgraph.OnFlyCallGraphBuilder.getImplicitTargets(OnFlyCallGraphBuilder.java:604)</div><div><span class="" style="white-space:pre">        </span>at soot.jimple.toolkits.callgraph.OnFlyCallGraphBuilder.processNewMethod(OnFlyCallGraphBuilder.java:530)</div><div><span class="" style="white-space:pre">        </span>at soot.jimple.toolkits.callgraph.OnFlyCallGraphBuilder.processReachables(OnFlyCallGraphBuilder.java:420)</div><div><span class="" style="white-space:pre">        </span>at soot.jimple.spark.solver.OnFlyCallGraph.build(OnFlyCallGraph.java:55)</div><div><span class="" style="white-space:pre">        </span>at soot.jimple.spark.builder.ContextInsensitiveBuilder.build(ContextInsensitiveBuilder.java:76)</div><div><span class="" style="white-space:pre">        </span>at soot.jimple.spark.SparkTransformer.internalTransform(SparkTransformer.java:84)</div><div><span class="" style="white-space:pre">        </span>at soot.SceneTransformer.transform(SceneTransformer.java:39)</div><div><span class="" style="white-space:pre">        </span>at soot.Transform.apply(Transform.java:90)</div><div><span class="" style="white-space:pre">        </span>at soot.RadioScenePack.internalApply(RadioScenePack.java:57)</div><div><span class="" style="white-space:pre">        </span>at soot.jimple.toolkits.callgraph.CallGraphPack.internalApply(CallGraphPack.java:49)</div><div><span class="" style="white-space:pre">        </span>at soot.Pack.apply(Pack.java:116)</div><div><span class="" style="white-space:pre">        </span>at soot.PackManager.runWholeProgramPacks(PackManager.java:563)</div><div><span class="" style="white-space:pre">        </span>at soot.PackManager.runPacksNormally(PackManager.java:456)</div><div><span class="" style="white-space:pre">        </span>at soot.PackManager.runPacks(PackManager.java:391)</div><div><span class="" style="white-space:pre">        </span>at Main.main(Main.java:39)</div><div><span class="" style="white-space:pre">        </span>at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)</div><div><span class="" style="white-space:pre">        </span>at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)</div><div><span class="" style="white-space:pre">        </span>at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)</div><div><span class="" style="white-space:pre">        </span>at java.lang.reflect.Method.invoke(Method.java:483)</div><div><span class="" style="white-space:pre">        </span>at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)</div></div><div><br></div><div>I&#39;ve tried adding all the methods per class to a the entry points and run the callgraph when the class changes, obviously the above method, one-by-one resolution, etc.  But the exception continues to persist.</div><div><br></div><div>Any ideas on how to build a callgraph for &gt;50 different classes that contain n-number of custom entry points that don&#39;t produce the exception would be very helpful.  Thanks.</div></div>