Bug 274737 - Relative Classpath entries should not be resolved relative to the workspace
Summary: Relative Classpath entries should not be resolved relative to the workspace
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.5   Edit
Hardware: All All
: P3 minor with 2 votes (vote)
Target Milestone: 3.7 M6   Edit
Assignee: Jay Arthanareeswaran CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-05-02 16:46 EDT by David Wegener CLA
Modified: 2012-04-23 11:18 EDT (History)
6 users (show)

See Also:


Attachments
Resolve relative library entries based on project instead of workspace (4.65 KB, patch)
2009-05-02 16:55 EDT, David Wegener CLA
no flags Details | Diff
mylyn/context/zip (3.13 KB, application/octet-stream)
2009-05-02 16:55 EDT, David Wegener CLA
no flags Details
patch adjusted for HEAD (5.26 KB, patch)
2011-01-04 05:13 EST, Jay Arthanareeswaran CLA
no flags Details | Diff
Updated patch (7.24 KB, patch)
2011-01-18 05:18 EST, Jay Arthanareeswaran CLA
no flags Details | Diff
Same path with test (10.87 KB, patch)
2011-01-24 00:27 EST, Jay Arthanareeswaran CLA
no flags Details | Diff
Updated patch (9.91 KB, patch)
2011-02-14 01:35 EST, Jay Arthanareeswaran CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description David Wegener CLA 2009-05-02 16:46:16 EDT
The relative classpath changes made as part of 3.5M3 resolve classpath entries relative to the workspace directory.  This is most likely not the desired root for a relative entry.

Library entries should be resolved relative to the project location.  They will currently only resolve relative to the project if it is contained in the workspace.  For projects residing outside the workspace, the library entries are still resolved relative to the workspace root.

Example Workspace Location: /home/myhome/workspace1
Project location: /home/myhome/development/project1
Classpath Library entry: ../third_party/some.jar.
Expected resolution: /home/myhome/development/third_party/some.jar
Actual resolution: /home/myhome/workspace1/third_party/some.jar

Variable entries defined relative to a Classpath Variable can't be resolved at all.  The path of a variable entry has the variable name as the first segment.  The extension of the variable is appended to the variable name to complete the path.  If the extension  begins with a relative reference (../), the canonicalization of the Path for the ClasspathEntry removes the variable name completely from the path.  This prevents the ClasspathEntry from being resolved.

Example:  Classpath Variable: EXTERNAL_LOCATION = /home/myhome/development/lib
Classpath Variable Extension: ../third_party/some.jar
Expected resolution: /home/myhome/development/third_party/some.jar

When the JavaProject reads this from the .classpath file, it calls ClasspathEntry.elementDecode() to create a ClasspathEntry with a path of EXTERNAL_LOCATION/../third_party/some.jar.  As part of the decode process, ClasspathEntry creates a Path instance.  As part of the Path constructor, the path is canonicalized.  This results in a path of /third_party/some.jar.  Subsequent attempts by the JavaModelManager to resolve the variable entry fail because the ClasspathEntry no longer includes the variable name as the first segment of the path.
Comment 1 David Wegener CLA 2009-05-02 16:55:44 EDT
Created attachment 134162 [details]
Resolve relative library entries based on project instead of workspace
Comment 2 David Wegener CLA 2009-05-02 16:55:49 EDT
Created attachment 134163 [details]
mylyn/context/zip
Comment 3 Olivier Thomann CLA 2010-01-05 09:15:32 EST
Jay,

