wala / WALA

T.J. Watson Libraries for Analysis, with frontends for Java, Android, and JavaScript, and may common static program analyses
http://github.com/wala/WALA
Eclipse Public License 2.0
757 stars 221 forks source link

CHA empty for Java source files #366

Open reddr opened 5 years ago

reddr commented 5 years ago

I tried to generate a CHA using Java source files with the code below. The code does not fail, but will give me a hierarchy object with no classes (here I added the Object class as binary to prevent the "failed to load root" error).

AnalysisScope scope = AnalysisScope.createJavaAnalysisScope();

// this is just to prevent the "failed to load root <Primordial,Ljava/lang/Object> of class hierarchy" error
scope.addClassFileToScope(ClassLoaderReference.Primordial, new File("./bin/Object.class"));

// ! this does not read the source file / create an IClass
File srcFile = new File("./src/com/Foo.java");
scope.addSourceFileToScope(ClassLoaderReference.Application, srcFile, $FILENAME);

IClassHierarchy cha = ClassHierarchyFactory.make(scope);
System.out.println("CHA  # classes: " + cha.getNumberOfClasses());  // = 1, should be 2

The first obstacle was the $FILENAME you have to provide, given that you already have to provide a File instance. When turning the debugging on for ClassLoaderImpl, I could see that loadAllSources tries some magic to infer the full package.class name from $FILENAME. Hence, srcFile.getName() or srcFile.getPath() do result in weird typenames that are eventually put in the sourceMap, i.e.

adding to source map: LFoo -> Foo.java     // if FILENAME = srcFile.getName()
adding to source map:  L/src/com/Foo -> Foo.java .   // if FILENAME = srcFile.getPath()

Using "com.Foo" or "com/Foo" as FILENAME then fixed the mapping, but still no IClass was created. So the first issue is that "fileName" as argument to addSourceFileToScope is misleading. It would even be better if this would automatically be inferred from the source file, similar as for .class files.

The main issue, however, is that no IClass is created. In ClassLoaderImpl.loadAllSources there is a comment saying "Add the T and entry to the sourceMap anyway, just in case in some special cases, we add new classes later." But, in contrast to loadAllClasses, no IClasses are created, returning an empty IClassHierarchy.

By quickly searching through the code base, JavaSourceLoaderImpl looks like the class to achieve this. But I don't have a clue how and where to apply this. Any comments on the issue?

PS: I tested with master, 1.4.0, 1.5.0 w/o phantomclasses and with ClassLoaderReference App/Primordial.

qingdujun commented 5 years ago

I have encountered the same problem.

Questions:(You can see)

AllApplicationEntrypoints Number of EntryPoints:0.

Could not create a entrypoint callsites: 1. [Moderate] class com.ibm.wala.ipa.cha.ClassHierarchy$ClassExclusion : <Primordial,Ljavafx/embed/swt/CustomTransfer> No superclass found for <Primordial,Ljavafx/embed/swt/CustomTransfer> Superclass name Lorg/eclipse/swt/dnd/ByteArrayTransfer
2. [Moderate] class com.ibm.wala.ipa.cha.ClassHierarchy$ClassExclusion : <Primordial,Ljavafx/embed/swt/FXCanvas> No superclass found for <Primordial,Ljavafx/embed/swt/FXCanvas> Superclass name Lorg/eclipse/swt/widgets/Canvas
3. [SEVERE] class com.ibm.wala.classLoader.BytecodeClass$ClassNotFoundWarning : Lorg/eclipse/swt/dnd/DragSourceListener
4. [SEVERE] class com.ibm.wala.classLoader.BytecodeClass$ClassNotFoundWarning : Lorg/eclipse/swt/dnd/DropTargetListener
5. [SEVERE] class com.ibm.wala.classLoader.BytecodeClass$ClassNotFoundWarning : Lorg/eclipse/swt/events/ControlListener
6. [SEVERE] class com.ibm.wala.classLoader.BytecodeClass$ClassNotFoundWarning : Lorg/eclipse/swt/events/DisposeListener
7. [SEVERE] class com.ibm.wala.classLoader.BytecodeClass$ClassNotFoundWarning : Lorg/eclipse/swt/events/FocusListener
8. [SEVERE] class com.ibm.wala.classLoader.BytecodeClass$ClassNotFoundWarning : Lorg/eclipse/swt/events/KeyListener
9. [SEVERE] class com.ibm.wala.classLoader.BytecodeClass$ClassNotFoundWarning : Lorg/eclipse/swt/events/MouseListener
10. [SEVERE] class com.ibm.wala.classLoader.BytecodeClass$ClassNotFoundWarning : Lorg/eclipse/swt/events/MouseTrackListener
11. [SEVERE] class com.ibm.wala.classLoader.ClassLoaderImpl$MultipleImplementationsWarning : Lnetscape/javascript/JSException
12. [SEVERE] class com.ibm.wala.classLoader.ClassLoaderImpl$MultipleImplementationsWarning : Lnetscape/javascript/JSObject

My code as follow,

//scope.addToScope(JavaSourceAnalysisScope.SOURCE, 
//new SourceDirectoryTreeModule(new File(sourceDir)));

scope.addSourceFileToScope(ClassLoaderReference.Application, 
new File(sourceDir+"/xxx.java"), sourceDir+"/xxx.java");

//...

Iterable<? extends Entrypoint> entrypoints = 
new AllApplicationEntrypoints((JavaSourceAnalysisScope)scope, cha);

So, how to add source files and get entrypoints?