### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: model/org/eclipse/jdt/internal/core/JavaProject.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java,v retrieving revision 1.404.2.1 diff -u -r1.404.2.1 JavaProject.java --- model/org/eclipse/jdt/internal/core/JavaProject.java 25 Jun 2008 08:20:20 -0000 1.404.2.1 +++ model/org/eclipse/jdt/internal/core/JavaProject.java 24 Oct 2008 13:11:10 -0000 @@ -17,6 +17,7 @@ import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.Map; import javax.xml.parsers.DocumentBuilder; @@ -2449,7 +2450,7 @@ * Resolve the given raw classpath. */ public IClasspathEntry[] resolveClasspath(IClasspathEntry[] rawClasspath) throws JavaModelException { - ArrayList resolvedEntries = new ArrayList(); + LinkedHashSet resolvedEntries = new LinkedHashSet(); for (int i = 0, length = rawClasspath.length; i < length; i++) { IClasspathEntry rawEntry = rawClasspath[i]; switch (rawEntry.getEntryKind()){ @@ -2525,7 +2526,7 @@ HashMap rawReverseMap = new HashMap(); Map rootPathToResolvedEntries = new HashMap(); - ArrayList resolvedEntries = new ArrayList(); + LinkedHashSet resolvedEntries = new LinkedHashSet(); int length = rawClasspath.length; for (int i = 0; i < length; i++) { 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.101 diff -u -r1.101 ClasspathEntry.java --- model/org/eclipse/jdt/internal/core/ClasspathEntry.java 27 May 2008 23:40:18 -0000 1.101 +++ model/org/eclipse/jdt/internal/core/ClasspathEntry.java 24 Oct 2008 13:11:09 -0000 @@ -1284,6 +1284,17 @@ if (rawClasspath == null) return JavaModelStatus.VERIFIED_OK; + // check duplicate entries on raw classpath only (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=175226 ) + int rawLength = rawClasspath.length; + HashSet pathes = new HashSet(rawLength); + for (int i = 0 ; i < rawLength; i++) { + IPath entryPath = rawClasspath[i].getPath(); + if (!pathes.add(entryPath)){ + String entryPathMsg = projectName.equals(entryPath.segment(0)) ? entryPath.removeFirstSegments(1).toString() : entryPath.makeRelative().toString(); + return new JavaModelStatus(IJavaModelStatusConstants.NAME_COLLISION, Messages.bind(Messages.classpath_duplicateEntryPath, new String[] {entryPathMsg, projectName})); + } + } + // retrieve resolved classpath IClasspathEntry[] classpath; try { @@ -1388,8 +1399,6 @@ for (int i = 0; i < outputCount; i++) allowNestingInOutputLocations[i] = true; } - HashSet pathes = new HashSet(length); - // check all entries for (int i = 0 ; i < length; i++) { IClasspathEntry entry = classpath[i]; @@ -1397,14 +1406,6 @@ IPath entryPath = entry.getPath(); int kind = entry.getEntryKind(); - // Build some common strings for status message - boolean isProjectRelative = projectName.equals(entryPath.segment(0)); - String entryPathMsg = isProjectRelative ? entryPath.removeFirstSegments(1).toString() : entryPath.makeRelative().toString(); - - // complain if duplicate path - if (!pathes.add(entryPath)){ - return new JavaModelStatus(IJavaModelStatusConstants.NAME_COLLISION, Messages.bind(Messages.classpath_duplicateEntryPath, new String[] {entryPathMsg, projectName})); - } // no further check if entry coincidates with project or output location if (entryPath.equals(projectPath)){ // complain if self-referring project entry Index: model/org/eclipse/jdt/core/IJavaProject.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaProject.java,v retrieving revision 1.100 diff -u -r1.100 IJavaProject.java --- model/org/eclipse/jdt/core/IJavaProject.java 27 May 2008 23:40:20 -0000 1.100 +++ model/org/eclipse/jdt/core/IJavaProject.java 24 Oct 2008 13:11:09 -0000 @@ -613,6 +613,11 @@ * variables are changed, the resolved classpath can become out of date. * Because of this, hanging on resolved classpath is not recommended. *

+ *

+ * Since 3.4.2, if the resolution creates duplicate entries + * (i.e. {@link IClasspathEntry entries} which are {@link Object#equals(Object)}), + * only the first one is added to the resolved classpath. + *

* * @param ignoreUnresolvedEntry indicates how to handle unresolvable * variables and containers; true indicates that missing #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.174.2.4 diff -u -r1.174.2.4 ClasspathTests.java --- src/org/eclipse/jdt/core/tests/model/ClasspathTests.java 9 Oct 2008 14:03:40 -0000 1.174.2.4 +++ src/org/eclipse/jdt/core/tests/model/ClasspathTests.java 24 Oct 2008 13:11:12 -0000 @@ -53,6 +53,7 @@ import org.eclipse.jdt.core.JavaConventions; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.tests.model.ClasspathInitializerTests.DefaultVariableInitializer; import org.eclipse.jdt.core.tests.util.Util; import org.eclipse.jdt.internal.core.ClasspathEntry; import org.eclipse.jdt.internal.core.JavaModelManager; @@ -3768,7 +3769,7 @@ * Ensures that a duplicate entry created by editing the .classpath is detected. * (regression test for bug 24498 Duplicate entries on classpath cause CP marker to no longer refresh) */ -public void testDuplicateEntries() throws CoreException { +public void testDuplicateEntries1() throws CoreException { try { IJavaProject project = this.createJavaProject("P", new String[] {"src"}, "bin"); this.editFile( @@ -3788,6 +3789,64 @@ this.deleteProject("P"); } } +/* + * Ensures that duplicate entries due to resolution are not reported + * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=175226 ) + */ +public void testDuplicateEntries2() throws CoreException { + try { + IJavaProject project = createJavaProject("P"); + VariablesInitializer.setInitializer(new DefaultVariableInitializer(new String[] {"TEST_LIB", "/P/lib.jar"})); + ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P", "/P/lib.jar"})); + createFile("/P/lib.jar", ""); + editFile( + "/P/.classpath", + "\n" + + "\n" + + " \n" + + " \n" + + " \n" + + "" + ); + assertMarkers( + "Unexpected markers", + "", + project); + } finally { + ContainerInitializer.setInitializer(null); + VariablesInitializer.setInitializer(null); + deleteProject("P"); + } +} +/* + * Ensures that the resolved classpath doesn't contain duplicate entries due to resolution + * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=175226 ) + */ +public void testDuplicateEntries3() throws CoreException { + try { + IJavaProject project = createJavaProject("P"); + VariablesInitializer.setInitializer(new DefaultVariableInitializer(new String[] {"TEST_LIB", "/P/lib.jar"})); + ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P", "/P/lib.jar"})); + createFile("/P/lib.jar", ""); + editFile( + "/P/.classpath", + "\n" + + "\n" + + " \n" + + " \n" + + " \n" + + "" + ); + assertClasspathEquals( + project.getResolvedClasspath(true), + "/P/lib.jar[CPE_LIBRARY][K_BINARY][isExported:false]" + ); + } finally { + ContainerInitializer.setInitializer(null); + VariablesInitializer.setInitializer(null); + deleteProject("P"); + } +} private void denseCycleDetection(final int numberOfParticipants) throws CoreException { final IJavaProject[] projects = new IJavaProject[numberOfParticipants];