5

I'm trying to find a path to a jar file that's in the raw classpath. getRawClasspath returns a collection of IClasspathEntry objects. I can call getPath on those.

But getPath returns something weird: an IPath that starts with the project name, like:

/ProjectName/lib/something.jar

What's the right way to turn this relative path into a full-qualified OS path? At first I thought I could just add the path to the workspace root, but that doesn't work since there are often intermediate directories between the workspace and the project.

And more generally, how do I know what to do with an IPath returned by a method? It seems like I never know what that IPath is; relative to the project, relative to the workspace, relative to the project but with the project name as the first element, relative to the phase of the moon... It's all baffling, and the documentation is never helpful - or at least I don't know where to look.

UPDATE

I'm even more confused now. The problem still is that, when you have an IClasspathEntry, it's still unclear to me how to resolve it to a filesystem path.

The answer that says "if a path starts with a / it's an absolute path (relative to the workspace) isn't correct. The problem is that the getPath method on an IClasspath returns one of two things: a path starting with a slash that's relative to the workspace, or an IPath starting with a / that's an actual filesystem path. Yes, two completely different things are shoved into one type. You get the filesystem variant when the jar is outside the workspace, and you get the "absolute" variant when it's in the workspace.

I think part of the answer is that an IPath, by itself, is only a fancy string. You have to know where it came from to make sense out of it. It doesn't carry the right sorts of information to be useful on its own.

So what's the right way to deal with this?

James Moore
  • 8,636
  • 5
  • 71
  • 90

4 Answers4

5

try this:

    IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
    IResource res = root.findMember("/ProjectName/lib/something.jar");
    System.out.println(res.getLocation().toString());
Dollyn
  • 914
  • 4
  • 15
  • That works (upvote), but doesn't answer the larger question of "how should I have known that"? Why shouldn't it have been a lookup on the project instead of the workspace, for example? – James Moore Feb 06 '12 at 18:18
  • If the path starts with a ' / ' it means that it's an absolute path(relative the workspace root). If not, it means that it's a relative path, it can be relative to any container... You can use IPath.isAbsolute() to know whether a path is an absolute path. For JDT's IProject.getRawClasspath it always use absolute path. – Dollyn Feb 09 '12 at 06:00
  • I'm beginning to think that my basic mistake is in thinking that Eclipse paths have something to do with OS paths. Does an eclipse absolute path _always_ have the project as the first element, no matter what the filesystem path is? So I should expect something in /Users/james/workspace/someSubDirectory/foo/ProjectX/src/Code.java to have an absolute path of /ProjectX/src/Code.java? – James Moore Feb 09 '12 at 16:30
  • Yes, eclipse.resources plugin uses it's own resource system. In this system, workspace is treated as the root. For more information, look at the eclipse's help document: Help-> Help Contents-> Platform Plug-in Developer Guide > Programmer's Guide > Resources overview – Dollyn Feb 10 '12 at 06:42
  • And now I think that page is less than useful. The problem is that you can't know what a an absolute path is relative to; Eclipse uses at least two different sorts of absolute paths, only one of which is relative to the workspace. (Yes, this is horrible.) – James Moore May 25 '12 at 05:30
1

Paths in Eclipse are complicated, and there are a few other situations that you haven't mentioned, like classpath containers (JRE is an example), linked resources outside of the workspace and classpath variables.

To simplify, I suggest you use getResolvedClasspath instead, that returns only 'simple' classpath entires (no variables, no containers). According to its Javadoc, it returns absolute paths, and their interpretation depends on the kind of the entry:

  • CPE_LIBRARY - if it's an external library, it's a filesystem path (and it has no associated resource, meaning you can't find it with findMember). Otherwise, it's a path based on the workspace root
  • CPE_PROJECT - absolute path to the project
  • CPE_SOURCE - absolute path to the source folder

All absolute path are interpreted in the workspace. If you need the file-system path, you need to go through getLocation.

As a side-note, there is no 1-to-1 mapping between file-system entities and workspace resources. Because of workspace links, you may have several workspace paths pointing to the same (file-system) location.

Iulian Dragos
  • 5,692
  • 23
  • 31
0

This is the best I could come up with, and it totally is an ugly hack, yes:

private IPath getCorrectAbsolutePath(IJavaProject project, IPath path) throws IllegalArgumentException {
    final String projectName = project.getProject().getName();
    if (path.segmentCount() > 1 && path.segment(0).equals(projectName)) {
        IPath projectAbsolutePath = project.getProject().getLocation();
        IPath relativePath = path.removeFirstSegments(1);
        return projectAbsolutePath.append(relativePath);
    } else {
        if (!path.isAbsolute())
            path = path.makeAbsolute();
        if (!path.isAbsolute())
            throw new IllegalArgument("Cannot make IPath absolute: " + path.toString()); 
        return path;
    }
}
vorburger
  • 3,439
  • 32
  • 38
-2

I have a suggestion, look picture attachment, find "location" property from properties of any plugin of eclipse , maybe can find it where is from. but sorry I have no 10 reputation, you can see picture from picture url

orange
  • 42
  • 3