### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: model/org/eclipse/jdt/internal/core/ClasspathEntry.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java,v retrieving revision 1.128 diff -u -r1.128 ClasspathEntry.java --- model/org/eclipse/jdt/internal/core/ClasspathEntry.java 14 Feb 2011 04:50:02 -0000 1.128 +++ model/org/eclipse/jdt/internal/core/ClasspathEntry.java 14 Oct 2011 15:54:15 -0000 @@ -1827,6 +1827,9 @@ * @return a java model status describing the problem related to this classpath entry if any, a status object with code IStatus.OK if the entry is fine */ public static IJavaModelStatus validateClasspathEntry(IJavaProject project, IClasspathEntry entry, boolean checkSourceAttachment, boolean referredByContainer){ + if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) { + JavaModelManager.getJavaModelManager().removeFromInvalidArchiveCache(entry.getPath()); + } IJavaModelStatus status = validateClasspathEntry(project, entry, null, checkSourceAttachment, referredByContainer); // https://bugs.eclipse.org/bugs/show_bug.cgi?id=171136 and https://bugs.eclipse.org/bugs/show_bug.cgi?id=300136 // Ignore class path errors from optional entries. Index: model/org/eclipse/jdt/internal/core/DeltaProcessor.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java,v retrieving revision 1.346 diff -u -r1.346 DeltaProcessor.java --- model/org/eclipse/jdt/internal/core/DeltaProcessor.java 9 Sep 2011 09:37:22 -0000 1.346 +++ model/org/eclipse/jdt/internal/core/DeltaProcessor.java 14 Oct 2011 15:54:15 -0000 @@ -954,7 +954,7 @@ // project does not exist -> ignore continue; } - boolean hasChainedJar = false; + boolean deltaContainsModifiedJar = false; for (int j = 0; j < entries.length; j++){ if (entries[j].getEntryKind() == IClasspathEntry.CPE_LIBRARY) { IPath entryPath = entries[j].getPath(); @@ -1024,7 +1024,7 @@ System.out.println("- External JAR ADDED, affecting root: "+root.getElementName()); //$NON-NLS-1$ } elementAdded(root, null, null); - hasChainedJar |= !this.manager.isNonChainingJar(entryPath); + deltaContainsModifiedJar = true; this.state.addClasspathValidation(javaProject); // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=185733 hasDelta = true; } else if (status == EXTERNAL_JAR_CHANGED) { @@ -1033,7 +1033,7 @@ System.out.println("- External JAR CHANGED, affecting root: "+root.getElementName()); //$NON-NLS-1$ } contentChanged(root); - hasChainedJar |= !this.manager.isNonChainingJar(entryPath); + deltaContainsModifiedJar = true; hasDelta = true; } else if (status == EXTERNAL_JAR_REMOVED) { PackageFragmentRoot root = (PackageFragmentRoot) javaProject.getPackageFragmentRoot(entryPath.toString()); @@ -1041,7 +1041,7 @@ System.out.println("- External JAR REMOVED, affecting root: "+root.getElementName()); //$NON-NLS-1$ } elementRemoved(root, null, null); - hasChainedJar |= !this.manager.isNonChainingJar(entryPath); + deltaContainsModifiedJar = true; this.state.addClasspathValidation(javaProject); // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=185733 hasDelta = true; } @@ -1049,7 +1049,7 @@ } } - if (hasChainedJar) { + if (deltaContainsModifiedJar) { javaProject.resetResolvedClasspath(); } } Index: model/org/eclipse/jdt/internal/core/JavaModelManager.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java,v retrieving revision 1.469 diff -u -r1.469 JavaModelManager.java --- model/org/eclipse/jdt/internal/core/JavaModelManager.java 23 Aug 2011 18:04:23 -0000 1.469 +++ model/org/eclipse/jdt/internal/core/JavaModelManager.java 14 Oct 2011 15:54:15 -0000 @@ -3086,6 +3086,12 @@ return this.invalidArchives != null && this.invalidArchives.contains(path); } + public void removeFromInvalidArchiveCache(IPath path) { + if (this.invalidArchives != null) { + this.invalidArchives.remove(path); + } + } + public void setClasspathBeingResolved(IJavaProject project, boolean classpathIsResolved) { if (classpathIsResolved) { getClasspathBeingResolved().add(project); #P org.eclipse.jdt.core.tests.model Index: src/org/eclipse/jdt/core/tests/model/ClasspathTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java,v retrieving revision 1.226 diff -u -r1.226 ClasspathTests.java --- src/org/eclipse/jdt/core/tests/model/ClasspathTests.java 4 May 2011 14:47:25 -0000 1.226 +++ src/org/eclipse/jdt/core/tests/model/ClasspathTests.java 14 Oct 2011 15:54:17 -0000 @@ -249,6 +249,7 @@ suite.addTest(new ClasspathTests("testInvalidClasspath2")); suite.addTest(new ClasspathTests("testInvalidExternalClassFolder")); suite.addTest(new ClasspathTests("testInvalidExternalJar")); + suite.addTest(new ClasspathTests("testTransitionFromInvalidToValidJar")); suite.addTest(new ClasspathTests("testInvalidInternalJar1")); suite.addTest(new ClasspathTests("testInvalidInternalJar2")); suite.addTest(new ClasspathTests("testInvalidSourceFolder")); @@ -334,6 +335,7 @@ suite.addTest(new ClasspathTests("testBug321170")); suite.addTest(new ClasspathTests("testBug229042")); suite.addTest(new ClasspathTests("testBug274737")); + suite.addTest(new ClasspathTests("testBug357425")); return suite; } public void setUpSuite() throws Exception { @@ -4201,6 +4203,41 @@ } } /* + * Ensures that validateClasspathEntry() sees a transition from an invalid/missing jar to a valid jar. + */ +public void testTransitionFromInvalidToValidJar() throws CoreException, IOException { + String transitioningJarName = "transitioningJar.jar"; + String transitioningJar = getExternalPath() + transitioningJarName; + String nonExistingJar = getExternalPath() + "nonExisting.jar"; + IClasspathEntry transitioningEntry = JavaCore.newLibraryEntry(new Path(transitioningJar), null, null); + IClasspathEntry nonExistingEntry = JavaCore.newLibraryEntry(new Path(nonExistingJar), null, null); + + try { + IJavaProject proj = createJavaProject("P", new String[] {}, new String[] {transitioningJar, nonExistingJar}, "bin"); + + IJavaModelStatus status1 = ClasspathEntry.validateClasspathEntry(proj, transitioningEntry, false, false); + IJavaModelStatus status2 = ClasspathEntry.validateClasspathEntry(proj, nonExistingEntry, false, false); + assertFalse("Non-existing jar should be invalid", status1.isOK()); + assertFalse("Non-existing jar should be invalid", status2.isOK()); + + Util.createJar( + new String[0], + new String[] { + "META-INF/MANIFEST.MF", + "Manifest-Version: 1.0\n" + }, + transitioningJar, + JavaCore.VERSION_1_4); + status1 = ClasspathEntry.validateClasspathEntry(proj, transitioningEntry, false, false); + status2 = ClasspathEntry.validateClasspathEntry(proj, nonExistingEntry, false, false); + assertTrue("Existing jar should be valid", status1.isOK()); + assertFalse("Non-existing jar should be invalid", status2.isOK()); + } finally { + deleteExternalResource(transitioningJarName); + deleteProject("P"); + } +} +/* * Ensures that a non existing internal jar cannot be put on the classpath. */ public void testInvalidInternalJar1() throws CoreException { @@ -7190,4 +7227,46 @@ } } +/* + * Ensures that the correct delta is reported when changing the Class-Path: clause + * of an external jar from not containing a chained jar to containing a chained jar. + * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=357425) + */ +public void testBug357425() throws Exception { + try { + IJavaProject p = createJavaProject("P"); + addExternalLibrary(p, getExternalResourcePath("lib357425_a.jar"), new String[0], + new String[] { + "META-INF/MANIFEST.MF", + "Manifest-Version: 1.0\n" + }, + JavaCore.VERSION_1_4); + refreshExternalArchives(p); + + startDeltas(); + org.eclipse.jdt.core.tests.util.Util.createJar(new String[0], + new String[] { + "META-INF/MANIFEST.MF", + "Manifest-Version: 1.0\n" + + "Class-Path: lib357425_b.jar\n", + }, + getExternalResourcePath("lib357425_a.jar"), + JavaCore.VERSION_1_4); + createExternalFile("lib357425_b.jar", ""); + + refreshExternalArchives(p); + assertDeltas( + "Unexpected delta", + "P[*]: {CHILDREN | RESOLVED CLASSPATH CHANGED}\n" + + " "+ getExternalPath() + "lib357425_a.jar[*]: {CONTENT | REORDERED | ARCHIVE CONTENT CHANGED}\n" + + " "+ getExternalPath() + "lib357425_b.jar[+]: {}" + ); + } finally { + stopDeltas(); + deleteProject("P"); + deleteExternalResource("lib357425_a.jar"); + deleteExternalResource("lib357425_b.jar"); + } +} + }