Community
Participate
Working Groups
Build ID: M20070212-1330 Steps To Reproduce: My source tree looks like: foo/ /src /com /bar etc /qa /src /com /bar etc 1. Make a Project with source pointing to /foo 2. Link folder qa to project, and call it "qa". Of course, set up exclusion filter on the main project to exclude qa/ 3. Everything compiles nicely into a single proper output tree 4. But if you try to refactor, you get an error that "qa.com.foo.Baz cannot be found". Likewise, when you do a Reference Search, the references show up as "qa.com.foo.Baz", a question mark for the package icon, but the file itself is availabel and can be opened. More information:
What kind of refactoring do you do ?
Oh, anything, really. Let's say, "rename a method". Just make sure that the method being renamed belongs to a class defined in "foo/src/com/bar/..." tree, and it is called from a class that belongs to "foo/qa/src/com/bar/..." tree. The root cause seems to be in how Eclipse is resolving package names for classes on the linked folder called "qa". Even without refactoing, when you do a Reference Search, the references show up as "qa.com.foo.Baz", and a question mark for the package icon is a tell-tale sign that something is looking for a package name that starts with "qa" and cannot find it.
The problem with search is a separate issue. Please enter a separate bug report. Moving to JDT/UI for investigating why the rename refactoring fails this way.
Can you zip up the example project and attach it? I don't understand how exactly your project setup looks like.
Created attachment 64079 [details] Sample project to illustrate the problem Expand this zip file. The project file is in prj/src/.project . proj/qa/src must be linked as "qa". Open class Foo. If you try "refactor"/"rename" method someMethod() to fooMethod(), you would see that the invocation in qa/com.bar.Bar has not been updated. If you try "refactor"/"change method signature" and change the name of the method from someMethod() to fooMethod() there, you get: "An unexpected exception occured while prforming the refactorying. See error log for more details. Reason: qa.com.bar [in <project root> [in Project]] does not exist" Here is the error log entry. Java Model Exception: Java Model Status [qa.com.bar [in <project root> [in Project]] does not exist] at org.eclipse.jdt.internal.core.JavaElement.newNotPresentException(JavaElement.java:485) at org.eclipse.jdt.internal.core.PackageFragment.buildStructure(PackageFragment.java:72) at org.eclipse.jdt.internal.core.Openable.generateInfos(Openable.java:229) at org.eclipse.jdt.internal.core.Openable.openParent(Openable.java:420) at org.eclipse.jdt.internal.core.CompilationUnit.openParent(CompilationUnit.java:1065) at org.eclipse.jdt.internal.core.Openable.generateInfos(Openable.java:218) at org.eclipse.jdt.internal.core.JavaElement.openWhenClosed(JavaElement.java:505) at org.eclipse.jdt.internal.core.JavaElement.getElementInfo(JavaElement.java:249) at org.eclipse.jdt.internal.core.JavaElement.getElementInfo(JavaElement.java:235) at org.eclipse.jdt.internal.core.Openable.getBuffer(Openable.java:255) at org.eclipse.jdt.core.dom.rewrite.ASTRewrite.rewriteAST(ASTRewrite.java:239) at org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite.attachChange(CompilationUnitRewrite.java:206) at org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite.createChange(CompilationUnitRewrite.java:172) at org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite.createChange(CompilationUnitRewrite.java:157) at org.eclipse.jdt.internal.corext.refactoring.structure.ChangeSignatureRefactoring.createChangeManager(ChangeSignatureRefactoring.java:1294) at org.eclipse.jdt.internal.corext.refactoring.structure.ChangeSignatureRefactoring.checkFinalConditions(ChangeSignatureRefactoring.java:812) at org.eclipse.ltk.core.refactoring.CheckConditionsOperation.run(CheckConditionsOperation.java:83) at org.eclipse.ltk.core.refactoring.CreateChangeOperation.run(CreateChangeOperation.java:118) at org.eclipse.ltk.core.refactoring.PerformChangeOperation.run(PerformChangeOperation.java:189) at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1737) at org.eclipse.ltk.internal.ui.refactoring.WorkbenchRunnableAdapter.run(WorkbenchRunnableAdapter.java:87) at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:113)
Thanks Igor, the sample project makes it much easier to reproduce: Extract the zip to C:\temp\ and import it as existing project (without copying). The problems in the refactorings are actually caused by problems in the search engine when searching for occurrences (in HEAD): - search for references to com.foo.Foo.someMethod() => correctly finds barMethod with handleIdentifier "=Project/qa<com.bar{Bar.java[Bar~barMethod" - search for occurrences of com.foo.Foo.someMethod() => finds declaration and a non-existing barMethod with handleIdentifier "=Project/<qa.com.bar{Bar.java[Bar~barMethod" There's a problem with "com.bar" in source folder "qa". Moving to core.
This is not a search issue as Search Engine correctly finds the reference to the method in Bar. The real problem comes from the HandleFactory.createOpenable(String , IJavaSearchScope) method. While searching just for reference, there's only one processed SearchDocument: /Project/qa/com/bar/Bar.java and the factory creates the handle in the correct package fragment root: the source folder 'qa'. But while renaming, JDT/UI calls Search Engine using a combined pattern to search for both declaration and references. So, there are two SearchDocument in the loop: /Project/com/foo/Foo.java /Project/qa/com/bar/Bar.java Then the factory, first creates the handle for Foo which is in the <default> package fragment root. So, when creating the handle for Bar, the following test: if (this.lastPkgFragmentRootPath == null || !(resourcePath.startsWith(this.lastPkgFragmentRootPath) && (rootPathLength = this.lastPkgFragmentRootPath.length()) > 0 && resourcePath.charAt(rootPathLength) == '/')) { is wrongly true and the <default> package is still used for this compilation although it should call the getPkgFragmentRoot(resourcePath) to get the correct package fragment root 'qa'...
Note that the source folder does not need to be linked. It fails the same way with simple following set-up: /P + qa (src folder) + com + bar + Bar.java + com + foo + Foo.java + test + Test.java If in com.test.Test you have also a method calling Foo.someMethod(), then you can directly see the problem in Search view while searching for method references: /P - com.test - Test ^ testMethod() - ? qa.com.bar - ? Bar - ? barMethod()
Created attachment 86561 [details] Proposed fix and regression test
Fix and test released for 3.4M5
Verified for 3.4M5 using I20080204-0010