Please investigate what happens with the variable entries.
Comment 4 Gair CLA 2010-12-20 13:17:16 EST
I don't wish to overstate the importance of this bug, but we have been waiting for a fix for donkeys. When 3.5 included relative path support we were delighted but it does not work relative to the project as stated in the release note. This causes us to have to make copies of our libraries (that are version controlled alongside our projects) inside our projects using symlinks causing confusion and wasted disk space. I would have thought this a common problem and justify 'normal' importance?
Comment 5 Jay Arthanareeswaran CLA 2010-12-22 08:17:00 EST
(In reply to comment #1)
> Created an attachment (id=134162) [details]
> Resolve relative library entries based on project instead of workspace

Much has changed in HEAD since the patch was generated. I will take a look at the patch.
Comment 6 noreply CLA 2010-12-27 18:13:54 EST
I'm using 3.6.1 M2, and see the same behavior the others do - relative paths are relative to workspace; it would be desirable for them to be relative to project, to ease source control / multiple developer environment issues.

Ideally, using variables would be optional (allow relative path directly in .classpath file w/o workspace variable).
Comment 7 Jay Arthanareeswaran CLA 2011-01-04 05:13:54 EST
Created attachment 185989 [details]
patch adjusted for HEAD

Same as the previous patch but adjusted for HEAD. Yet to be reviewed and the patch is causing some tests to fail as well. Will look in to it.
Comment 8 Jay Arthanareeswaran CLA 2011-01-10 09:57:41 EST
(In reply to comment #7)
> Created attachment 185989 [details]
> patch adjusted for HEAD
> 
> Same as the previous patch but adjusted for HEAD. Yet to be reviewed and the
> patch is causing some tests to fail as well. Will look in to it.

There are two problems with this patch:
1. This doesn't consider the cases where the '..' path itself can have the project's path (like "../P/internal.jar" where P is the project)
2. The invocation of ClasspathEntry.resolveDotDot() from JavaModelManager passes the workspace location because it doesn't have the project context, which could be causing issues.

We might need a different approach here. Continuing investigation.
Comment 9 Jay Arthanareeswaran CLA 2011-01-11 00:22:41 EST
One of the approaches for fixing this would be to make sure that JavaModelManager#resolveVariableEntry(IClasspathEntry, boolean) gets the project context for resolving the variable entry. Only problem is the API JavaCore#getResolvedClasspathEntry(IClasspathEntry). I wonder why it is not like JavaCore#getClasspathContainer(IPath, IJavaProject).

Besides, the other relevant question I have is: Why don't classpath entries contain the project context? When would we want to create a classpath entry without the context of a project?
Comment 10 Jay Arthanareeswaran CLA 2011-01-13 04:15:32 EST
(In reply to comment #0)
> When the JavaProject reads this from the .classpath file, it calls
> ClasspathEntry.elementDecode() to create a ClasspathEntry with a path of
> EXTERNAL_LOCATION/../third_party/some.jar.  

Just wondering if this kind of usage is supported. Looking at the code, I can say it's not. The computed path is missing the variable name when we the classpath is decoded.

i.e.  VAR_NAME + ../path => /path

And I don't see anywhere in the documentation that says this is supported or otherwise. Do you have some reference, by any chance?
Comment 11 Jay Arthanareeswaran CLA 2011-01-18 05:18:01 EST
Created attachment 186986 [details]
Updated patch

The fix should be something similar to this. In this patch I have just kept both the existing code and new code as two different (if/else) cases - one for external projects and the other for those that reside in the workspace. Of course, the code can be optimized, which I will look at.

As for the variable path problem, I doubt if we can support the usage I mentioned in comment #10.
Comment 12 Jay Arthanareeswaran CLA 2011-01-24 00:27:26 EST
Created attachment 187396 [details]
Same path with test

New test added in ClasspathTests
Comment 13 Jay Arthanareeswaran CLA 2011-02-07 02:45:07 EST
Satyam, could you review this, please?
Comment 14 Satyam Kandula CLA 2011-02-10 06:36:32 EST
Jay, 
Here are some minor changes that you want to look at. 
1. ClasspathEntry->resolveDotDot(IPath reference, IPath path)-->workspaceLocation is getting un-necessarily getting computed. I do understand that you don't want to touch any code that wasn't modified, but I guess it is good to remove it here. 
2. JavaModelManager#resolveVariableEntry() probably need not be modified.
3. The bug summary for the testcase doesn't match this. 

+1 otherwise.
Comment 15 Jay Arthanareeswaran CLA 2011-02-14 01:35:54 EST
Created attachment 188870 [details]
Updated patch

Thanks Satyam. The new patch incorporates the suggestions.
Comment 16 Satyam Kandula CLA 2011-02-14 03:28:55 EST
Jay, The patch looks good. +1.
Comment 17 Jay Arthanareeswaran CLA 2011-02-14 03:43:06 EST
Released in HEAD for 3.7M6.
Comment 18 Gair CLA 2011-02-14 08:48:13 EST
Jay, this looks like great news, thanks.
Apologies for cheeky question & ignorance, but is there a version of the patch that may work against 3.5 or 3.6 (you mentioned there was a previous one?). Not to worry if not, but I guess 3.7M6 won't be on general release for some time so we won't be able to use it. I would like to test it regardless but might need some pointers on how to install the patch...
Comment 19 Olivier Thomann CLA 2011-02-14 08:52:35 EST
(In reply to comment #18)
> we won't be able to use it. I would like to test it regardless but might need
> some pointers on how to install the patch...
The easiest solution is to use this week I-build. It starts at 8am EST on Tuesday morning.
Comment 20 Satyam Kandula CLA 2011-03-08 05:07:25 EST
Verified for 3.7M6 using build I20110307-0800
Comment 21 Gair CLA 2011-12-13 18:29:49 EST
I know this has been closed but have just adopted 3.7.1 expecting this to now work but have had no luck (also tried 4). Should it be fixed in this version? I am expecting <classpathentry kind="lib" path="../lib/some.jar"> to work relative to the project but still seems to be relative to workspace which is not useful, am I missing something?
Comment 22 Jay Arthanareeswaran CLA 2011-12-14 01:01:43 EST
(In reply to comment #21)
> I know this has been closed but have just adopted 3.7.1 expecting this to now
> work but have had no luck (also tried 4). Should it be fixed in this version? I
> am expecting <classpathentry kind="lib" path="../lib/some.jar"> to work
> relative to the project but still seems to be relative to workspace which is
> not useful, am I missing something?

It works as expected when I tried with 4.2 M4. What is your folder structure? Where is your project located with reference to the workspace?

This is my folder structure:
<root>
    workspace
    externalprojects
        project274737
    lib
        jclMin1.5.jar  

classpath entry: ../lib/jclMin1.5.jar

The entry is resolved properly. Even when I try to edit the entry location from the build path dialog, it takes me to the correct location. I guess there is something different in your workspace. If you can't figure out if your folder structure is different, could you please attach the set-up so that I can have a look at it.
Comment 23 Gair CLA 2011-12-18 18:09:43 EST
Sorry, just tried this at home and it works fine on 3.7.1 64 bit. It must have been an environmental/'user' issue;) This will save us a lot of disk space and symlink confusion! Thx v much G
Comment 24 Ralph Mayr CLA 2012-04-23 08:48:16 EDT
Hello,

we're seeming to have similar troubles here – the ".." in a classpath variable always seems to be resolved relative to the workspace root, but not the current project root.

Our example situation looks like this:
Workspace Root: E:\workspace
Project Root: E:\workspace\myproject
Location of the library I want to match: E:\workspace\myproject\lib\test.jar
Classpath Variable: Name: TEST, location: ..\lib\test.jar

My expectation was, that "..\lib\test.jar" would hit the project-relative path of the JAR file, unfortunately I still get an error saying "Project ... is missing required library 'E:\workspace\lib\test.jar". Shouldn’t this be the behavior that was addressed in this bug? We are currently running 3.7 (SR2) and according to the source of ClasspathEntry.java from the jdt.core-bundle, the proposed patch was applied.
Comment 25 Jay Arthanareeswaran CLA 2012-04-23 11:18:16 EDT
(In reply to comment #24)
> Hello,
> 
> we're seeming to have similar troubles here – the ".." in a classpath variable
> always seems to be resolved relative to the workspace root, but not the current
> project root.

Sorry, this bug doesn't address relative paths in variables. That would be bug 70417, which is targeted for 3.8 M7.