Search code examples
javaeclipseeclipse-jdt

Why I got no super classes with getAllSuperclasses() in JDT API?


I have class A, and class B that inherits A in Eclipse workspace.

enter image description here enter image description here

The issue that I have is that I got nothing when I tried to get the super types of type B using eclipse JDT API. This is the code (I got the code from - List all subclasses with fully qualified names):

IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
java.io.File workspaceDirectory = root.getLocation().toFile();

// 1. The name of the project in the workspace
IProgressMonitor pm = new NullProgressMonitor();    
IProject orig = root.getProject(this.projectName);
orig.open(pm);
this.javaProject = JavaCore.create(orig);
orig.refreshLocal(IResource.DEPTH_INFINITE, pm);

// 2. Find the type                
IType type = this.javaProject.findType("p.B"); <-- returns correct type info
ITypeHierarchy hier = type.newSupertypeHierarchy(new NullProgressMonitor());
IType[] types = hier.getAllSuperclasses(type);
System.out.println(types); <-- Returns []

I also added the code to refresh/update the resources in package.

IPackageFragmentRoot[] packageFragmentRoots = this.javaProject.getPackageFragmentRoots();
for (IPackageFragmentRoot proot: packageFragmentRoots)
{
    proot.getResource().refreshLocal(IResource.DEPTH_INFINITE, null);
}

Everything works fine except getting the hierarchical type information. What might be wrong? Did I miss any setup before executing the API?

Mine is a headless RCP application.


Solution

  • This may be a temporary solution, but it worked for me.

    Short Answer

    Make a lib directory, and copy this rtstubs.jar into the directory. You may need to refresh(F5) the eclipse IDE to see the jar file is included in the project.

    enter image description here

    Then, in "Java Build Path", you need to add this jar file.

    enter image description here

    After the inclusion of the jar file in package fragment, you'll get the class hierarchy.

    enter image description here

    Long Answer (why does this solve the issue)

    CompilationUnitDeclaration (org.eclipse.jdt.internal.compiler.ast) and Hierarchy Resolver (org.eclipse.jdt.internal.core.hierarchy)

    It has a field ignoreFurtherInvestigation, and a method hasErrors() returns this field.

    org.eclipse.jdt.internal.core.hierarchy.HierarchyResolver#resolve() method invokes hasError() to add type information to cache. However, without the inclusion of the jar file, the hasError() method always returns false to prevent any class hierarchical information is stored.

    enter image description here

    org.eclipse.jdt.internal.core.JavaProjectElementInfo

    This class has cache initialization methods such as initializePackageNames and getProjectCache. In getProjectCache() method, package fragment element roots are loaded and added to the cache.

    enter image description here

    With the rtstubs.jar in the package fragment, the cache now contains all the Java class hierarchy. Without this setup, in the course of cache build up, the ignoreFurtherInvestigation filed is on, and hasError() method returns true not to contain the class hierarchical information to return just nothing.

    enter image description here

    ADDED

    The other solution can be using IRegion.

    How can I set the region (=set of java Elements) parameter in JDT TypeHierarchy?