### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core 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.125 diff -u -r1.125 ClasspathEntry.java --- model/org/eclipse/jdt/internal/core/ClasspathEntry.java 7 Apr 2010 08:29:33 -0000 1.125 +++ model/org/eclipse/jdt/internal/core/ClasspathEntry.java 22 Oct 2010 18:47:00 -0000 @@ -2063,6 +2063,11 @@ return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundSourceAttachment, new String [] {sourceAttachment.toString(), path.toString(), project.getElementName()})); } } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=229042 + // Validate the contents of the archive + IJavaModelStatus status = validateLibraryContents(path, project, entryPathMsg); + if (status != JavaModelStatus.VERIFIED_OK) + return status; break; case IResource.FOLDER : // internal binary folder if (sourceAttachment != null @@ -2083,13 +2088,22 @@ } else { return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalExternalFolder, new String[] {path.toOSString(), project.getElementName()})); } - } else if (sourceAttachment != null - && !sourceAttachment.isEmpty() - && JavaModel.getTarget(sourceAttachment, true) == null){ - if (container != null) { - return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundSourceAttachmentInContainedLibrary, new String [] {sourceAttachment.toString(), path.toOSString(), container})); - } else { - return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundSourceAttachment, new String [] {sourceAttachment.toString(), path.toOSString(), project.getElementName()})); + } else { + if (sourceAttachment != null + && !sourceAttachment.isEmpty() + && JavaModel.getTarget(sourceAttachment, true) == null){ + if (container != null) { + return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundSourceAttachmentInContainedLibrary, new String [] {sourceAttachment.toString(), path.toOSString(), container})); + } else { + return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundSourceAttachment, new String [] {sourceAttachment.toString(), path.toOSString(), project.getElementName()})); + } + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=229042 + // Validate the contents of the archive + if(file.isFile()) { + IJavaModelStatus status = validateLibraryContents(path, project, entryPathMsg); + if (status != JavaModelStatus.VERIFIED_OK) + return status; } } } else { @@ -2121,4 +2135,18 @@ } return JavaModelStatus.VERIFIED_OK; } + + private static IJavaModelStatus validateLibraryContents(IPath path, IJavaProject project, String entryPathMsg) { + JavaModelManager manager = JavaModelManager.getJavaModelManager(); + try { + manager.verifyArchiveContent(path); + } catch (CoreException e) { + if (e.getStatus().getMessage() == Messages.status_IOException) { + return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind( + Messages.classpath_illegalLibraryArchive, + new String[] {entryPathMsg, project.getElementName()})); + } + } + return JavaModelStatus.VERIFIED_OK; + } } Index: model/org/eclipse/jdt/internal/core/DeltaProcessor.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java,v retrieving revision 1.338 diff -u -r1.338 DeltaProcessor.java --- model/org/eclipse/jdt/internal/core/DeltaProcessor.java 20 May 2010 14:12:01 -0000 1.338 +++ model/org/eclipse/jdt/internal/core/DeltaProcessor.java 22 Oct 2010 18:47:01 -0000 @@ -2271,7 +2271,11 @@ /* check classpath or prefs files change */ IFile file = (IFile) resource; String fileName = file.getName(); - if (fileName.equals(JavaProject.CLASSPATH_FILENAME)) { + RootInfo rootInfo = null; + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=229042 + // Mark a validation if a library with package fragment root in the project has changed + if (fileName.equals(JavaProject.CLASSPATH_FILENAME) + || ((rootInfo = rootInfo(file.getFullPath(), delta.getKind())) != null && rootInfo.entryKind == IClasspathEntry.CPE_LIBRARY)) { JavaProject javaProject = (JavaProject)JavaCore.create(file.getProject()); this.state.addClasspathValidation(javaProject); affectedProjects.add(file.getProject().getFullPath()); Index: model/org/eclipse/jdt/internal/core/JavaModelManager.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java,v retrieving revision 1.459 diff -u -r1.459 JavaModelManager.java --- model/org/eclipse/jdt/internal/core/JavaModelManager.java 13 Sep 2010 18:26:08 -0000 1.459 +++ model/org/eclipse/jdt/internal/core/JavaModelManager.java 22 Oct 2010 18:47:02 -0000 @@ -18,6 +18,7 @@ import java.text.MessageFormat; import java.util.*; import java.util.Map.Entry; +import java.util.zip.ZipException; import java.util.zip.ZipFile; import javax.xml.parsers.DocumentBuilder; @@ -82,6 +83,9 @@ */ public class JavaModelManager implements ISaveParticipant, IContentTypeChangeListener { + private static final String NON_CHAINING_JARS_CACHE = "nonChainingJarsCache"; //$NON-NLS-1$ + private static final String INVALID_ARCHIVES_CACHE = "invalidArchivesCache"; //$NON-NLS-1$ + /** * Define a zip cache object. */ @@ -1171,8 +1175,8 @@ } public synchronized ClasspathChange resetResolvedClasspath() { - // clear non-chaining jars cache - JavaModelManager.getJavaModelManager().resetNonChainingJarsCache(); + // clear non-chaining jars cache and invalid jars cache + JavaModelManager.getJavaModelManager().resetClasspathListCache(); // null out resolved information return setResolvedClasspath(null, null, null, null, this.rawTimeStamp, true/*add classpath change*/); @@ -1418,6 +1422,11 @@ * List of IPath of jars that are known to not contain a chaining (through MANIFEST.MF) to another library */ private Set nonChainingJars; + + /* + * List of IPath of jars that are known to be invalid - such as not being a valid/known format + */ + private Set invalidArchives; /** * Update the classpath variable cache @@ -1549,7 +1558,8 @@ */ if (Platform.isRunning()) { this.indexManager = new IndexManager(); - this.nonChainingJars = loadNonChainingJarsCache(); + this.nonChainingJars = loadClasspathListCache(NON_CHAINING_JARS_CACHE); + this.invalidArchives = loadClasspathListCache(INVALID_ARCHIVES_CACHE); String includeContainerReferencedLib = System.getProperty(RESOLVE_REFERENCED_LIBRARIES_FOR_CONTAINERS); this.resolveReferencedLibrariesForContainers = TRUE.equalsIgnoreCase(includeContainerReferencedLib); } @@ -1567,6 +1577,16 @@ if (this.nonChainingJars != null) this.nonChainingJars.add(path); } + + public void addInvalidArchive(IPath path) { + // unlikely to be null + if (this.invalidArchives == null) { + this.invalidArchives = Collections.synchronizedSet(new HashSet()); + } + if(this.invalidArchives != null) { + this.invalidArchives.add(path); + } + } /** * Starts caching ZipFiles. @@ -2545,6 +2565,14 @@ return this.workspaceScope; } + public void verifyArchiveContent(IPath path) throws CoreException { + if (isInvalidArchive(path)) { + throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.status_IOException, new ZipException())); + } + ZipFile file = getZipFile(path); + closeZipFile(file); + } + /** * Returns the open ZipFile at the given path. If the ZipFile * does not yet exist, it is created, opened, and added to the cache @@ -2558,6 +2586,9 @@ */ public ZipFile getZipFile(IPath path) throws CoreException { + if (isInvalidArchive(path)) + throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.status_IOException, new ZipException())); + ZipCache zipCache; ZipFile zipFile; if ((zipCache = (ZipCache)this.zipFiles.get()) != null @@ -2591,6 +2622,7 @@ } return zipFile; } catch (IOException e) { + addInvalidArchive(path); throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.status_IOException, e)); } } @@ -2994,6 +3026,10 @@ public boolean isNonChainingJar(IPath path) { return this.nonChainingJars != null && this.nonChainingJars.contains(path); } + + public boolean isInvalidArchive(IPath path) { + return this.invalidArchives != null && this.invalidArchives.contains(path); + } public void setClasspathBeingResolved(IJavaProject project, boolean classpathIsResolved) { if (classpathIsResolved) { @@ -3003,19 +3039,19 @@ } } - private Set loadNonChainingJarsCache() { - Set nonChainingJarsCache = new HashSet(); - File nonChainingJarsFile = getNonChainingJarsFile(); + private Set loadClasspathListCache(String cacheName) { + Set pathCache = new HashSet(); + File cacheFile = getClasspathListFile(cacheName); DataInputStream in = null; try { - in = new DataInputStream(new BufferedInputStream(new FileInputStream(nonChainingJarsFile))); + in = new DataInputStream(new BufferedInputStream(new FileInputStream(cacheFile))); int size = in.readInt(); while (size-- > 0) { String path = in.readUTF(); - nonChainingJarsCache.add(Path.fromPortableString(path)); + pathCache.add(Path.fromPortableString(path)); } } catch (IOException e) { - if (nonChainingJarsFile.exists()) + if (cacheFile.exists()) Util.log(e, "Unable to read non-chaining jar cache file"); //$NON-NLS-1$ } finally { if (in != null) { @@ -3026,11 +3062,11 @@ } } } - return Collections.synchronizedSet(nonChainingJarsCache); + return Collections.synchronizedSet(pathCache); } - - private File getNonChainingJarsFile() { - return JavaCore.getPlugin().getStateLocation().append("nonChainingJarsCache").toFile(); //$NON-NLS-1$ + + private File getClasspathListFile(String fileName) { + return JavaCore.getPlugin().getStateLocation().append(fileName).toFile(); } private Set getNonChainingJarsCache() throws CoreException { @@ -3057,7 +3093,16 @@ this.nonChainingJars = Collections.synchronizedSet(result); return this.nonChainingJars; } - + + private Set getClasspathListCache(String cacheName) throws CoreException { + if (cacheName == NON_CHAINING_JARS_CACHE) + return getNonChainingJarsCache(); + else if (cacheName == INVALID_ARCHIVES_CACHE) + return this.invalidArchives; + else + return null; + } + public void loadVariablesAndContainers() throws CoreException { // backward compatibility, consider persistent property QualifiedName qName = new QualifiedName(JavaCore.PLUGIN_ID, "variables"); //$NON-NLS-1$ @@ -3734,7 +3779,7 @@ info.forgetExternalTimestampsAndIndexes(); } } - resetNonChainingJarsCache(); + resetClasspathListCache(); } /* @@ -3776,9 +3821,11 @@ this.cache.resetJarTypeCache(); } - public void resetNonChainingJarsCache() { + public void resetClasspathListCache() { if (this.nonChainingJars != null) this.nonChainingJars.clear(); + if (this.invalidArchives != null) + this.invalidArchives.clear(); } /* @@ -3852,15 +3899,15 @@ } } - private void saveNonChainingJarsCache() throws CoreException { - File file = getNonChainingJarsFile(); + private void saveClasspathListCache(String cacheName) throws CoreException { + File file = getClasspathListFile(cacheName); DataOutputStream out = null; try { out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file))); - Set nonChainingJarsCache = getNonChainingJarsCache(); - synchronized (nonChainingJarsCache) { - out.writeInt(nonChainingJarsCache.size()); - Iterator entries = nonChainingJarsCache.iterator(); + Set pathCache = getClasspathListCache(cacheName); + synchronized (pathCache) { + out.writeInt(pathCache.size()); + Iterator entries = pathCache.iterator(); while (entries.hasNext()) { IPath path = (IPath) entries.next(); out.writeUTF(path.toPortableString()); @@ -4139,8 +4186,9 @@ switch(context.getKind()) { case ISaveContext.FULL_SAVE : { - // save non-chaining jar cache on snapshot/full save - saveNonChainingJarsCache(); + // save non-chaining jar and invalid jar caches on full save + saveClasspathListCache(NON_CHAINING_JARS_CACHE); + saveClasspathListCache(INVALID_ARCHIVES_CACHE); // will need delta since this save (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=38658) context.needDelta(); #P org.eclipse.jdt.core.tests.builder Index: src/org/eclipse/jdt/core/tests/builder/BuildpathTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/BuildpathTests.java,v retrieving revision 1.51 diff -u -r1.51 BuildpathTests.java --- src/org/eclipse/jdt/core/tests/builder/BuildpathTests.java 9 Oct 2008 11:55:22 -0000 1.51 +++ src/org/eclipse/jdt/core/tests/builder/BuildpathTests.java 22 Oct 2010 18:47:05 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2008 IBM Corporation and others. + * Copyright (c) 2000, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -13,6 +13,7 @@ import junit.framework.*; import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.*; @@ -25,6 +26,7 @@ import org.eclipse.jdt.internal.core.*; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.util.*; @@ -103,10 +105,28 @@ } } -public void testClosedProject() throws JavaModelException { +public void testClosedProject() throws JavaModelException, IOException { IPath project1Path = env.addProject("CP1"); //$NON-NLS-1$ + IProject project1 = ResourcesPlugin.getWorkspace().getRoot().getProject("CP1"); env.addExternalJars(project1Path, Util.getJavaClassLibs()); - IPath jarPath = env.addInternalJar(project1Path, "temp.jar", new byte[] {0}); //$NON-NLS-1$ + + String jarFile = project1.getLocation().toOSString() + File.separator + "temp.jar"; + + org.eclipse.jdt.core.tests.util.Util.createJar( + null, + new String[] { + "META-INF/MANIFEST.MF", + "Manifest-Version: 1.0\n", + }, + jarFile, + null, + JavaCore.VERSION_1_4); + + FileInputStream fis = new FileInputStream(jarFile); + int length = fis.available(); + byte[] jarContent = new byte[length]; + fis.read(jarContent); + IPath jarPath = env.addInternalJar(project1Path, "temp.jar", jarContent); //$NON-NLS-1$ IPath project2Path = env.addProject("CP2"); //$NON-NLS-1$ env.addExternalJars(project2Path, Util.getJavaClassLibs()); #P org.eclipse.jdt.core.tests.compiler Index: src/org/eclipse/jdt/core/tests/util/Util.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/Util.java,v retrieving revision 1.81 diff -u -r1.81 Util.java --- src/org/eclipse/jdt/core/tests/util/Util.java 7 Dec 2009 20:32:59 -0000 1.81 +++ src/org/eclipse/jdt/core/tests/util/Util.java 22 Oct 2010 18:47:07 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -341,6 +341,17 @@ flushDirectoryContent(classesDir); compile(pathsAndContents, getCompileOptions(compliance), folderPath); } +public static void createEmptyJar(String jarPath, String compliance) throws IOException { + org.eclipse.jdt.core.tests.util.Util.createJar( + null, + new String[] { + "META-INF/MANIFEST.MF", + "Manifest-Version: 1.0\n", + }, + jarPath, + null, + compliance); +} public static void createJar(String[] pathsAndContents, Map options, String jarPath) throws IOException { createJar(pathsAndContents, null, options, null, jarPath); } #P org.eclipse.jdt.core.tests.model Index: src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java,v retrieving revision 1.66 diff -u -r1.66 AttachSourceTests.java --- src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java 3 Sep 2010 15:20:03 -0000 1.66 +++ src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java 22 Oct 2010 18:47:09 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -14,6 +14,7 @@ import java.io.IOException; import junit.framework.Test; + import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; @@ -22,10 +23,25 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; -import org.eclipse.jdt.core.*; -import org.eclipse.jdt.core.dom.*; +import org.eclipse.jdt.core.IBuffer; +import org.eclipse.jdt.core.IClassFile; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IMember; +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.IPackageFragment; +import org.eclipse.jdt.core.IPackageFragmentRoot; +import org.eclipse.jdt.core.ISourceRange; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.SourceRange; +import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.ASTParser; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.core.JarPackageFragmentRoot; +import org.eclipse.jdt.internal.core.JavaProject; import org.eclipse.jdt.internal.core.util.Util; /** @@ -270,6 +286,7 @@ // add source attachment file back moveFile("AttachSourceTests/attachsrc.new.zip", "AttachSourceTests/attachsrc.zip"); + ((JavaProject)this.currentProject).resetResolvedClasspath(); assertSourceEquals( "unexpected source for foo() after addition", "public void foo() {\n" + Index: src/org/eclipse/jdt/core/tests/model/ClasspathInitializerTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathInitializerTests.java,v retrieving revision 1.69 diff -u -r1.69 ClasspathInitializerTests.java --- src/org/eclipse/jdt/core/tests/model/ClasspathInitializerTests.java 6 Oct 2010 17:32:30 -0000 1.69 +++ src/org/eclipse/jdt/core/tests/model/ClasspathInitializerTests.java 22 Oct 2010 18:47:09 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.jdt.core.tests.model; +import java.io.IOException; import java.util.HashMap; import java.util.Map; @@ -1313,7 +1314,7 @@ * @bug 138599: [model][classpath] Need a way to mark a classpath variable as deprecated * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=138599" */ -public void testVariableInitializerDeprecated() throws CoreException { +public void testVariableInitializerDeprecated() throws CoreException, IOException { try { // Create initializer String varName = "TEST_DEPRECATED"; @@ -1326,7 +1327,10 @@ // Create project IJavaProject project = createJavaProject("P1"); - createFile("/P1/lib.jar", ""); + addLibrary(project, "lib.jar", null, new String[0], + new String[]{"META-INF/MANIFEST.MF", + "Manifest-Version: 1.0\n"} , + JavaCore.VERSION_1_4); IClasspathEntry variable = JavaCore.newVariableEntry(new Path("TEST_DEPRECATED"), null, null); IJavaModelStatus status = JavaConventions.validateClasspathEntry(project, variable, false); assertStatus("Classpath variable 'TEST_DEPRECATED' in project 'P1' is deprecated: Test deprecated flag", status); @@ -1367,7 +1371,7 @@ * @bug 156226: [model][classpath] Allow classpath variable to be marked as non modifiable * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=156226" */ -public void testVariableInitializerReadOnly() throws CoreException { +public void testVariableInitializerReadOnly() throws CoreException, IOException { try { // Create initializer String varName = "TEST_READ_ONLY"; @@ -1380,7 +1384,10 @@ // Create project IJavaProject project = createJavaProject("P1"); - createFile("/P1/lib.jar", ""); + addLibrary(project, "lib.jar", null, new String[0], + new String[]{"META-INF/MANIFEST.MF", + "Manifest-Version: 1.0\n"} , + JavaCore.VERSION_1_4); IClasspathEntry variable = JavaCore.newVariableEntry(new Path("TEST_READ_ONLY"), null, null); IJavaModelStatus status = JavaConventions.validateClasspathEntry(project, variable, false); assertStatus("OK", status); @@ -1391,7 +1398,7 @@ deleteProject("P1"); } } -public void testVariableInitializerDeprecatedAndReadOnly() throws CoreException { +public void testVariableInitializerDeprecatedAndReadOnly() throws CoreException, IOException { try { // Create initializer String varName = "TEST_DEPRECATED_READ_ONLY"; @@ -1405,7 +1412,10 @@ // Create project IJavaProject project = createJavaProject("P1"); - createFile("/P1/lib.jar", ""); + addLibrary(project, "lib.jar", null, new String[0], + new String[]{"META-INF/MANIFEST.MF", + "Manifest-Version: 1.0\n"} , + JavaCore.VERSION_1_4); IClasspathEntry variable = JavaCore.newVariableEntry(new Path("TEST_DEPRECATED_READ_ONLY"), null, null); IJavaModelStatus status = JavaConventions.validateClasspathEntry(project, variable, false); assertStatus("Classpath variable 'TEST_DEPRECATED_READ_ONLY' in project 'P1' is deprecated: A deprecated and read-only initializer", status); @@ -1422,7 +1432,7 @@ * @bug 172207: [model] Marker for deprecated classpath variable should always have WARNING severity * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=172207" */ -public void testVariableInitializerBug172207() throws CoreException { +public void testVariableInitializerBug172207() throws CoreException, IOException { try { // Create initializer String varName = "TEST_DEPRECATED_READ_ONLY"; @@ -1436,7 +1446,10 @@ // Create project IJavaProject project = createJavaProject("P1"); - createFile("/P1/lib.jar", ""); + addLibrary(project, "lib.jar", null, new String[0], + new String[]{"META-INF/MANIFEST.MF", + "Manifest-Version: 1.0\n"} , + JavaCore.VERSION_1_4); IClasspathEntry variable = JavaCore.newVariableEntry(new Path("TEST_DEPRECATED_READ_ONLY"), null, null); IClasspathEntry[] entries = project.getRawClasspath(); int length = entries.length; 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.218 diff -u -r1.218 ClasspathTests.java --- src/org/eclipse/jdt/core/tests/model/ClasspathTests.java 11 Oct 2010 12:34:42 -0000 1.218 +++ src/org/eclipse/jdt/core/tests/model/ClasspathTests.java 22 Oct 2010 18:47:10 -0000 @@ -549,10 +549,12 @@ /* * Ensures that adding a library entry for an existing external ZIP archive doesn't generate a marker */ -public void testAddZIPArchive1() throws CoreException { +public void testAddZIPArchive1() throws CoreException, IOException { try { IJavaProject p = createJavaProject("P"); - createExternalFile("externalLib.abc", ""); + org.eclipse.jdt.core.tests.util.Util.createEmptyJar( + getExternalResourcePath("externalLib.abc"), + JavaCore.VERSION_1_4); setClasspath(p, new IClasspathEntry[] {JavaCore.newLibraryEntry(new Path(getExternalResourcePath("externalLib.abc")), null, null)}); assertMarkers("Unexpected markers", "", p); } finally { @@ -564,9 +566,11 @@ /* * Ensures that creating a project with a library entry for an existing external ZIP archive doesn't generate a marker */ -public void testAddZIPArchive2() throws CoreException { +public void testAddZIPArchive2() throws CoreException, IOException { try { - createExternalFile("externalLib.abc", ""); + org.eclipse.jdt.core.tests.util.Util.createEmptyJar( + getExternalResourcePath("externalLib.abc"), + JavaCore.VERSION_1_4); IJavaProject p = createJavaProject("P", new String[0], new String[] {getExternalResourcePath("externalLib.abc")}, ""); assertMarkers("Unexpected markers", "", p); } finally { @@ -614,13 +618,14 @@ /* * Ensures that creating an external ZIP archive referenced by a library entry and refreshing removes the marker */ -public void testAddZIPArchive5() throws CoreException { +public void testAddZIPArchive5() throws CoreException, IOException { try { IJavaProject p = createJavaProject("P", new String[0], new String[] {getExternalResourcePath("externalLib.abc")}, ""); refreshExternalArchives(p); waitForAutoBuild(); - - createExternalFile("externalLib.abc", ""); + org.eclipse.jdt.core.tests.util.Util.createEmptyJar( + getExternalResourcePath("externalLib.abc"), + JavaCore.VERSION_1_4); refreshExternalArchives(p); assertMarkers("Unexpected markers", "", p); } finally { @@ -633,13 +638,14 @@ * Ensures that creating an external ZIP archive referenced by a library entry and refreshing after a restart * removes the marker */ -public void testAddZIPArchive6() throws CoreException { +public void testAddZIPArchive6() throws CoreException, IOException { try { simulateExitRestart(); IJavaProject p = createJavaProject("P", new String[0], new String[] {getExternalResourcePath("externalLib.abc")}, ""); refreshExternalArchives(p); - - createExternalFile("externalLib.abc", ""); + org.eclipse.jdt.core.tests.util.Util.createEmptyJar( + getExternalResourcePath("externalLib.abc"), + JavaCore.VERSION_1_4); refreshExternalArchives(p); assertMarkers("Unexpected markers", "", p); } finally { @@ -651,13 +657,15 @@ /* * Ensures that adding a library entry for an existing internal ZIP archive doesn't generate a marker */ -public void testAddZIPArchive7() throws CoreException { +public void testAddZIPArchive7() throws CoreException, IOException { try { IJavaProject p = createJavaProject("P"); refreshExternalArchives(p); waitForAutoBuild(); - - createFile("/P/internalLib.abc", ""); + addLibrary(p, "internalLib.abc", null, new String[0], + new String[]{"META-INF/MANIFEST.MF", + "Manifest-Version: 1.0\n"} , + JavaCore.VERSION_1_4); setClasspath(p, new IClasspathEntry[] {JavaCore.newLibraryEntry(new Path("/P/internalLib.abc"), null, null)}); assertMarkers("Unexpected markers", "", p); } finally { @@ -2604,13 +2612,16 @@ String externalJarPath = getWorkspaceRoot().getLocation().removeLastSegments(1).append("external.jar").toOSString(); try { IJavaProject p = createJavaProject("P"); - Util.writeToFile("", externalJarPath); + org.eclipse.jdt.core.tests.util.Util.createEmptyJar( + externalJarPath, + JavaCore.VERSION_1_4); ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P", "../../external.jar"})); setClasspath(p, new IClasspathEntry[] {JavaCore.newContainerEntry(new Path("org.eclipse.jdt.core.tests.model.TEST_CONTAINER"))}); assertElementDescendants( "Unexpected project content", "P\n" + - " "+ getExternalPath() + "external.jar", + " "+ getExternalPath() + "external.jar\n" + + " (...)", p ); } finally { @@ -2645,12 +2656,15 @@ String externalJarPath = getWorkspaceRoot().getLocation().append("external.jar").toOSString(); try { IJavaProject p = createJavaProject("P"); - Util.writeToFile("", externalJarPath); + org.eclipse.jdt.core.tests.util.Util.createEmptyJar( + externalJarPath, + JavaCore.VERSION_1_4); setClasspath(p, new IClasspathEntry[] {JavaCore.newLibraryEntry(new Path("../external.jar"), null, null)}); assertElementDescendants( "Unexpected project content", "P\n" + - " "+ getWorkspacePath() + "external.jar", + " "+ getWorkspacePath() + "external.jar\n" + + " (...)", p ); } finally { @@ -2666,12 +2680,15 @@ String externalJarPath = getWorkspaceRoot().getLocation().removeLastSegments(1).append("external.jar").toOSString(); try { IJavaProject p = createJavaProject("P"); - Util.writeToFile("", externalJarPath); + org.eclipse.jdt.core.tests.util.Util.createEmptyJar( + externalJarPath, + JavaCore.VERSION_1_4); setClasspath(p, new IClasspathEntry[] {JavaCore.newLibraryEntry(new Path("../../external.jar"), null, null)}); assertElementDescendants( "Unexpected project content", "P\n" + - " "+ getExternalPath() + "external.jar", + " "+ getExternalPath() + "external.jar\n" + + " (...)", p ); } finally { @@ -2687,12 +2704,15 @@ String externalJarPath = getWorkspaceRoot().getLocation().removeLastSegments(1).append("external.jar").toOSString(); try { IJavaProject p = createJavaProject("P"); - Util.writeToFile("", externalJarPath); + org.eclipse.jdt.core.tests.util.Util.createEmptyJar( + externalJarPath, + JavaCore.VERSION_1_4); setClasspath(p, new IClasspathEntry[] {JavaCore.newLibraryEntry(new Path("src/../../../external.jar"), null, null)}); assertElementDescendants( "Unexpected project content", "P\n" + - " "+ getExternalPath() + "external.jar", + " "+ getExternalPath() + "external.jar\n" + + " (...)", p ); } finally { @@ -2706,15 +2726,20 @@ */ public void testDotDotLibraryEntry4() throws Exception { try { - createProject("P1"); - createFile("/P1/internal.jar", ""); - IJavaProject p = createJavaProject("P2"); - setClasspath(p, new IClasspathEntry[] {JavaCore.newLibraryEntry(new Path("../P1/internal.jar"), null, null)}); + IJavaProject p1 = createJavaProject("P1"); + IJavaProject p2 = createJavaProject("P2"); + + addLibrary(p1, "internal.jar", null, new String[0], + new String[]{"META-INF/MANIFEST.MF", + "Manifest-Version: 1.0\n"} , + JavaCore.VERSION_1_4); + setClasspath(p2, new IClasspathEntry[] {JavaCore.newLibraryEntry(new Path("../P1/internal.jar"), null, null)}); assertElementDescendants( "Unexpected project content", "P2\n" + - " /P1/internal.jar", - p + " /P1/internal.jar\n" + + " (...)", + p2 ); } finally { deleteProject("P1"); @@ -2729,7 +2754,9 @@ String externalJarPath = getWorkspaceRoot().getLocation().append("external.jar").toOSString(); try { IJavaProject p = createJavaProject("P"); - Util.writeToFile("", externalJarPath); + org.eclipse.jdt.core.tests.util.Util.createEmptyJar( + externalJarPath, + JavaCore.VERSION_1_4); setClasspath(p, new IClasspathEntry[] {JavaCore.newLibraryEntry(new Path("../external.jar"), null, null)}); assertMarkers( "Unexpected markers", @@ -2764,7 +2791,9 @@ String externalJarPath = getWorkspaceRoot().getLocation().append("external.jar").toOSString(); try { IJavaProject p = createJavaProject("P"); - Util.writeToFile("", externalJarPath); + org.eclipse.jdt.core.tests.util.Util.createEmptyJar( + externalJarPath, + JavaCore.VERSION_1_4); editFile( "/P/.classpath", "\n" + @@ -2778,7 +2807,8 @@ "P\n" + " \n" + " (...)\n" + - " "+ getWorkspacePath() + "external.jar", + " "+ getWorkspacePath() + "external.jar\n" + + " (...)", p ); } finally { @@ -2819,12 +2849,15 @@ try { JavaCore.setClasspathVariable("TWO_UP", new Path("../.."), null); IJavaProject p = createJavaProject("P"); - Util.writeToFile("", externalJarPath); + org.eclipse.jdt.core.tests.util.Util.createEmptyJar( + externalJarPath, + JavaCore.VERSION_1_4); setClasspath(p, new IClasspathEntry[] {JavaCore.newVariableEntry(new Path("TWO_UP/external.jar"), null, null)}); assertElementDescendants( "Unexpected project content", "P\n" + - " "+ getExternalPath() + "external.jar", + " "+ getExternalPath() + "external.jar\n" + + " (...)", p ); } finally { @@ -3122,8 +3155,9 @@ waitUntilIndexesReady(); waitForAutoBuild(); // at this point, a marker indicates that test185733.jar has been created: "Project 'P' is missing required library: '[...]\test185733.jar'" - - createFile(new File(getExternalPath()), "test185733.jar", ""); + org.eclipse.jdt.core.tests.util.Util.createEmptyJar( + getExternalResourcePath("test185733.jar"), + JavaCore.VERSION_1_4); refreshExternalArchives(p); assertMarkers( "Unexpected markers", @@ -3749,13 +3783,16 @@ * Ensures that a marker is removed if adding an internal jar that is on the classpath in another project * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=213723 ) */ -public void testFixClasspath1() throws CoreException { +public void testFixClasspath1() throws CoreException, IOException { try { createProject("P1"); - IJavaProject project = createJavaProject("P2", new String[0], new String[] {"/P1/lib.jar"}, "bin"); + IJavaProject project = createJavaProject("P2", new String[0], new String[0], "bin"); waitForAutoBuild(); - - createFile("/P1/lib.jar", ""); + addLibrary(project, "lib.jar", null, new String[0], + new String[]{"META-INF/MANIFEST.MF", + "Manifest-Version: 1.0\n"} , + JavaCore.VERSION_1_4); + assertMarkers( "Unexpected markers", "", @@ -3769,11 +3806,13 @@ * Ensures that a marker is removed if adding an external jar, restarting and refreshing * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=216446 ) */ -public void testFixClasspath2() throws CoreException { +public void testFixClasspath2() throws CoreException, IOException { try { IJavaProject p = createJavaProject("P", new String[0], new String[] {getExternalResourcePath("externalLib.abc")}, ""); waitForAutoBuild(); // 1 marker - createExternalFile("externalLib.abc", ""); + org.eclipse.jdt.core.tests.util.Util.createEmptyJar( + getExternalResourcePath("externalLib.abc"), + JavaCore.VERSION_1_4); simulateExitRestart(); refreshExternalArchives(p); @@ -3939,11 +3978,15 @@ * Ensures that a file not ending with .jar or .zip can be put on the classpath. * (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=182360 ) */ -public void testInvalidInternalJar2() throws CoreException { +public void testInvalidInternalJar2() throws CoreException, IOException { try { - createProject("P1"); - createFile("/P1/existing.txt", ""); - IJavaProject proj = createJavaProject("P2", new String[] {}, new String[] {"/P1/existing.txt"}, "bin"); + IJavaProject proj = createJavaProject("P1", new String[] {}, new String[0], "bin"); + + addLibrary(proj, "existing.txt", null, new String[0], + new String[]{"META-INF/MANIFEST.MF", + "Manifest-Version: 1.0\n"} , + JavaCore.VERSION_1_4); + proj = createJavaProject("P2", new String[] {}, new String[] {"/P1/existing.txt"}, "bin"); assertMarkers( "Unexpected markers", "", @@ -4933,12 +4976,15 @@ * 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 { +public void testDuplicateEntries2() throws CoreException, IOException { 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", ""); + addLibrary(project, "lib.jar", null, new String[0], + new String[]{"META-INF/MANIFEST.MF", + "Manifest-Version: 1.0\n"} , + JavaCore.VERSION_1_4); editFile( "/P/.classpath", "\n" + @@ -4948,6 +4994,7 @@ " \n" + "" ); + waitForAutoBuild(); assertMarkers( "Unexpected markers", "", @@ -5497,13 +5544,18 @@ /* * Ensures that removing an internal ZIP archive referenced by a library entry creates a marker */ -public void testRemoveZIPArchive6() throws CoreException { +public void testRemoveZIPArchive6() throws CoreException, IOException { try { - IJavaProject p = createJavaProject("P", new String[0], new String[] {"/P/internalLib.abc"}, ""); - createFile("/P/internalLib.abc", ""); + IJavaProject p = createJavaProject("P", new String[0], new String[0], ""); + + addLibrary(p, "internalLib.abc", null, new String[0], + new String[]{"META-INF/MANIFEST.MF", + "Manifest-Version: 1.0\n"} , + JavaCore.VERSION_1_4); waitForAutoBuild(); deleteFile("/P/internalLib.abc"); + waitForAutoBuild(); assertMarkers( "Unexpected markers", "Project \'P\' is missing required library: \'internalLib.abc\'", @@ -5517,12 +5569,15 @@ * Ensures that renaming a .jar file and updating the classpath in a PRE_BUILD event doesn't leave markers * (regression test for bug 177922 FlexibleProjectContainer refresh logic sporadically leaves project with "missing library" error on rename/delete) */ -public void testRenameJar() throws CoreException { +public void testRenameJar() throws CoreException, IOException { IResourceChangeListener listener = null; try { - final IJavaProject p = createJavaProject("P", new String[0], new String[] {"/P/lib/test1.jar"}, ""); + final IJavaProject p = createJavaProject("P", new String[0], new String[0], ""); createFolder("/P/lib"); - createFile("/P/lib/test1.jar", ""); + addLibrary(p, "lib/test1.jar", null, new String[0], + new String[]{"META-INF/MANIFEST.MF", + "Manifest-Version: 1.0\n"} , + JavaCore.VERSION_1_4); // at this point no markers exist // register a listener that updates the classpath in a PRE_BUILD event @@ -6813,6 +6868,41 @@ deleteProject("ReferencedProject"); } } - +/** + * @bug 229042: [buildpath] could create build path error in case of invalid external JAR format + * + * Test that an invalid archive (JAR) creates a buildpath error + * + * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=229042" + * @throws Exception + */ +public void testBug229042() throws Exception { + try { + IJavaProject p = createJavaProject("P"); + createFile("/P/library.jar", ""); + setClasspath(p, new IClasspathEntry[] { JavaCore.newLibraryEntry(new Path("/P/library.jar"), null,null)}); + assertMarkers("Expected marker", + "Illegal type of archive for required library: \'library.jar\' in project \'P\'", p); + setClasspath(p, new IClasspathEntry[0]); + addLibrary(p, "library.jar", null, new String[0], + new String[] { + "p/X.java", + "package p;\n" + + "public class X {}\n", + "META-INF/MANIFEST.MF", + "Manifest-Version: 1.0\n", + }, + JavaCore.VERSION_1_4); + IFile file = p.getProject().getFile("library.jar"); + assertNotNull(file); + file.touch(null); + waitForAutoBuild(); + assertMarkers("Unexpected marker", + "", p); + + } finally { + deleteProject("P"); + } +} } Index: src/org/eclipse/jdt/core/tests/model/JavaProjectTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaProjectTests.java,v retrieving revision 1.105 diff -u -r1.105 JavaProjectTests.java --- src/org/eclipse/jdt/core/tests/model/JavaProjectTests.java 30 Aug 2010 10:53:31 -0000 1.105 +++ src/org/eclipse/jdt/core/tests/model/JavaProjectTests.java 22 Oct 2010 18:47:10 -0000 @@ -244,13 +244,14 @@ public void testAddZIPArchive1() throws Exception { try { IJavaProject p = createJavaProject("P"); - createExternalFile("externalLib.abc", ""); + org.eclipse.jdt.core.tests.util.Util.createEmptyJar(getExternalResourcePath("externalLib.abc"), JavaCore.VERSION_1_4); setClasspath(p, new IClasspathEntry[] {JavaCore.newLibraryEntry(new Path(getExternalResourcePath("externalLib.abc")), null, null)}); assertElementDescendants( "Unexpected project content", - "P\n" + - " "+ getExternalPath() + "externalLib.abc", + "P\n" + + " "+ getExternalPath() + "externalLib.abc\n" + + " (...)", p ); } finally { @@ -319,12 +320,13 @@ refreshExternalArchives(p); expandAll(p); - createExternalFile("externalLib.abc", ""); + org.eclipse.jdt.core.tests.util.Util.createEmptyJar(getExternalResourcePath("externalLib.abc"), JavaCore.VERSION_1_4); refreshExternalArchives(p); assertElementDescendants( "Unexpected project content", - "P\n" + - " "+ getExternalPath() + "externalLib.abc", + "P\n" + + " "+ getExternalPath() + "externalLib.abc\n" + + " (...)", p ); } finally { @@ -372,12 +374,19 @@ public void testAddZIPArchive6() throws Exception { try { IJavaProject p = createJavaProject("P"); - createFile("/P/internalLib.abc", ""); + addLibrary(p, "internalLib.abc", null, new String[0], + new String[] { + "META-INF/MANIFEST.MF", + "Manifest-Version: 1.0\n" + + "Class-Path: lib2.jar\n", + }, + JavaCore.VERSION_1_4); setClasspath(p, new IClasspathEntry[] {JavaCore.newLibraryEntry(new Path("/P/internalLib.abc"), null, null)}); assertElementDescendants( "Unexpected project content", - "P\n" + - " internalLib.abc", + "P\n" + + " internalLib.abc\n" + + " (...)", p ); } finally { @@ -527,7 +536,7 @@ */ public void testChangeZIPArchive1() throws CoreException, IOException { try { - createExternalFile("externalLib.abc", ""); + org.eclipse.jdt.core.tests.util.Util.createEmptyJar(getExternalResourcePath("externalLib.abc"), JavaCore.VERSION_1_4); IJavaProject p = createJavaProject("P", new String[0], new String[] {getExternalResourcePath("externalLib.abc")}, "bin"); refreshExternalArchives(p); expandAll(p); @@ -607,7 +616,8 @@ public void testChangeZIPArchive3() throws CoreException, IOException { try { IJavaProject p = createJavaProject("P", new String[0], new String[] {"/P/internalLib.abc"}, "bin"); - IFile lib = createFile("/P/internalLib.abc", ""); + String libPath = p.getProject().getLocation().toOSString()+ File.separator + "internalLib.abc"; + org.eclipse.jdt.core.tests.util.Util.createEmptyJar(libPath, JavaCore.VERSION_1_4); expandAll(p); createJar( @@ -617,7 +627,7 @@ "public class X {\n" + "}" }, - lib.getLocation().toOSString()); + libPath); p.getProject().refreshLocal(IResource.DEPTH_INFINITE, null); assertElementDescendants( "Unexpected project content", @@ -2065,9 +2075,9 @@ /* * Ensures that removing a library entry for an existing external ZIP archive updates the model */ -public void testRemoveZIPArchive1() throws CoreException { +public void testRemoveZIPArchive1() throws CoreException, IOException { try { - createExternalFile("externalLib.abc", ""); + org.eclipse.jdt.core.tests.util.Util.createEmptyJar(getExternalResourcePath("externalLib.abc"), JavaCore.VERSION_1_4); IJavaProject p = createJavaProject("P", new String[0], new String[] {getExternalResourcePath("externalLib.abc")}, ""); refreshExternalArchives(p); expandAll(p); @@ -2108,9 +2118,9 @@ /* * Ensures that removing an external ZIP archive referenced by a library entry and refreshing updates the model */ -public void testRemoveZIPArchive3() throws CoreException { +public void testRemoveZIPArchive3() throws CoreException, IOException { try { - createExternalFile("externalLib.abc", ""); + org.eclipse.jdt.core.tests.util.Util.createEmptyJar(getExternalResourcePath("externalLib.abc"), JavaCore.VERSION_1_4); IJavaProject p = createJavaProject("P", new String[0], new String[] {getExternalResourcePath("externalLib.abc")}, ""); refreshExternalArchives(p); expandAll(p); @@ -2131,10 +2141,10 @@ /* * Ensures that removing a library entry for an existing internal ZIP archive updates the model */ -public void testRemoveZIPArchive4() throws CoreException { +public void testRemoveZIPArchive4() throws CoreException, IOException { try { IJavaProject p = createJavaProject("P", new String[0], new String[] {"/P/internalLib.abc"}, ""); - createFile("/P/internalLib.abc", ""); + org.eclipse.jdt.core.tests.util.Util.createEmptyJar(p.getProject().getLocation().toOSString()+ File.separator + "internalLib.abc", JavaCore.VERSION_1_4); expandAll(p); setClasspath(p, new IClasspathEntry[] {});