Community
Participate
Working Groups
Build 20020530 Found the bug while testing archive refresh. 0. Import x.jar from external location and add the JAR to the build path ==> x.jar as INTERNAL JAR 1. Drill into a package where class C is visible 2. Remove x.jar from build path (not from project) 3. Add x.jar as EXTERNAL JAR 4. Drill into the package where class C is visible 5. Delete C from the external JAR 6. Refresh the project ==> C remains visible Same scenario works if started with 3.
If enabling delta tracing, you'll see that the correct delta got notified. Java Model[*]: {CHILDREN} Proj1[*]: {CHILDREN} D:/zz/x.jar[*]: {CONTENT | ARCHIVE CONTENT CHANGED} However, the package view listener doesn't check for this change, and thus doesn't refresh. I got it to work fine when changing JavaElementContentProvider#processDelta as follow (BTW this method would benefit from being rewritten using a switch statement): [ /** * Processes a delta recursively. When more than two children are affected the * tree is fully refreshed starting at this node. The delta is processed in the * current thread but the viewer updates are posted to the UI thread. */ protected void processDelta(IJavaElementDelta delta) throws JavaModelException { int kind= delta.getKind(); int flags= delta.getFlags(); IJavaElement element= delta.getElement(); if (!getProvideWorkingCopy() && isWorkingCopy(element)) return; if (element != null && element.getElementType() == IJavaElement.COMPILATION_UNIT && !element.getJavaProject().isOnClasspath (element)) return; // handle open and closing of a solution or project if (((flags & IJavaElementDelta.F_CLOSED) != 0) || ((flags & IJavaElementDelta.F_OPENED) != 0)) { postRefresh(element); return; } if (kind == IJavaElementDelta.REMOVED) { // when a working copy is removed all we have to do // is to refresh the compilation unit if (isWorkingCopy(element)) { refreshWorkingCopy((IWorkingCopy)element); return; } Object parent= internalGetParent(element); postRemove(element); if (parent instanceof IPackageFragment) updatePackageIcon((IPackageFragment)parent); // we are filtering out empty subpackages, so we // a package becomes empty we remove it from the viewer. if (isPackageFragmentEmpty(element.getParent())) { if (fViewer.testFindItem(parent) != null) postRefresh(internalGetParent(parent)); } return; } if (kind == IJavaElementDelta.ADDED) { // when a working copy is added all we have to do // is to refresh the compilation unit if (isWorkingCopy(element)) { refreshWorkingCopy((IWorkingCopy)element); return; } Object parent= internalGetParent(element); // we are filtering out empty subpackages, so we // have to handle additions to them specially. if (parent instanceof IPackageFragment) { Object grandparent= internalGetParent(parent); // 1GE8SI6: ITPJUI:WIN98 - Rename is not shown in Packages View // avoid posting a refresh to an unvisible parent if (parent.equals(fInput)) { postRefresh(parent); } else { // refresh from grandparent if parent isn't visible yet if (fViewer.testFindItem(parent) == null) postRefresh(grandparent); else { postRefresh(parent); } } } else { postAdd(parent, element); } } if (element instanceof ICompilationUnit) { if (getProvideWorkingCopy()) { IJavaElement original= ((IWorkingCopy) element).getOriginalElement(); if (original != null) element= original; } if (kind == IJavaElementDelta.CHANGED) { postRefresh(element); return; } } // we don't show the contents of a compilation or IClassFile, so don't go any deeper if ((element instanceof ICompilationUnit) || (element instanceof IClassFile)) return; if (isClassPathChange(delta)) { // throw the towel and do a full refresh of the affected java project. postRefresh(element.getJavaProject()); } if (delta.getResourceDeltas() != null) { IResourceDelta[] rd= delta.getResourceDeltas(); for (int i= 0; i < rd.length; i++) { processResourceDelta(rd[i], element); } } if (element instanceof IPackageFragmentRoot && kind == IJavaElementDelta.CHANGED && flags == (IJavaElementDelta.F_CONTENT | IJavaElementDelta.F_ARCHIVE_CONTENT_CHANGED)){ postRefresh(element); return; } IJavaElementDelta[] affectedChildren= delta.getAffectedChildren (); if (affectedChildren.length > 1) { // a package fragment might become non empty refresh from the parent if (element instanceof IPackageFragment) { IJavaElement parent= (IJavaElement) internalGetParent(element); // 1GE8SI6: ITPJUI:WIN98 - Rename is not shown in Packages View // avoid posting a refresh to an unvisible parent if (element.equals(fInput)) { postRefresh(element); } else { postRefresh(parent); } return; } // more than one child changed, refresh from here downwards if (element instanceof IPackageFragmentRoot) postRefresh(skipProjectPackageFragmentRoot ((IPackageFragmentRoot)element)); else postRefresh(element); return; } for (int i= 0; i < affectedChildren.length; i++) { processDelta(affectedChildren[i]); } } ]
That's what we see too BUT when getting the JAR it seams to return old (cached?) values.
Created attachment 1136 [details] p1.zip lib containing X and Y
Created attachment 1137 [details] p1.zip lib containing only X type
Using attached archives, and if doing precisely: 0. Import p1.zip from external location and add the JAR to the build path ==> p1.zip as INTERNAL JAR 1. Drill into a package where class Y is visible 2. Remove p1.zip from build path (not from project) 3. Add p1.zip as EXTERNAL JAR 4. Drill into the package where class Y is visible 5. Switch p1.zip with the one not containing X and Y 6. Refresh the project ==> Y is gone
dani can you pls try reproduce
I can reproduce it every time (note: I test on what's in JDT HEAD plus newest jdtcore export from Dirk). I do the steps quickly after each other. 0. Export attached x.jar to c:\ 1. Fresh workspace 2. Create Ja project "JUnit" 3. Import x.jar from file system c:\ (as single file) 4. Add x.jar to the build path 5. Open junit.samples.VectorTest 6. Remove x.jar from the build path (press OK) 7. Add external c:\JAR x.jar to the build path 8. Open junit.samples.VectorTest 9. Open c:\x.jar with winzip, delete VectorTest.java, close winzip 10. Select project "JUnit" in packages view press F5 ==> VectorTest remains in Packages view Note: Close the project, reopen it: now VectorTest is gone
Created attachment 1139 [details] x.jar
Aahh - the main difference is that you switch the zips while I EDIT the external zip.
No the problem is that the external JAR is located in the root folder, and that platform API IContainer#findMember("c:/x.jar") may answer the corresponding internal JAR instead. When trying to reproduce, my jar was located in a "c:/zz/x.jar". Now we found one issue in our code, which was incorrectly calling for for IProject.findMember(...) instead of using the root. This is why we did misbehave in this one case. So this defect is fixed, but the platform bug remains (bug 17209). Moving to platform/core for further investigation
Verified