Bug 578452 - JavaProject.computeExpandedClasspath() too aggressive at duplicate removal
Summary: JavaProject.computeExpandedClasspath() too aggressive at duplicate removal
Status: NEW
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 4.16   Edit
Hardware: PC Windows 10
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: JDT-Core-Inbox CLA
QA Contact:
URL:
Whiteboard: stalebug
Keywords: helpwanted
Depends on:
Blocks:
 
Reported: 2022-01-30 09:00 EST by Jeremy Krieg CLA
Modified: 2024-01-24 16:44 EST (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jeremy Krieg CLA 2022-01-30 09:00:26 EST
I was experimenting with exported, transitive dependencies in a chain of Eclipse project and found what I would class as a bug.

Suppose you have a Jar library A. A is an exported dependency of two projects, P1 & P2. "Combine access rules" is used so that only a subset of A is effectively exported by the projects, and P1 & P2 have different access rules so the subset of A that is effectively exported is different for each project. Let's call these subsets A1 and A2 respectively.

P3 has P1 & P2 on its classpath, in that order.

What I expect to happen: P3 can see all the classes in P1 and in P2, but also see the subset of A that is equal to the union of A1 & A2.

What actually happens: P3 can see P1 & P2, but it can only see subset A1 and not subset A2.

Reason: JavaProject.computeExpandedClasspath() has duplicate removal, but it only checks the library path of the ClasspathEntry when it's looking for duplicates - it doesn't look at the access rules. So the first ClasspathEntry with the set of access rules A1 gets added to the expanded classpath, and then the second ClasspathEntry is simply discarded because it points to the same library as the first classpath entry.

Relevant code is here: 

https://git.eclipse.org/c/jdt/eclipse.jdt.core.git/tree/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java#n647


Possible solutions:
-duplicate detection should be keyed on the library path *and* the access rules (so in the above use case both entries would be included in the expanded list), or
-when a duplicate library path is found, instead of discarding the duplicate, combine the access rules with those of the existing entry.
Comment 1 Jay Arthanareeswaran CLA 2022-01-31 22:47:27 EST
This looks like a bug to me but I have no idea why this doesn't work as expected. Perhaps this has always been like this? Would be nice if someone picks this up.
Comment 2 Jeremy Krieg CLA 2022-02-02 20:42:41 EST
I suspect that it has probably always been like this. I am exercising a part of the code that hasn't really been exercised before. Further investigation revealed that there may be some other duplicate removal further up the classpath resolution chain which might be causing issues too.

In an effort to work around this limitation, I rewrote the container to compute the expanded classpath directly so that I could bypass the export/computeExpandedClasspath() mechanism. 

My first attempted implemented the first of the two possible solutions: ie, including the dependency each time for each set of access rules. However, although the multiple entries appeared in the build path configuration window, the package explorer only showed the dependency appearing once. Not sure if this is further classpath processing removing it *after* my container has resolved, or if the GUI is removing the duplicate.

So my current approach is to include each dependency once and merge the access rules. Early indications are that this will work, but I'm still wrestling with it.

Another idea I toyed with was creating a virtual resource for each unique set of access rules, which points to the same physical resource. The hope was that the duplicate removal would then consider them to be unique libraries and not remove them.
Comment 3 Eclipse Genie CLA 2024-01-24 16:44:50 EST
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.