Community
Participate
Working Groups
Build 20020515 - I had a binary project in my workspace, which was not a Java project (org.eclipse.platform.win32) - replaced it with source from repository - it's still not a Java project, according to the .project file and the project icon (no J decoration) - however, it got a .classpath file added Its .project file contains: <?xml version="1.0" encoding="UTF-8"?> <projectDescription> <name>org.eclipse.platform.win32</name> <comment></comment> <projects> </projects> <buildSpec> </buildSpec> <natures> <nature>org.eclipse.team.cvs.core.cvsnature</nature> </natures> </projectDescription> May be related to bug 16138
This is fairly annoying as it dirties the project when I haven't actually made any changes. If I try to delete the file it reappears immediately. If I delete the binary project first (including contents), then reload from source, the problem does not occur.
moving to JDT Core for investigation. could be related to 19058
Actually, this would rather be a duplicate of bug 18698
Nick, I don't see source for org.eclipse.platform.win32 in dev.eclipse.org (this project contains no .java file). What are your exact steps?
Correct. It has no .java files because it's not a Java project. However, it still gets a .classpath when loaded from the repository. Still occurs on F2. The steps are: - import org.eclipse.platform.win32 as a binary project (using PDE importer) - switch to Navigator view to see it - load org.eclipse.platform.win32 from dev.eclipse.org using CVS repositories view - notice that it now has a .classpath file - notice that the .project file does not include the Java nature. Philippe says this is a dup of bug 18698, which has apparently been fixed since F2.
This is not a dup of bug 18698 as I can reproduce in our latest. Note that when the project was imported using PDE import, it was given the java nature and a .classpath file was created. When the project is imported from the repository, it looses its java nature BUT the .classpath is not removed.
Simpler test case: 1. Create Java project Observe: a .classpath is created 2. Edit .project file and remove the java builder and java nature Observe: the .classpath is still present.
Will consider post 2.0.
This is a really a PDE problem then. It shouldn't generate a .classpath if it's not a Java project. Leaving PR here though since you might consider (2) a JDT Core issue. Not critical for 2.0.
*** Bug 20485 has been marked as a duplicate of this bug. ***
Actually, I didn't realize (even if Nick said it :-) that the user could not remove the .classpath at all (it is constantly recreated). Reconsidering for 2.0.
Simpler test case is: 1. Create simple project 2. Add .classpath file in this project 3. Try to delete the .classpath file Observe: The .classpath file is recreated right away.
Problem is with DeltaProcessor.performPreBuildCheck which traverses even non- java project. Proposed fix: /** * Check whether the updated file is affecting some of the properties of a given project (like * its classpath persisted as a file). * Also force classpath problems to be refresh if not running in autobuild mode. * NOTE: It can induce resource changes, and cannot be called during POST_CHANGE notification. * */ public void performPreBuildCheck( IResourceDelta delta, IJavaElement parent) { IResource resource = delta.getResource(); IJavaElement element = JavaCore.create(resource); boolean processChildren = false; switch (resource.getType()) { case IResource.ROOT : if (delta.getKind() == IResourceDelta.CHANGED) { processChildren = true; } break; case IResource.PROJECT : if (delta.getKind() == IResourceDelta.CHANGED && this.hasJavaNature(resource)) { processChildren = true; } break; case IResource.FILE : if (parent.getElementType() == IJavaElement.JAVA_PROJECT) { IFile file = (IFile) resource; JavaProject project = (JavaProject) parent; /* check classpath property file change */ QualifiedName classpathProp; if (file.getName().equals( project.computeSharedPropertyFileName( classpathProp = project.getClasspathPropertyName()))) { switch (delta.getKind()) { case IResourceDelta.REMOVED : // recreate one based on in-memory path try { project.saveClasspath(project.getRawClasspath(), project.getOutputLocation()); } catch (JavaModelException e) { if (project.getProject().isAccessible()) { Util.log(e, "Could not save classpath for "+ project.getPath()); //$NON- NLS-1$ } } break; case IResourceDelta.CHANGED : if ((delta.getFlags() & IResourceDelta.CONTENT) == 0) break; // only consider content change case IResourceDelta.ADDED : // check if any actual difference project.flushClasspathProblemMarkers(false, true); try { // force to (re)read the property file IClasspathEntry[] fileEntries = null; try { String fileClasspathString = project.loadClasspath(); if (fileClasspathString != null) { fileEntries = project.readPaths(fileClasspathString); } } catch (JavaModelException e) { if (project.getProject().isAccessible()) { Util.log(e, "Exception while retrieving "+ project.getPath() //$NON-NLS-1$ +"/.classpath, ignore change"); //$NON-NLS-1$ } project.createClasspathProblemMarker( Util.bind("classpath.cannotReadClasspathFile", project.getElementName ()), //$NON-NLS-1$ IMarker.SEVERITY_ERROR, false, // cycle error true); // file format error } catch (IOException e) { if (project.getProject().isAccessible()) { Util.log(e, "Exception while retrieving "+ project.getPath() //$NON-NLS-1$ +"/.classpath, ignore change"); //$NON-NLS-1$ } project.createClasspathProblemMarker( Util.bind("classpath.cannotReadClasspathFile", project.getElementName ()), //$NON-NLS-1$ IMarker.SEVERITY_ERROR, false, // cycle error true); // file format error } if (fileEntries == null) break; // could not read, ignore if (project.isClasspathEqualsTo(project.getRawClasspath(), project.getOutputLocation(), fileEntries)) break; // will force an update of the classpath/output location based on the file information // extract out the output location IPath outputLocation = null; if (fileEntries != null && fileEntries.length > 0) { IClasspathEntry entry = fileEntries[fileEntries.length - 1]; if (entry.getContentKind() == ClasspathEntry.K_OUTPUT) { outputLocation = entry.getPath(); IClasspathEntry[] copy = new IClasspathEntry[fileEntries.length - 1]; System.arraycopy(fileEntries, 0, copy, 0, copy.length); fileEntries = copy; } } // restore output location if (outputLocation == null) { outputLocation = SetClasspathOperation.ReuseOutputLocation; } project.setRawClasspath( fileEntries, outputLocation, null, // monitor true, // canChangeResource false, // forceSave project.getResolvedClasspath(true), // ignoreUnresolvedVariable true, // needCycleCheck true); // needValidation } catch (RuntimeException e) { // setRawClasspath might fire a delta, and a listener may throw an exception if (project.getProject().isAccessible()) { Util.log(e, "Could not set classpath for "+ project.getPath()); //$NON- NLS-1$ } break; } catch (CoreException e) { // happens if the .classpath could not be written to disk if (project.getProject().isAccessible()) { Util.log(e, "Could not set classpath for "+ project.getPath()); //$NON- NLS-1$ } break; } } } } break; } if (processChildren) { IResourceDelta[] children = delta.getAffectedChildren(); for (int i = 0; i < children.length; i++) { performPreBuildCheck(children[i], element); } } }
Note that with this fix, the .classpath is not deleted when the project looses its java nature, but the user CAN now delete it manually.
Does it also prevent the project from being marked dirty when converted from binary to source? I actually care more about the dirty indication than the free .classpath file.
I'll assume you convert the project from binary to source by checking out the project as you first described. In this case, the .classpath is removed (I guess by Team) and it is not being recreated, so the project is not dirty.
Correct, when you do a CVS Checkout from the repo browser, all files (but not the project itself) are deleted and new ones written. Preventing the re-generation of the .classpath is goodness.
Fix is trivial, simply ignore delta on .classpath file if not belong to project with java nature. Consequences are fairly nasty if not fixed, .classpath file is recreated instantaneously and causing confusion.
Should fix for F4
Indeed the fix is trivial and should be fixed for F4.
The problem does not exists in 1.0.
Entered bug 20708 to reflect that JDT/Core still needs to remove the .classpath file when a project looses its java nature.
Fix got approved, released in 20020620.
Verified.