### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core.tests.model Index: src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java,v retrieving revision 1.164 diff -u -r1.164 JavaSearchBugsTests.java --- src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java 18 Feb 2009 12:08:58 -0000 1.164 +++ src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java 2 Mar 2009 16:59:31 -0000 @@ -10425,6 +10425,79 @@ } } +/** + * @bug 261722: [search] NPE after removing a project + * @test Ensure that no NPE occurs when project is deleted before the end of the search request + * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=261722" + */ +public void testBug261722() throws Exception { + IPath projectPath = null; + IJavaProject javaProject = null; + try { + // Create jar and project + final int MAX = 10; + final String[] pathsAndContents = new String[(1+MAX)*2]; + pathsAndContents[0] = "p261722/X.java"; + pathsAndContents[1] = "package p261722;\n" + + "public class X {}"; + for (int i=1; i<=MAX; i++) { + String className = (i<10) ? "X0"+i : "X"+i; + pathsAndContents[i*2] = "p261722/"+className+".java"; + pathsAndContents[i*2+1] = "package p261722;\n" + + "public class "+className+" extends X {}"; + } + javaProject = createJavaProject("P"); + projectPath = javaProject.getProject().getLocation(); + addLibrary(javaProject, "lib261722.jar", "lib261722.zip", pathsAndContents, "1.4"); + waitUntilIndexesReady(); + + // Search in separated thread + class TestSearchRequestor extends SearchRequestor { + int count = 0; + public void acceptSearchMatch(SearchMatch searchMatch) throws CoreException { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + // skip + } + this.count++; + } + } + final TestSearchRequestor requestor = new TestSearchRequestor(); + final SearchPattern pattern = SearchPattern.createPattern("X*", IJavaSearchConstants.DECLARATIONS, IJavaSearchConstants.TYPE, SearchPattern.R_PATTERN_MATCH); + final IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[] { javaProject }); + Runnable search = new Runnable() { + public void run() { + try { + new SearchEngine().search(pattern, new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() }, scope, requestor, null); + } catch (CoreException e) { + throw new RuntimeException(e); + } + } + }; + Thread thread = new Thread(search); + thread.start(); + + // Delete project in current thread + while (requestor.count < (MAX/3)) { + Thread.sleep(10); + } + deleteProject(javaProject); + + // Wait until search is finished + while (thread.isAlive()) { + Thread.sleep(100); + } + + // Verify search results + assertEquals("Unexpected matches count", MAX+1, requestor.count); + } finally { + if (projectPath != null) { + deleteFile("/P/lib261722.jar"); + deleteFile("/P/lib261722.zip"); + } + } +} /** * @bug 265065: [search] java.lang.ClassCastException while running "Refactor...Extract Class" #P org.eclipse.jdt.core Index: search/org/eclipse/jdt/internal/core/search/matching/PossibleMatch.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PossibleMatch.java,v retrieving revision 1.30 diff -u -r1.30 PossibleMatch.java --- search/org/eclipse/jdt/internal/core/search/matching/PossibleMatch.java 27 Jun 2008 16:03:59 -0000 1.30 +++ search/org/eclipse/jdt/internal/core/search/matching/PossibleMatch.java 2 Mar 2009 16:59:32 -0000 @@ -68,8 +68,10 @@ if (fileName == NO_SOURCE_FILE_NAME) return CharOperation.NO_CHAR; SourceMapper sourceMapper = this.openable.getSourceMapper(); - IType type = ((ClassFile) this.openable).getType(); - contents = sourceMapper.findSource(type, fileName); + if (sourceMapper != null) { + IType type = ((ClassFile) this.openable).getType(); + contents = sourceMapper.findSource(type, fileName); + } } else { contents = this.document.getCharContents(); }