Community
Participate
Working Groups
If a container is updated, and the change was that a project was added or removed from the container, there is no kind of notification to indicate that the project's classpath (the one with the container, not the project being added/removed) has changed in any way. If the container added/removed a jar, then such a notification of an add/remove of the jar from the classpath is notified. We need to track changes to the classpath and we aren't able to see these because of this lack of notification. An example to try is to add a listener to a plugin project, then using the manifest editor you should add a another plugin project as a required plugin. The only notification sent is that the manifest file itself was changed. But this is not something we can listen for because that is not generic for containers, only for the PDE. If you instead used the wizards to change the .classpath file to add/remove a project, you at least get a notification that the classpath has changed, even though you don't get a notification that the project was added/removed, but at least there is a notification.
Could this bug be looked at for 3.2.1. The VE team needs this fixed in order to fix one of their critical bugs.
Java element delta notifications are only sent if the change modifies the Java model. Adding/removing a project reference to/from a container doesn't change the Java model in the sense that the tree rooted at IJavaModel is the same before and after the change. You're seeing a F_CLASSPATH_CHANGED notification when changing the .classpath directly indicating that the *raw* classpath (IJavaProject#getRawClasspath()) has changed. There is no (and never has been any) notification for changes to the *resolved* classpath (IJavaProject#getResolvedClasspath()). Adding such notification would involve adding a new flag to IJavaElementDelta. Since 3.2.1 is a bug fix release, I see litle chance that this happens.
Changes to the resolved classpath are already notified. For example changing what a variable points to, is changing the resolved classpath. The unresolved classpath has not changed and is still the same. Even in a classpath container, if the container decides to add/remove a jar, this is notified, even though that is only on the resolved classpath and not the unresolved classpath. Notifying that a jar/folder has been added/removed from a classpath but not notifying on projects is kind of half-useful. There are notifications that the classpath has changed EXECPT if it changed due to a project? It begs the question of why bother notifing at all. So it just boils down to there not being any notifications of projects being added/removed from a classpath. I'd be happy at this time with just a simple notification that the project's classpath has changed when a container directly in the project adds/removes a project. That is what I need to know. There is already a flag on project delta for classpath changed. It would be a plus to know the project added/removed, but I can live at this time not having that. It would just make the program inefficient because I would have to then go and re-resolve the entire classpath to find the actual project added/removed.
(In reply to comment #3) > Changes to the resolved classpath are already notified. For example changing > what a variable points to, is changing the resolved classpath. The unresolved > classpath has not changed and is still the same. Even in a classpath container, > if the container decides to add/remove a jar, this is notified, even though > that is only on the resolved classpath and not the unresolved classpath. I believe that this kind of change is reported using an IPackageFragmentRoot delta, no using a classpath change (F_CLASSPATH_CHANGE) delta. > Notifying that a jar/folder has been added/removed from a classpath but not > notifying on projects is kind of half-useful. There are notifications that the > classpath has changed EXECPT if it changed due to a project? It begs the > question of why bother notifing at all. Only changes to the raw classpath are reported. Changes to the resolved classpath are not reported directly (i.e. there is no F_RESOLVED_CLASSPATH_CHANGED flag). Only changes to the Java model resulting from the resolved classpath change are reported. In the case of a project reference addition/removal, the Java model is not changed, thus no notification is sent. > So it just boils down to there not being any notifications of projects being > added/removed from a classpath. I'd be happy at this time with just a simple > notification that the project's classpath has changed when a container directly > in the project adds/removes a project. That is what I need to know. There is > already a flag on project delta for classpath changed. Unfortunately this flag (F_CLASSPATH_CHANGED) - even if badly named - is specified to report raw classpath change only. > It would be a plus to know the project added/removed, but I can live at this > time not having that. It would just make the program inefficient because I > would have to then go and re-resolve the entire classpath to find the actual > project added/removed. Agreed this is a valid feature request.
> It would be a plus to know the project added/removed, but I can live at this > time not having that. It would just make the program inefficient because I > would have to then go and re-resolve the entire classpath to find the actual > project added/removed. >> Agreed this is a valid feature request. I meant I can't make it work the way it is currently. :-( Without knowing that a project has been added/removed I can't fix the problem I am having. What I meant was just having a notification that A change had occurred, not necessarily exactly what project was added/removed would at least allow me to continue.
Rich, one possible workaround for you would be to listen to resource changes as well and check for project description changes (see IResourceDelta#DESCRIPTION). When a project is added/removed to/from a container, the project description of the corresponding Java project is changed to update its dynamic references (see IProjectDescription#getDynamicReferences()).
I don't think it does that anymore. I ran some tests and watched what was sent. Take for example the PDE container. If I had two projects that were plugin projects, and then started listening to changes. Then using the manifest editor I added one plugin as a required plugin. When I save the manifest the only notification that goes out is that the MANIFEST.MF has changed. JDT no longer updates the project description file for required projects. That was too brittle and was removed in Eclipse 3.2.
Right, the .project file is not updated. Still the dynamic references (as oposed to the 'hard' references) are updated in memory, and a project description changes should still be notified.
Ok, that's a promising approach, though quite complicated. The actual notification of the project description change due to a container changing doesn't go out until AFTER the build is complete. So I wouldn't see the change until much later. Normally I'm listening on POST_CHANGE notifications, but the dynamic description change isn't processed until the build for container changes. Projects adding/removing/closing/opening description notifications do go right away. I'll need to listen for both POST_CHANGE and POST_BUILD. I'll see if this can be made to work. Thanks. Never heard of the dynamic references before.
For 3.3, we should investigate unifying the change notification for easing clients ' experience. From Rich Kulp: "I think it should be an enhancement. It's a lot of extra work using the description when you already know what project was added/removed (because you already handle the addtional package fragment roots that this would entail being added/removed). It should be in one place."
Removing target milestone as this didn't make it in 3.3
*** Bug 189987 has been marked as a duplicate of this bug. ***
Tagging for 3.4. Also see bug 189987 for nasty consequences on client who try to be optimized (and rely heavily on our deltas).
Created attachment 79123 [details] Proposed fix and regression tests The new tests are ClasspathTests#testAddProjectToContainer() and testChangeRawButNotResolvedClasspath(). Other tests have been touched to take the new flag into account.
Fix and tests released for 3.4M3 in HEAD.
Question: How are F_RESOLVED_CLASSPATH_CHANGED and F_CLASSPATH_CHANGED related? Is a.) F_RESOLVED_CLASSPATH_CHANGED is 'extending' F_CLASSPATH_CHANGED (say, when F_CLASSPATH_CHANGED is set also F_RESOLVED_CLASSPATH_CHANGED will be set) or is b.) F_RESOLVED_CLASSPATH_CHANGED just covering changes in containers? A clarification in the Javadoc would be good. The current explanation is not really clear to me: * Note this is independent from {@link #F_CLASSPATH_CHANGED} which indicates * that the raw classpath has changed.
(In reply to comment #16) > Question: How are F_RESOLVED_CLASSPATH_CHANGED and F_CLASSPATH_CHANGED related? > Is > a.) F_RESOLVED_CLASSPATH_CHANGED is 'extending' F_CLASSPATH_CHANGED (say, when > F_CLASSPATH_CHANGED is set also F_RESOLVED_CLASSPATH_CHANGED will be set) > or is > b.) F_RESOLVED_CLASSPATH_CHANGED just covering changes in containers? > > A clarification in the Javadoc would be good. The current explanation is not > really clear to me: > * Note this is independent from {@link #F_CLASSPATH_CHANGED} which indicates > * that the raw classpath has changed. > Would that clarify things ? * Note that F_RESOLVED_CLASSPATH_CHANGED and F_CLASSPATH_CHANGED are not related. * The resolved classpath can change without the raw classpath changing (e.g. * if a container resolves to a different set of classpath entries), and * conversely the raw classpath can change without the resolved classpath * changing.
Yes, the example helps. But wouldn't say 'not related'. 'independant' was better. Here's my suggestion: * F_CLASSPATH_CHANGED is set when there are changes to the raw class path ({@link IJavaProject.getRawClasspath()}). * This flag is only valid if the element is an {@link IJavaProject}. * Also see {@link F_RESOLVED_CLASSPATH_CHANGED}, which is set when there's a change to the resolved class path {@link IJavaProject.getResolvedClasspath()} * The resolved classpath can change without the raw classpath changing (e.g. * if a container resolves to a different set of classpath entries), and * conversely, its possible to construct a case where the raw classpath can change without the resolved classpath changing.
Thanks Martin. Suggestion released in HEAD.
Verified for 3.4M3 using I20071029-0010 build.