Absolute filesystem path for an IClasspathEntry

866 views Asked by At

I have an IJavaProject, and my goal is to generate a List<File> with the absolute filesystem paths for the resolved classpath entries for the project. I start by calling project.getResolvedClasspath(true) to get an array of IClasspathEntry objects. But I'm not sure how to reliably determine the absolute filesystem path for each entry. The approach I'm currently pursuing is highlighted below, but if there's an easier way, I'd definitely like to know.


My first thought was to do something like this for each entry: ResourcesPlugin.getWorkspace().getRoot().getLocation().append(entry.getPath()). But the problem is that not all IClasspathEntry objects have workspace-relative paths; external libraries have absolute filesystem paths. I can easily identify if an IClasspathEntry is a library (getEntryKind() == IClasspathEntry.CPE_LIBRARY)...however I cannot see any obvious API for identifying whether or not a library entry is external or not.

The Javadoc for IClasspathEntry.getPath() has this to say:

Returns the path of this classpath entry. The meaning of the path of a classpath entry depends on its entry kind:

[...]

•A binary library in the current project (CPE_LIBRARY) - the path associated with this entry is the absolute path to the JAR (or root folder), and in case it refers to an external library, then there is no associated resource in the workbench.

That would seem to suggest that perhaps I can test whether "there is no associated resource in the workbench" to determine if a library is external or not. But is this a reliable approach? And how does that translate to code?


My concern about the reliability is this: entry path /user/kevin/foo.jar could refer to an external jar (jarfile in my home directory under Linux), or an internal jar (jarfile in 'kevin' folder of project 'user'). As the user, I might try to add both jarfiles to my project classpath. Unless Eclipse prevents me from doing this (unfortunately I don't have a Linux machine handy to test this myself), then it seems to me that the internal jar would be shadowing the external one and my results would be inaccurate.

1

There are 1 answers

0
greg-449 On BEST ANSWER

This is what the Eclipse uses:

IClasspathEntry entry = ....

IWorkbenchRoot root = ResourcesPlugin.getWorkspace().getRoot();

if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
    IPath cpPath = entry.getPath();

    IResource res = root.findMember(cpPath);

    // If res is null, the path is absolute (it's an external jar)

    String path;
    if (res == null) {
        path = cpPath.toOSString();
    }
    else {
        // It's relative
        path res.getLocation().toOSString();
    }
}

adapted from org.eclipse.jdt.apt.core.util.AptConfig