Bug 324367 - IJavaProject.findPackageFragmentRoots(IClasspathEntry cpe) returns empty list
Summary: IJavaProject.findPackageFragmentRoots(IClasspathEntry cpe) returns empty list
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.7   Edit
Hardware: PC Windows 7
: P3 normal (vote)
Target Milestone: 3.7 M4   Edit
Assignee: Jay Arthanareeswaran CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 330765 (view as bug list)
Depends on:
Blocks:
 
Reported: 2010-09-02 22:43 EDT by pesckal CLA
Modified: 2010-12-07 03:42 EST (History)
6 users (show)

See Also:


Attachments
Eclipse plug-in to replicate bug (5.32 KB, application/x-gzip)
2010-09-02 22:50 EDT, pesckal CLA
no flags Details
Proposed patch (1.15 KB, patch)
2010-09-03 07:50 EDT, Jay Arthanareeswaran CLA
no flags Details | Diff
Updated patch with test (3.52 KB, patch)
2010-09-06 04:44 EDT, Jay Arthanareeswaran CLA
no flags Details | Diff
Patch with updated test (3.63 KB, patch)
2010-09-20 03:28 EDT, Jay Arthanareeswaran CLA
no flags Details | Diff
A test on API behavior (3.57 KB, patch)
2010-12-02 06:07 EST, Jay Arthanareeswaran CLA
no flags Details | Diff
Updated doc patch (1.45 KB, text/plain)
2010-12-02 06:49 EST, Jay Arthanareeswaran CLA
no flags Details
Updated documentation (2.58 KB, patch)
2010-12-03 21:40 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 pesckal CLA 2010-09-02 22:43:39 EDT
Build Identifier: I20100608-0911

The method call "javaProject.findPackageFragmentRoots(cpe)" returns an empty list when cpe is of kind CPE_PROJECT and exists in javaProject's raw classpath. This occurs even when the project referenced by cpe has source or exported package fragment roots.

Reproducible: Always

Steps to Reproduce:
Call javaProject.findPackageFragmentRoots(cpe) where cpe is of kind CPE_PROJECT and the referenced project has source or exported package fragment roots.

See the attachments for an Eclipse plug-in with a JUnit test case to replicate this problem.
Comment 1 pesckal CLA 2010-09-02 22:50:39 EDT
Created attachment 178116 [details]
Eclipse plug-in to replicate bug

Import the project org.eclipse.bugs in the archive to your workspace and run the class TestFindPackageFragmentRoots as a 'JUnit Plug-in Test.'
Comment 2 Jay Arthanareeswaran CLA 2010-09-03 01:38:53 EDT
I will see what's happening.
Comment 3 Jay Arthanareeswaran CLA 2010-09-03 07:50:02 EDT
Created attachment 178134 [details]
Proposed patch

The problem seems to arise from the assumption that a required project entry in the classpath should also be marked as 'exported'. But I am not able to see this specified anywhere in the API docs. As per my understanding, the required projects' source projects are automatically chained and only the library, container and variable entries that need explicit exporting. 

The attached patch fixes this in the area that is causing this bug.

Tests to be added.
Comment 4 Jay Arthanareeswaran CLA 2010-09-03 08:07:27 EDT
May be I was wrong. As per the following API

org.eclipse.jdt.core.JavaCore.newProjectEntry(IPath, IAccessRule[], boolean, IClasspathAttribute[], boolean)

