Community
Participate
Working Groups
When using the java source attachment the .classpath file should not hardcode the project name. sourcepath="/projectname/ext-dist/log4j-1.2.7.zip" This is a problem because we check in the .classpath file. Now anyone who doesn't name their project "projectname" will not be able to jump into that source. This is not the only issue it also becomes a problem if you have to work on multiple branchs and can not have two projects with the same name, although the non projectname named project would end up using the projectname source jar files this isn't a good thing since they could be different versions or no longer exist. The source path should assume the current project. The only work around seems to be to create another cvs project which contains only source jars but then even that fails to work if you are working on multiple versions where those version have changes in the source jar files.
You could use variables to abstract this information. Our assumption is that project names are stable (thus we support project name references for prerequisites). No plan to change this.
It is true that I could use a variable to abstract this information but I think the source library should default fall under the same category as the bytecode libraries. For instance to reference a byteclass library the .classpath file will use an entry like this: <classpathentry kind="lib" path="lib/log4j.jar"/> Note that the project the library is not contained in the path. Now to include the source for this library the entry changes to this: <classpathentry kind="lib" path="lib/log4j.jar" sourcepath="/projects/src-libs/log4j-1.2.7.zip"/> Note that now I do have to reference the project name. But let's ignore the unconsistant feel of this approach for the moment. Lets assume I have a product with one branch and the trunk. I initially create the product in cvs as "product" so my classpath file has the entry: sourcepath="/product/src-libs/log4j-1.2.7.zip". Now we finish that version of the product and that file is now part of the version1 branch. Both the head and the branch now have a .classpath file with sourcepath="/product/src-libs/log4j-1.2.7.zip". This works in the case of the head but now I check out the branch and it is referencing the source library from the head. This is a problem for many reasons - src lib could be updated/deleted/etc. Now the question is can using a variable to reference the product really help me. It would seem to me that the only way that using a variable would help me is if everytime after branching I created a new variable maybe VersionX and then updated every entry in the classpath to use that new variable. I think that is too much overhead and complicates the workflow a lot.
Actually, I see your original point now. The source attachment should be shortened in a project relative form as the library path is already. It should only include the project name if located outside of the referring project.
Patch on ClasspathEntry: /** * Returns the XML encoding of the class path. */ public Element elementEncode( Document document, IPath projectPath) throws JavaModelException { Element element = document.createElement("classpathentry"); // $NON-NLS-1$ element.setAttribute("kind", kindToString(this.entryKind)); //$NON-NLS-1$ IPath xmlPath = this.path; if (this.entryKind != IClasspathEntry.CPE_VARIABLE && this.entryKind != IClasspathEntry.CPE_CONTAINER) { // translate to project relative from absolute if (xmlPath.isAbsolute()) { if (projectPath != null && projectPath.isPrefixOf(xmlPath)) { if (xmlPath.segment(0).equals (projectPath.segment(0))) { xmlPath = xmlPath.removeFirstSegments(1); xmlPath = xmlPath.makeRelative (); } else { xmlPath = xmlPath.makeAbsolute (); } } } } element.setAttribute("path", xmlPath.toString()); //$NON-NLS-1$ // translate to project relative from absolute if (this.sourceAttachmentPath != null) { xmlPath = this.sourceAttachmentPath; if (projectPath != null && projectPath.isPrefixOf (xmlPath)) { if (xmlPath.segment(0).equals (projectPath.segment(0))) { xmlPath = xmlPath.removeFirstSegments (1); xmlPath = xmlPath.makeRelative(); } else { xmlPath = xmlPath.makeAbsolute(); } } element.setAttribute("sourcepath", xmlPath.toString ()); //$NON-NLS-1$ } if (this.sourceAttachmentRootPath != null) { element.setAttribute("rootpath", this.sourceAttachmentRootPath.toString()); //$NON-NLS-1$ } if (this.isExported) { element.setAttribute("exported", "true"); //$NON-NLS-1 $ //$NON-NLS-2$ } if (this.exclusionPatterns.length > 0) { StringBuffer excludeRule = new StringBuffer(10); for (int i = 0, max = this.exclusionPatterns.length; i < max; i++){ if (i > 0) excludeRule.append('|'); excludeRule.append(this.exclusionPatterns[i]); } element.setAttribute("excluding", excludeRule.toString ()); //$NON-NLS-1$ } if (this.specificOutputLocation != null) { IPath outputLocation = this.specificOutputLocation.removeFirstSegments(1); outputLocation = outputLocation.makeRelative(); element.setAttribute("output", outputLocation.toString ()); //$NON-NLS-1$ } return element; } public static IClasspathEntry elementDecode(Element element, IJavaProject project) { IPath projectPath = project.getProject().getFullPath(); String kindAttr = element.getAttribute("kind"); //$NON-NLS-1$ String pathAttr = element.getAttribute("path"); //$NON-NLS-1$ // ensure path is absolute IPath path = new Path(pathAttr); int kind = kindFromString(kindAttr); if (kind != IClasspathEntry.CPE_VARIABLE && kind != IClasspathEntry.CPE_CONTAINER && !path.isAbsolute()) { path = projectPath.append(path); } // source attachment info (optional) IPath sourceAttachmentPath = element.hasAttribute("sourcepath") //$NON-NLS-1$ ? new Path(element.getAttribute("sourcepath")) //$NON- NLS-1$ : null; if (sourceAttachmentPath != null && ! sourceAttachmentPath.isAbsolute()) { sourceAttachmentPath = projectPath.append(path); } IPath sourceAttachmentRootPath = element.hasAttribute("rootpath") //$NON-NLS-1$ ? new Path(element.getAttribute("rootpath")) //$NON-NLS- 1$ : null; // exported flag (optional) boolean isExported = element.getAttribute("exported").equals ("true"); //$NON-NLS-1$ //$NON-NLS-2$ // exclusion patterns (optional) String exclusion = element.getAttribute("excluding"); //$NON- NLS-1$ IPath[] exclusionPatterns = ClasspathEntry.NO_EXCLUSION_PATTERNS; if (!exclusion.equals("")) { //$NON-NLS-1$ char[][] patterns = CharOperation.splitOn('|', exclusion.toCharArray()); int patternCount; if ((patternCount = patterns.length) > 0) { exclusionPatterns = new IPath[patternCount]; for (int j = 0; j < patterns.length; j++){ exclusionPatterns[j] = new Path(new String(patterns[j])); } } } // custom output location IPath outputLocation = element.hasAttribute("output") ? projectPath.append(element.getAttribute("output")) : null; //$NON-NLS-1$ //$NON- NLS-2$ // recreate the CP entry switch (kind) { case IClasspathEntry.CPE_PROJECT : return JavaCore.newProjectEntry(path, isExported); case IClasspathEntry.CPE_LIBRARY : return JavaCore.newLibraryEntry( path, sourceAttachmentPath, sourceAttachmentRootPath, isExported); case IClasspathEntry.CPE_SOURCE : // must be an entry in this project or specify another project String projSegment = path.segment(0); if (projSegment != null && projSegment.equals (project.getElementName())) { // this project return JavaCore.newSourceEntry(path, exclusionPatterns, outputLocation); } else { // another project return JavaCore.newProjectEntry(path, isExported); } case IClasspathEntry.CPE_VARIABLE : return JavaCore.newVariableEntry( path, sourceAttachmentPath, sourceAttachmentRootPath, isExported); case IClasspathEntry.CPE_CONTAINER : return JavaCore.newContainerEntry( path, isExported); case ClasspathEntry.K_OUTPUT : if (!path.isAbsolute()) return null; return new ClasspathEntry( ClasspathEntry.K_OUTPUT, IClasspathEntry.CPE_LIBRARY, path, ClasspathEntry.NO_EXCLUSION_PATTERNS, null, // source attachment null, // source attachment root null, // custom output location false); default : throw new Assert.AssertionFailedException (Util.bind("classpath.unknownKind", kindAttr)); //$NON-NLS-1$ } }
Fixed in latest. Source attachments will be project relative when applicable.
Verified.