it would mean that even project entries need to be explicitly exported in order to be available for the dependent projects.
Comment 5 Jay Arthanareeswaran CLA 2010-09-06 03:35:15 EDT
(In reply to comment #4)
> May be I was wrong. As per the following API
> 
> org.eclipse.jdt.core.JavaCore.newProjectEntry(IPath, IAccessRule[], boolean,
> IClasspathAttribute[], boolean isExported)
> 
> it would mean that even project entries need to be explicitly exported in order
> to be available for the dependent projects.

The term 'dependent projects' in the documentation seem confusing. Here are some fragments from the Javadoc.

"A project entry is used to denote a prerequisite project on a classpath."

...

"The isExported flag indicates whether this entry is contributed to dependent projects. If not exported, dependent projects will not see any of the classes from this entry. If exported, dependent projects will concatenate the accessible files patterns of this entry with the accessible files patterns of the projects, and they will concatenate the non accessible files patterns of this entry with the non accessible files patterns of the project. "

After going through this again, it seems to me that in the context of project references, it means the 'dependent project' is the project (A) that is referencing the project (B) that includes this project  entry (C) in it's classpath.

For example, Project A depends on Project B. Project B has Project C as a project entry it's classpath. Here, in the case Project C as a project entry, A is the 'dependent project'.
Comment 6 Jay Arthanareeswaran CLA 2010-09-06 04:44:47 EDT
Created attachment 178248 [details]
Updated patch with test

This patch should be good enough. The patch also includes the test.

pesckal, can you please see if this patch address your problem and if the new test is close enough to the scenario you described?
Comment 7 pesckal CLA 2010-09-10 00:03:23 EDT
(In reply to comment #6)
> Created an attachment (id=178248) [details]
> Updated patch with test
> 
> This patch should be good enough. The patch also includes the test.
> 
> pesckal, can you please see if this patch address your problem and if the new
> test is close enough to the scenario you described?

Perfect! The method now works the way the API made me expect.

The test also looks good. I think it could have another case to check that source package fragment roots are also returned by findPackageFragmentRoots though (just add a source PFR to referencedProject and check that the length of the returned array is two.)
Comment 8 Jay Arthanareeswaran CLA 2010-09-20 03:28:10 EDT
Created attachment 179224 [details]
Patch with updated test

Patch contains updated test.
Comment 9 Jay Arthanareeswaran CLA 2010-09-20 03:31:31 EDT
Markus,
This patch fixes one of the APIs. Could you please review this and see if the changes are in line with the current API specifications?
Comment 10 Markus Keller CLA 2010-10-04 11:23:37 EDT
> This patch fixes one of the APIs. Could you please review this and see if the
> changes are in line with the current API specifications?

Looks good.
Comment 11 Jay Arthanareeswaran CLA 2010-10-12 00:30:55 EDT
Released in HEAD for 3.7M3.
Comment 12 Dani Megert CLA 2010-11-18 05:32:57 EST
This causes a major issues for the PDE container which now shows unexpected entries:
1. start new workspace
2. import 'org.eclipse.jface.text' as source
3. import 'org.eclipse.ui.editors' as source
4. expand the PDE container


The changed method was not including the exported roots since it got added in 2.1, hence when changing such a fundamental thing you should check at least all clients inside the SDK to make sure the change does not break them. In this case also clients outside the SDK (e.g. WTP) might be broken. I suggest to revert the change and adjust the Javadoc.

NOTE 1: you also need to change the Javadoc of getPackageFragmentRoots(ICPE)
NOTE 2: the bug number in the CVS comment of the change seems wrong
Comment 13 Dani Megert CLA 2010-11-18 05:33:11 EST
.
Comment 14 Jay Arthanareeswaran CLA 2010-11-19 02:55:38 EST
Dani, I agree I should have anticipated the breakages with this change. But as reported, the API in question, includes neither the exported fragments nor the source entries. The documentation states in several places that the source entries should be automatically included while the other types will be included if 'exported'. 

I also agree this change might have affected more than just eclipse projects. My question, though is, can we say that 'having additional unexpected entries' is better than 'not having some of the expected entries' and make a case for this?

If you don't agree, I will post the reverse patch and updated docs.
Comment 15 Dani Megert CLA 2010-11-19 02:59:08 EST
>is better than 'not having some of the expected entries' and make a case for
>this?
It worked like that since 2.1, so yes adjusting the doc is better than changing the behavior (and also add potential performance issues by returning more nodes).
Comment 16 Jay Arthanareeswaran CLA 2010-11-19 03:01:47 EST
(In reply to comment #15)
> >is better than 'not having some of the expected entries' and make a case for
> >this?
> It worked like that since 2.1, so yes adjusting the doc is better than changing
> the behavior (and also add potential performance issues by returning more
> nodes).

Should I just say in the two APIs' documentation
that if the classpath entry is a project, we return an empty list? This way, we
may not have to touch the other places where we talk about 'exported'.
Comment 17 Dani Megert CLA 2010-11-19 03:04:55 EST
> Should I just say in the two APIs' documentation
> that if the classpath entry is a project, we return an empty list? This way, we
> may not have to touch the other places where we talk about 'exported'.
I guess we can simply remove the "Note..." part.

If there is real/proven need for the currently specified behavior then we might
consider adding a new method with an additional Boolean parameter and deprecate
the existing method.

Please discuss and decide this (incl. Javadoc change) together with Markus.
Comment 18 Jay Arthanareeswaran CLA 2010-11-19 03:29:05 EST
(In reply to comment #17)
> If there is real/proven need for the currently specified behavior then we might
> consider adding a new method with an additional Boolean parameter and deprecate
> the existing method.
> 
> Please discuss and decide this (incl. Javadoc change) together with Markus.

I am interested in the new API idea. This way, we won't break the existing clients and also we don't have to change the doc to suit the behavior. Markus, will it be too late for a new API?
Comment 19 Dani Megert CLA 2010-11-19 03:40:12 EST
> I am interested in the new API idea. This way, we won't break the existing
> clients and also we don't have to change the doc to suit the behavior.
Well, the current method can't be changed and since it is wrong we have to change the doc.

> Markus,
> will it be too late for a new API?
API freeze is with M6 (in March).
Comment 20 Jay Arthanareeswaran CLA 2010-11-19 06:33:56 EST
Fix made has been reverted. We will keep this bug for API changes or document
changes, whichever is the outcome of further discussions.
Comment 21 Markus Keller CLA 2010-11-22 05:59:45 EST
> I am interested in the new API idea. This way, we won't break the existing
> clients and also we don't have to change the doc to suit the behavior.

You're contradicting yourself here: Either we break existing clients, or we change the Javadoc of the existing method. We will do the latter, since this bug has been in place forever.

pesckal, do you have a real need for a new API IJavaProject#
findPackageFragmentRoots(IClasspathEntry entry, boolean includeSourceFolders)? If yes, we can add this (with the implementation that was in 3.7M3), although I don't see any places where we would use this in the SDK.
Comment 22 Jay Arthanareeswaran CLA 2010-11-22 06:07:26 EST
(In reply to comment #21)
> You're contradicting yourself here: Either we break existing clients, or we
> change the Javadoc of the existing method. We will do the latter, since this
> bug has been in place forever.

I overlooked the fact that the new API will not be used by the SDK but by other clients that may want this behavior.
Comment 23 Jay Arthanareeswaran CLA 2010-11-22 07:18:45 EST
By the way, IJavaProject#getAllPackageFragmentRoots() does consider the exported classpath entries in the referenced project.
Comment 24 Dani Megert CLA 2010-11-22 11:18:18 EST
*** Bug 330765 has been marked as a duplicate of this bug. ***
Comment 25 Jay Arthanareeswaran CLA 2010-12-02 06:07:54 EST
Created attachment 184336 [details]
A test on API behavior

This patch has tests the behavior of several API methods relevant to exported entries. There are five tests totally and all of them currently pass. The first two APIs (IJavaProject#isOnClasspath(IResource) and IJavaProject#getAllPackageFragmentRoots()) consider the exported classpath entries from referenced projects while others don't.

I think instead of removing the doc about the 'exported' itself, we would be better of just adding this to the concerned APIs alone, just like in IJavaProject#getPackageFragmentRoots, which has the following line:

"The result does not include package fragment roots in other projects referenced on this project's classpath."

Markus, what do you think?
Comment 26 Jay Arthanareeswaran CLA 2010-12-02 06:49:23 EST
Created attachment 184342 [details]
Updated doc patch

I have added similar documentation as noted in comment #25 to the following APIs:
IJavaProject#findPackageFragmentRoots(IClasspathEntry)
IJavaProject#getPackageFragmentRoots(IClasspathEntry)
Comment 27 Markus Keller CLA 2010-12-02 10:11:25 EST
(In reply to comment #26)
> Created an attachment (id=184342) [details] [diff]
> Updated doc patch

The added paragraph looks good, but you also have to remove the wrong parts of the second sentence:

	 * Note that a classpath entry that refers to another project may
	 * have more than one root (if that project has more than on root
	 * containing source), and classpath entries within the current
	 * project identify a single root.

E.g. replace with:

* A classpath entry within the current project identifies a single root.
Comment 28 Jay Arthanareeswaran CLA 2010-12-03 21:40:23 EST
Created attachment 184524 [details]
Updated documentation

This patch incorporates the suggestions from Markus.
Comment 29 Jay Arthanareeswaran CLA 2010-12-03 21:43:10 EST
Released the documentation changes in HEAD for 3.7M4.
Comment 30 Satyam Kandula CLA 2010-12-07 03:42:58 EST
Verified for 3.7M4 using build I20101205-2000 looking at the Javadoc