/******************************************************************************* * Copyright (c) 2000, 2015 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 * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.core.tests.model; import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.eclipse.core.resources.*; import org.eclipse.core.runtime.*; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.jdt.core.*; import org.eclipse.jdt.internal.core.ClasspathEntry; import org.eclipse.jdt.internal.core.JavaModelManager; import org.eclipse.jdt.internal.core.JavaModelStatus; import org.eclipse.jdt.internal.core.JavaProject; import org.eclipse.jdt.internal.core.UserLibrary; import org.eclipse.jdt.internal.core.UserLibraryClasspathContainer; import junit.framework.Test; @SuppressWarnings({"rawtypes", "unchecked"}) public class ClasspathInitializerTests extends ModifyingResourceTests { public static class DefaultVariableInitializer implements VariablesInitializer.ITestInitializer { Map variableValues; /* * values is [<var name>, <var value>]* */ public DefaultVariableInitializer(String[] values) { this.variableValues = new HashMap(); for (int i = 0; i < values.length; i+=2) { this.variableValues.put(values[i], new Path(values[i+1])); } } public void initialize(String variable) throws JavaModelException { if (this.variableValues == null) return; JavaCore.setClasspathVariable( variable, (IPath)this.variableValues.get(variable), null); } } // Simple container initializer, which keeps setting container to null // (30920 - stackoverflow when setting container to null) public class NullContainerInitializer implements ContainerInitializer.ITestInitializer { public boolean hasRun = false; public boolean allowFailureContainer() { return false; // allow the initializer to run again } public void initialize(IPath containerPath, IJavaProject project) throws CoreException { this.hasRun = true; JavaCore.setClasspathContainer( containerPath, new IJavaProject[] {project}, new IClasspathContainer[] { null }, null); } } public ClasspathInitializerTests(String name) { super(name); } public static Test suite() { return buildModelTestSuite(ClasspathInitializerTests.class); } // Use this static initializer to specify subset for tests // All specified tests which do not belong to the class are skipped... static { // Names of tests to run: can be "testBugXXXX" or "BugXXXX") // TESTS_NAMES = new String[] { "testBug346002" }; // Numbers of tests to run: "test<number>" will be run for each number of this array // TESTS_NUMBERS = new int[] { 2, 12 }; // Range numbers of tests to run: all tests between "test<first>" and "test<last>" will be run for { first, last } // TESTS_RANGE = new int[] { 16, -1 }; } protected void tearDown() throws Exception { // Cleanup caches JavaModelManager manager = JavaModelManager.getJavaModelManager(); manager.containers = new HashMap(5); manager.variables = new HashMap(5); super.tearDown(); } public void testContainerInitializer01() throws CoreException { try { createProject("P1"); createFile("/P1/lib.jar", ""); ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P2", "/P1/lib.jar"})); IJavaProject p2 = createJavaProject( "P2", new String[] {}, new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, ""); IPackageFragmentRoot root = p2.getPackageFragmentRoot(getFile("/P1/lib.jar")); assertTrue("/P1/lib.jar should exist", root.exists()); } finally { stopDeltas(); deleteProject("P1"); deleteProject("P2"); } } public void testContainerInitializer02() throws CoreException { try { createProject("P1"); createFile("/P1/lib.jar", ""); ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P2", "/P1/lib.jar"})); IJavaProject p2 = createJavaProject( "P2", new String[] {}, new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, ""); // simulate state on startup simulateExitRestart(); startDeltas(); p2.getResolvedClasspath(true); assertDeltas( "Unexpected delta on startup", "" ); } finally { stopDeltas(); deleteProject("P1"); deleteProject("P2"); } } public void testContainerInitializer03() throws CoreException { try { createProject("P1"); createFile("/P1/lib.jar", ""); ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P2", "/P1/lib.jar"})); createJavaProject( "P2", new String[] {}, new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, ""); // change value of TEST_CONTAINER createFile("/P1/lib2.jar", ""); ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P2", "/P1/lib2.jar"})); // simulate state on startup simulateExitRestart(); startDeltas(); getJavaProject("P2").getResolvedClasspath(true); assertDeltas( "Unexpected delta on startup", "P2[*]: {CHILDREN | RESOLVED CLASSPATH CHANGED}\n" + " /P1/lib.jar[*]: {REMOVED FROM CLASSPATH}\n" + " /P1/lib2.jar[*]: {ADDED TO CLASSPATH}" ); } finally { stopDeltas(); deleteProject("P1"); deleteProject("P2"); } } /* Ensure that initializer is not callled when resource tree is locked. * (regression test for bug 29585 Core Exception as resource tree is locked initializing classpath container) */ public void testContainerInitializer04() throws CoreException { try { createProject("P1"); createFile("/P1/lib.jar", ""); DefaultContainerInitializer initializer = new DefaultContainerInitializer(new String[] {"P2", "/P1/lib.jar"}); ContainerInitializer.setInitializer(initializer); createJavaProject( "P2", new String[] {""}, new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, ""); // simulate state on startup simulateExitRestart(); startDeltas(); createFile("/P2/X.java", "public class X {}"); assertEquals("Should not get exception", null, initializer.exception); assertDeltas( "Unexpected delta on startup", "P2[*]: {CHILDREN}\n" + " <project root>[*]: {CHILDREN}\n" + " <default>[*]: {CHILDREN}\n" + " X.java[+]: {}" ); } finally { stopDeltas(); deleteProject("P1"); deleteProject("P2"); } } /* * 30920 - Stack overflow when container resolved to null */ public void testContainerInitializer05() throws CoreException { try { NullContainerInitializer nullInitializer = new NullContainerInitializer(); ContainerInitializer.setInitializer(nullInitializer); createJavaProject( "P1", new String[] {""}, new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, ""); // simulate state on startup simulateExitRestart(); startDeltas(); // will trigger classpath resolution (with null container value) createFile("/P1/X.java", "public class X {}"); assertDeltas( "Unexpected delta on startup", "P1[*]: {CHILDREN}\n" + " <project root>[*]: {CHILDREN}\n" + " <default>[*]: {CHILDREN}\n" + " X.java[+]: {}" ); assertTrue("initializer did not run", nullInitializer.hasRun); // next cp resolution request will rerun the initializer waitForAutoBuild(); nullInitializer.hasRun = false; // reset getJavaProject("P1").getResolvedClasspath(true); assertTrue("initializer did not run", nullInitializer.hasRun); // initializer should have run again (since keep setting to null) // assigning new (non-null) value to container waitForAutoBuild(); createFile("/P1/lib.jar", ""); ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P1", "/P1/lib.jar"})); clearDeltas(); getJavaProject("P1").getResolvedClasspath(true); assertDeltas( "Unexpected delta after setting container", "P1[*]: {CHILDREN | RESOLVED CLASSPATH CHANGED}\n" + " lib.jar[*]: {ADDED TO CLASSPATH}" ); } catch (StackOverflowError e) { e.printStackTrace(); assertTrue("stack overflow assigning container", false); } finally { stopDeltas(); deleteProject("P1"); } } /* * Ensures that running the initializer during a reconcile operation just after workspace startup * doesn't throw a NPE * (regression test for bug 48818 NPE in delta processor) */ public void testContainerInitializer06() throws CoreException { ICompilationUnit workingCopy = null; try { createProject("P1"); ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P2", ""})); createJavaProject( "P2", new String[] {"src"}, new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, "bin"); createFile( "/P2/src/X,java", "public class X {\n" + "}" ); // change value of TEST_CONTAINER ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P2", "/P1"})); // simulate state on startup simulateExitRestart(); startDeltas(); workingCopy = getCompilationUnit("/P2/src/X.java"); workingCopy.becomeWorkingCopy(null); assertWorkingCopyDeltas( "Unexpected delta on startup", "P2[*]: {CHILDREN}\n" + " src[*]: {CHILDREN}\n" + " <default>[*]: {CHILDREN}\n" + " [Working copy] X.java[+]: {PRIMARY WORKING COPY}" ); } finally { stopDeltas(); if (workingCopy != null) workingCopy.discardWorkingCopy(); deleteProject("P1"); deleteProject("P2"); } } /* * Ensure that an OperationCanceledException goes through * (regression test for bug 59363 Should surface cancellation exceptions) */ public void testContainerInitializer07() throws CoreException { try { boolean gotException = false; try { ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P1", "/P1/lib.jar"}) { public void initialize(IPath containerPath, IJavaProject project) throws CoreException { throw new OperationCanceledException("test"); }}); IJavaProject p1 = createJavaProject( "P1", new String[] {}, new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, ""); p1.getResolvedClasspath(true); } catch (OperationCanceledException e) { gotException = true; } assertTrue("Should get an OperationCanceledException", gotException); } finally { stopDeltas(); deleteProject("P1"); } } /* * Ensure that the stack doesn't blow up if initializer is missbehaving * (regression test for bug 61052 Flatten cp container initialization) */ public void testContainerInitializer08() throws CoreException { final int projectLength = 10; final String[] projects = new String[projectLength]; for (int i = 0; i < projectLength; i++) { projects[i] = "P" + i; } try { String[] projectRefs = new String[(projectLength-1) * 2]; for (int i = 0; i < projectLength-1; i++) { projectRefs[i*2] = "P" + i; projectRefs[(i*2)+1] = "/P" + i + "/test.jar"; } ContainerInitializer.setInitializer(new DefaultContainerInitializer(projectRefs) { void foo(int n) { if (n > 0) { foo(n-1); return; } IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); for (int i = 0; i < projectLength-1; i++) { try { JavaCore.create(root.getProject(projects[i])).getResolvedClasspath(true); } catch (JavaModelException e) { // project doesn't exist: ignore } } } public void initialize(IPath containerPath, IJavaProject project) throws CoreException { foo(500); super.initialize(containerPath, project); } }); JavaCore.run(new IWorkspaceRunnable() { public void run(IProgressMonitor monitor) throws CoreException { for (int i = 0; i < projectLength; i++) { createProject(projects[i]); editFile( "/" + projects[i] + "/.project", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<projectDescription>\n" + " <name>" + projects[i] + "</name>\n" + " <comment></comment>\n" + " <projects>\n" + (i == 0 ? "" : "<project>" + projects[i-1] + "</project>\n") + " </projects>\n" + " <buildSpec>\n" + " <buildCommand>\n" + " <name>org.eclipse.jdt.core.javabuilder</name>\n" + " <arguments>\n" + " </arguments>\n" + " </buildCommand>\n" + " </buildSpec>\n" + " <natures>\n" + " <nature>org.eclipse.jdt.core.javanature</nature>\n" + " </natures>\n" + "</projectDescription>" ); createFile( "/" + projects[i] + "/.classpath", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<classpath>\n" + (i == 0 ? "" : "<classpathentry kind=\"src\" path=\"/" + projects[i-1] + "\"/>\n") + " <classpathentry kind=\"con\" path=\"org.eclipse.jdt.core.tests.model.TEST_CONTAINER\"/>\n" + " <classpathentry kind=\"output\" path=\"\"/>\n" + "</classpath>" ); } } }, null); getJavaProject("P0").getResolvedClasspath(true); } finally { stopDeltas(); deleteProjects(projects); } } /* * Ensure that a StackOverFlowError is not thrown if the initializer asks for the resolved classpath * that is being resolved. * (regression test for bug 61040 Should add protect for reentrance to #getResolvedClasspath) */ public void testContainerInitializer09() throws CoreException { try { DefaultContainerInitializer initializer = new DefaultContainerInitializer(new String[] {"P1", "/P1/lib.jar"}) { protected DefaultContainer newContainer(char[][] libPaths) { return new DefaultContainer(libPaths) { public IClasspathEntry[] getClasspathEntries() { try { getJavaProject("P1").getResolvedClasspath(true); } catch (JavaModelException e) { // project doesn't exist: ignore } return super.getClasspathEntries(); } }; } }; ContainerInitializer.setInitializer(initializer); JavaCore.run(new IWorkspaceRunnable() { public void run(IProgressMonitor monitor) throws CoreException { createProject("P1"); editFile( "/P1/.project", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<projectDescription>\n" + " <name>P1</name>\n" + " <comment></comment>\n" + " <projects>\n" + " </projects>\n" + " <buildSpec>\n" + " <buildCommand>\n" + " <name>org.eclipse.jdt.core.javabuilder</name>\n" + " <arguments>\n" + " </arguments>\n" + " </buildCommand>\n" + " </buildSpec>\n" + " <natures>\n" + " <nature>org.eclipse.jdt.core.javanature</nature>\n" + " </natures>\n" + "</projectDescription>" ); createFile( "/P1/.classpath", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<classpath>\n" + " <classpathentry kind=\"con\" path=\"org.eclipse.jdt.core.tests.model.TEST_CONTAINER\"/>\n" + " <classpathentry kind=\"output\" path=\"\"/>\n" + "</classpath>" ); } }, null); getJavaProject("P1").getResolvedClasspath(true); } finally { stopDeltas(); ContainerInitializer.setInitializer(null); deleteProject("P1"); } } /* * Ensure that creating a Java project initializes a container and refreshes the external jar at the same time * without throwing a ConcurrentModificationException * (regression test for bug 63534 ConcurrentModificationException after "catching up") */ public void testContainerInitializer10() throws CoreException { class LogListener implements ILogListener { IStatus loggedStatus; public void logging(IStatus status, String plugin) { this.loggedStatus = status; } } LogListener listener = new LogListener(); try { Platform.addLogListener(listener); final IJavaProject p1 = createJavaProject("P1"); final IJavaProject p2 = createJavaProject("P2"); ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P3", "/P1"}) { public void initialize(IPath containerPath, IJavaProject project) throws CoreException { super.initialize(containerPath, project); getJavaModel().refreshExternalArchives(new IJavaElement[] {p1}, null); } }); getWorkspace().run(new IWorkspaceRunnable() { public void run(IProgressMonitor monitor) throws CoreException { p2.setRawClasspath(new IClasspathEntry[] {JavaCore.newSourceEntry(new Path("/P2/src"))}, new Path("/P2/bin"), null); createProject("P3"); editFile( "/P3/.project", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<projectDescription>\n" + " <name>P3</name>\n" + " <comment></comment>\n" + " <projects>\n" + " </projects>\n" + " <buildSpec>\n" + " <buildCommand>\n" + " <name>org.eclipse.jdt.core.javabuilder</name>\n" + " <arguments>\n" + " </arguments>\n" + " </buildCommand>\n" + " </buildSpec>\n" + " <natures>\n" + " <nature>org.eclipse.jdt.core.javanature</nature>\n" + " </natures>\n" + "</projectDescription>\n" ); createFile( "/P3/.classpath", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<classpath>\n" + " <classpathentry kind=\"src\" path=\"\"/>\n" + " <classpathentry kind=\"var\" path=\"JCL_LIB\"/>\n" + " <classpathentry kind=\"con\" path=\"org.eclipse.jdt.core.tests.model.TEST_CONTAINER\"/>\n" + " <classpathentry kind=\"output\" path=\"\"/>\n" + "</classpath>" ); } }, null); assertEquals("Should not get any exception in log", null, listener.loggedStatus); } finally { Platform.removeLogListener(listener); deleteProject("P1"); deleteProject("P2"); deleteProject("P3"); } } /* * Ensure that a classpath initializer is not run on shutdown * (regression test for bug 93941 Classpath initialization on shutdown) */ public void testContainerInitializer11() throws CoreException { boolean hasExited = false; try { ContainerInitializer.setInitializer(null); createJavaProject( "P", new String[] {}, new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, ""); simulateExitRestart(); DefaultContainerInitializer initializer = new DefaultContainerInitializer(new String[] {}) { public void initialize(IPath containerPath,IJavaProject project) throws CoreException { assertTrue("Should not initialize container on shutdown", false); } }; ContainerInitializer.setInitializer(initializer); simulateExit(); hasExited = true; } finally { ContainerInitializer.setInitializer(null); if (hasExited) simulateRestart(); deleteProject("P"); } } /* * Ensure that the initializer is removed from the cache when the project is deleted * (regression test for bug 116072 cached classpath containers not removed when project deleted) */ public void testContainerInitializer12() throws CoreException { try { ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P1", "/P1/lib.jar"})); IJavaProject project = createJavaProject( "P1", new String[] {}, new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, ""); createFile("/P1/lib.jar", ""); IPackageFragmentRoot root = project.getPackageFragmentRoot(getFile("/P1/lib.jar")); assertTrue("/P1/lib.jar should exist", root.exists()); deleteProject("P1"); class Initializer extends DefaultContainerInitializer { boolean initialized; public Initializer(String[] args) { super(args); } public void initialize(IPath containerPath, IJavaProject p) throws CoreException { super.initialize(containerPath, p); this.initialized = true; } } Initializer initializer = new Initializer(new String[] {"P1", "/P1/lib.jar"}); ContainerInitializer.setInitializer(initializer); createJavaProject( "P1", new String[] {}, new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, ""); createFile("/P1/lib.jar", ""); assertTrue("/P1/lib.jar should exist", root.exists()); assertTrue("Should have been initialized", initializer.initialized); } finally { stopDeltas(); deleteProject("P1"); } } /* * Ensures that no resource deta is reported if a container that was not initialized is initialized with null * (regression test for bug 149043 Unresolvable classpath container leads to lots of scheduled jobs) */ public void testContainerInitializer13() throws CoreException { IResourceChangeListener listener = new IResourceChangeListener() { StringBuffer buffer = new StringBuffer(); public void resourceChanged(IResourceChangeEvent event) { this.buffer.append(event.getDelta().findMember(new Path("/P1"))); } public String toString() { return this.buffer.toString(); } }; try { NullContainerInitializer nullInitializer = new NullContainerInitializer(); ContainerInitializer.setInitializer(nullInitializer); IJavaProject project = createJavaProject( "P1", new String[] {}, new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, ""); // simulate state on startup simulateExitRestart(); getWorkspace().addResourceChangeListener(listener, IResourceChangeEvent.POST_CHANGE); // force resolution of container project.findPackageFragmentRoots(project.getRawClasspath()[0]); assertEquals( "Unexpected resource delta on startup", "", listener.toString() ); } finally { getWorkspace().removeResourceChangeListener(listener); deleteProject("P1"); } } /* * Ensures that a misbehaving container (that initializes another project than the one asked for) doesn't cause * the container to be initialized again * (regression test for bug 160005 Add protection about misbehaving container initializer) */ public void testContainerInitializer14() throws CoreException { try { createProject("P1"); createFile("/P1/lib.jar", ""); class Container extends DefaultContainerInitializer { int initializeCount = 0; Container(String[] values) { super(values); } public void initialize(IPath containerPath, IJavaProject project) throws CoreException { this.initializeCount++; super.initialize(containerPath, getJavaProject("P1")); } } Container container = new Container(new String[] {"P2", "/P1/lib.jar"}); ContainerInitializer.setInitializer(container); IJavaProject p2 = createJavaProject( "P2", new String[] {}, new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, ""); p2.getResolvedClasspath(true); assertEquals("Unexpected number of initalizations", 1, container.initializeCount); } finally { stopDeltas(); deleteProject("P1"); deleteProject("P2"); } } /* * Ensures that if a container is misbehaving (it doesn't initialize a project when asked for), * then the resulting container's classpath is not null * (regression test for bug 161846 Expanding a java project with invalid classpath container entries in Project Explorer causes CPU to stay at 100%) */ public void testContainerInitializer15() throws CoreException { try { class Container extends DefaultContainerInitializer { Container(String[] values) { super(values); } public void initialize(IPath containerPath, IJavaProject project) throws CoreException { } } Container container = new Container(new String[] {"P1", "/P1/lib.jar"}); ContainerInitializer.setInitializer(container); IJavaProject p1 = createJavaProject( "P1", new String[] {}, new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, ""); IClasspathContainer classpathContainer = JavaCore.getClasspathContainer(new Path("org.eclipse.jdt.core.tests.model.TEST_CONTAINER"), p1); assertClasspathEquals(classpathContainer.getClasspathEntries(), ""); } finally { stopDeltas(); deleteProject("P1"); } } /* * Ensure that an initializer cannot return a project entry that points to the project of the container (cycle). */ public void testContainerInitializer16() throws CoreException { try { ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P1", "/P1"})); JavaModelException exception = null; try { IJavaProject p1 = createJavaProject( "P1", new String[] {}, new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, ""); p1.getResolvedClasspath(true); } catch (JavaModelException e) { exception = e; } assertExceptionEquals( "Unexpected expection", "Project 'P1' cannot reference itself", exception); } finally { stopDeltas(); deleteProject("P1"); } } /* * Ensures that no resource deta is reported if a container is initialized right after startup to the same value it had before shutdown. * (regression test for bug 175849 Project is touched on restart) */ public void testContainerInitializer17() throws CoreException { IResourceChangeListener listener = new IResourceChangeListener() { StringBuffer buffer = new StringBuffer(); public void resourceChanged(IResourceChangeEvent event) { this.buffer.append(event.getDelta().findMember(new Path("/P2"))); } public String toString() { return this.buffer.toString(); } }; try { createProject("P1"); createFile("/P1/lib.jar", ""); ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P2", "/P1/lib.jar", "P3", "/P1/lib.jar"})); IJavaProject p2 = createJavaProject( "P2", new String[] {}, new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, ""); createJavaProject( "P3", new String[] {}, new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, ""); // simulate state on startup simulateExitRestart(); getWorkspace().addResourceChangeListener(listener, IResourceChangeEvent.POST_CHANGE); // initialize to the same value ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P2", "/P1/lib.jar", "P3", "/P1/lib.jar"}) { public void initialize(IPath containerPath, IJavaProject project) throws CoreException { // simulate concurrency (another thread is initializing all containers in parallel and thus this flag is set to true) JavaModelManager.getJavaModelManager().batchContainerInitializations = JavaModelManager.NEED_BATCH_INITIALIZATION; super.initialize(containerPath, project); } }); p2.getResolvedClasspath(true); assertEquals( "Unexpected resource delta on container initialization", "", listener.toString() ); } finally { getWorkspace().removeResourceChangeListener(listener); deleteProject("P1"); deleteProject("P2"); deleteProject("P3"); } } /* * Ensures that an unbound container marker is created if container is reset to null * (regression test for 182204 Deleting a JRE referenced by container does not result in unbound container problem) */ public void testContainerInitializer18() throws CoreException { try { ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P1", "/P1/lib.jar"})); IJavaProject p1 = createJavaProject( "P1", new String[] {}, new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, ""); createFile("/P1/lib.jar", ""); p1.getResolvedClasspath(true); waitForAutoBuild(); ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[0])); JavaCore.setClasspathContainer(new Path("org.eclipse.jdt.core.tests.model.TEST_CONTAINER"), new IJavaProject[] {p1}, new IClasspathContainer[] {null}, null); assertMarkers( "Unexpected markers", "Unbound classpath container: \'org.eclipse.jdt.core.tests.model.TEST_CONTAINER\' in project \'P1\'", p1); } finally { deleteProject("P1"); } } /* * Ensures that a container is not kept in the cache if no longer referenced on the classpath * (regression test for 139446 [build path] bug in the Edit Library dialog box, when changing the default JRE, and switching from alternate JRE to workspace default) */ public void testContainerInitializer19() throws CoreException { try { // setup ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P1", "/P1/lib1.jar"})); IJavaProject p1 = createJavaProject( "P1", new String[] {}, new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, ""); createFile("/P1/lib1.jar", ""); createFile("/P1/lib2.jar", ""); p1.getResolvedClasspath(true); IClasspathEntry[] initialClasspath = p1.getRawClasspath(); // remove reference to container, change initializer, and add reference to container back p1.setRawClasspath(new IClasspathEntry[0], null); ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P1", "/P1/lib2.jar"})); p1.setRawClasspath(initialClasspath, null); assertClasspathEquals( p1.getResolvedClasspath(true), "/P1/lib2.jar[CPE_LIBRARY][K_BINARY][isExported:false]" ); } finally { deleteProject("P1"); } } /* * Ensures that container a container is not kept in the cache if no longer referenced on the classpath * (regression test for 136382 [classpath] Discard container if not referenced on classpath) */ public void testContainerInitializer20() throws CoreException { try { IJavaProject p = createJavaProject("P"); final StringBuffer paths = new StringBuffer(); DefaultContainerInitializer initializer = new DefaultContainerInitializer(new String[] {"P", "/P/lib.jar"}) { public void initialize(IPath containerPath, IJavaProject project) throws CoreException { paths.append(containerPath); paths.append('\n'); super.initialize(containerPath, project); } }; ContainerInitializer.setInitializer(initializer); setClasspath(p, new IClasspathEntry[] {JavaCore.newContainerEntry(new Path("org.eclipse.jdt.core.tests.model.TEST_CONTAINER/JRE1"))}); setClasspath(p, new IClasspathEntry[] {JavaCore.newContainerEntry(new Path("org.eclipse.jdt.core.tests.model.TEST_CONTAINER/JRE2"))}); setClasspath(p, new IClasspathEntry[] {JavaCore.newContainerEntry(new Path("org.eclipse.jdt.core.tests.model.TEST_CONTAINER/JRE1"))}); assertStringEquals( "org.eclipse.jdt.core.tests.model.TEST_CONTAINER/JRE1\n" + "org.eclipse.jdt.core.tests.model.TEST_CONTAINER/JRE2\n" + "org.eclipse.jdt.core.tests.model.TEST_CONTAINER/JRE1\n", paths.toString(), false); } finally { stopDeltas(); deleteProject("P"); } } public void testContainerInitializer21() throws CoreException { try { createProject("P1"); createExternalFolder("externalLib"); ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P2", getExternalResourcePath("externalLib")})); IJavaProject p2 = createJavaProject( "P2", new String[] {}, new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, ""); IPackageFragmentRoot root = p2.getPackageFragmentRoot(getExternalResourcePath("externalLib")); assertTrue(getExternalResourcePath("externalLib") + " should exist", root.exists()); } finally { stopDeltas(); deleteExternalResource("externalLib"); deleteProject("P1"); deleteProject("P2"); } } public void testContainerInitializer22() throws CoreException { try { createProject("P1"); createExternalFile("externalLib.abc", ""); ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P2", getExternalResourcePath("externalLib.abc")})); IJavaProject p2 = createJavaProject( "P2", new String[] {}, new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, ""); IPackageFragmentRoot root = p2.getPackageFragmentRoot(getExternalResourcePath("externalLib.abc")); assertTrue(getExternalResourcePath("externalLib.abc") + " should exist", root.exists()); } finally { stopDeltas(); deleteExternalResource("externalLib.abc"); deleteProject("P1"); deleteProject("P2"); } } public void testContainerInitializer23() throws CoreException { try { createProject("P1"); IFile lib = createFile("/P1/internalLib.abc", ""); ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P2", "/P1/internalLib.abc"})); IJavaProject p2 = createJavaProject( "P2", new String[] {}, new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, ""); IPackageFragmentRoot root = p2.getPackageFragmentRoot(lib); assertTrue("/P1/internalLib.abc should exist", root.exists()); } finally { stopDeltas(); deleteExternalResource("externalLib.abc"); deleteProject("P1"); deleteProject("P2"); } } /* * Ensures that the value of a resolved classpath is correct if another thread is resolving the classpath concurrently * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=232478 ) */ public void testContainerInitializer24() throws Exception { BPThread.TIMEOUT = 30000; // wait 30s max BPThread thread = new BPThread("getResolvedClasspath()"); ClasspathResolutionBreakpointListener listener = new ClasspathResolutionBreakpointListener(new BPThread[] {thread}); try { createProject("P1"); createFile("/P1/lib.jar", ""); ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P2", "/P1/lib.jar"})); final JavaProject project2 = (JavaProject) createJavaProject( "P2", new String[] {}, new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, ""); simulateExit(); try { deleteResource(JavaCore.getPlugin().getStateLocation().append("variablesAndContainers.dat").toFile()); } finally { simulateRestart(); } JavaProject.addCPResolutionBPListener(listener); thread.start(new Runnable() { public void run() { try { project2.getResolvedClasspath(); } catch (JavaModelException e) { e.printStackTrace(); } } }); thread.runToBP(1); thread.runToBP(2); thread.runToBP(3); IClasspathEntry[] classpath = project2.getResolvedClasspath(); assertClasspathEquals( classpath, "/P1/lib.jar[CPE_LIBRARY][K_BINARY][isExported:false]" ); } finally { JavaProject.removeCPResolutionBPListener(listener); thread.runToEnd(); deleteProjects(new String[] {"P1", "P2"}); } } /* * Ensures that the project references are updated on startup if the initializer gives a different value. */ public void testContainerInitializer25() throws CoreException { try { createProject("P1"); createFile("/P1/lib.jar", ""); ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P2", "/P1/lib.jar"})); IJavaProject p2 = createJavaProject( "P2", new String[] {}, new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, ""); ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P2", "/P1"})); // simulate state on startup simulateExitRestart(); p2.getResolvedClasspath(true); assertResourcesEqual( "Unexpected project references on startup", "/P1", p2.getProject().getReferencedProjects()); } finally { deleteProject("P1"); deleteProject("P2"); } } /* * https://bugs.eclipse.org/bugs/show_bug.cgi?id=327471 * [java.io.EOFException at java.io.DataInputStream.readInt(Unknown Source)] * This test ensures that there is no exception on a restart of eclipse after * the project is closed after the workspace save */ public void testContainerInitializer26() throws CoreException { try { createProject("P1"); createFile("/P1/lib.jar", ""); ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P2", "/P1/lib.jar"})); IJavaProject p2 = createJavaProject( "P2", new String[] {}, new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, ""); ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P2", "/P1"})); waitForAutoBuild(); getWorkspace().save(true/*full save*/, null/*no progress*/); p2.getProject().close(null); // close the project after the save and before the shutdown JavaModelManager.getJavaModelManager().shutdown(); startLogListening(); simulateRestart(); assertLogEquals(""); // no error should be logged } finally { stopLogListening(); deleteProject("P1"); deleteProject("P2"); } } public void testVariableInitializer01() throws CoreException { try { createProject("P1"); createFile("/P1/lib.jar", ""); VariablesInitializer.setInitializer(new DefaultVariableInitializer(new String[] {"TEST_LIB", "/P1/lib.jar"})); IJavaProject p2 = createJavaProject("P2", new String[] {}, new String[] {"TEST_LIB"}, ""); IPackageFragmentRoot root = p2.getPackageFragmentRoot(getFile("/P1/lib.jar")); assertTrue("/P1/lib.jar should exist", root.exists()); } finally { deleteProject("P1"); deleteProject("P2"); VariablesInitializer.reset(); } } public void testVariableInitializer02() throws CoreException { try { createProject("P1"); createFile("/P1/lib.jar", ""); createFile("/P1/src.zip", ""); VariablesInitializer.setInitializer(new DefaultVariableInitializer(new String[] { "TEST_LIB", "/P1/lib.jar", "TEST_SRC", "/P1/src.zip", "TEST_ROOT", "src", })); IJavaProject p2 = createJavaProject("P2", new String[] {}, new String[] {"TEST_LIB,TEST_SRC,TEST_ROOT"}, ""); IPackageFragmentRoot root = p2.getPackageFragmentRoot(getFile("/P1/lib.jar")); assertEquals("Unexpected source attachment path", "/P1/src.zip", root.getSourceAttachmentPath().toString()); assertEquals("Unexpected source attachment root path", "src", root.getSourceAttachmentRootPath().toString()); } finally { deleteProject("P1"); deleteProject("P2"); VariablesInitializer.reset(); } } public void testVariableInitializer03() throws CoreException { try { createProject("P1"); createFile("/P1/lib.jar", ""); createFile("/P1/src.zip", ""); String[] variableValues = new String[] { "TEST_LIB", "/P1/lib.jar", "TEST_SRC", "/P1/src.zip", "TEST_ROOT", "src", }; VariablesInitializer.setInitializer(new DefaultVariableInitializer(variableValues)); createJavaProject("P2", new String[] {}, new String[] {"TEST_LIB,TEST_SRC,TEST_ROOT"}, ""); // simulate state on startup simulateExitRestart(); startDeltas(); //JavaModelManager.CP_RESOLVE_VERBOSE=true; getJavaProject("P2").getResolvedClasspath(true); assertDeltas( "Unexpected delta on startup", "" ); } finally { //JavaModelManager.CP_RESOLVE_VERBOSE=false; stopDeltas(); deleteProject("P1"); deleteProject("P2"); VariablesInitializer.reset(); } } public void testVariableInitializer04() throws CoreException { try { final StringBuffer buffer = new StringBuffer(); VariablesInitializer.setInitializer(new VariablesInitializer.ITestInitializer() { public void initialize(String variable) throws JavaModelException { buffer.append("Initializing " + variable + "\n"); IPath path = new Path(variable.toLowerCase()); buffer.append("Setting variable " + variable + " to " + path + "\n"); JavaCore.setClasspathVariable(variable, path, null); } }); createJavaProject("P", new String[] {}, new String[] {"TEST_LIB,TEST_SRC,TEST_ROOT"}, ""); assertEquals( "Initializing TEST_LIB\n" + "Setting variable TEST_LIB to test_lib\n", buffer.toString()); } finally { deleteProject("P"); VariablesInitializer.reset(); } } public void testVariableInitializer05() throws CoreException { try { final StringBuffer buffer = new StringBuffer(); VariablesInitializer.setInitializer(new VariablesInitializer.ITestInitializer() { public void initialize(String variable) throws JavaModelException { buffer.append("Initializing " + variable + "\n"); IPath path = new Path(variable.toLowerCase()); JavaCore.getClasspathVariable("TEST_SRC"); buffer.append("Setting variable " + variable + " to " + path + "\n"); JavaCore.setClasspathVariable(variable, path, null); } }); createJavaProject("P", new String[] {}, new String[] {"TEST_LIB,TEST_SRC,TEST_ROOT"}, ""); assertEquals( "Initializing TEST_LIB\n" + "Initializing TEST_SRC\n" + "Setting variable TEST_SRC to test_src\n" + "Setting variable TEST_LIB to test_lib\n", buffer.toString()); } finally { deleteProject("P"); VariablesInitializer.reset(); } } /* * Ensures that if the initializer doesn't initialize a variable, it can be * initialized later on. */ public void testVariableInitializer06() throws CoreException { try { final StringBuffer buffer = new StringBuffer(); VariablesInitializer.setInitializer(new VariablesInitializer.ITestInitializer() { public void initialize(String variable) { // do nothing buffer.append("Ignoring request to initialize"); } }); IPath path = JavaCore.getClasspathVariable("TEST_SRC"); assertEquals( "Unexpected value of TEST_SRC after initializer was called", null, path); IPath varValue = new Path("src.zip"); JavaCore.setClasspathVariable("TEST_SRC", varValue, null); path = JavaCore.getClasspathVariable("TEST_SRC"); assertEquals( "Unexpected value of TEST_SRC after setting it", varValue, path); } finally { VariablesInitializer.reset(); } } public void testVariableInitializer07() throws CoreException { try { createProject("P1"); createFile("/P1/lib.jar", ""); createFile("/P1/src.zip", ""); String[] variableValues = new String[] { "TEST_LIB", "/P1/lib.jar", "TEST_SRC", "/P1/src.zip", "TEST_ROOT", "src", }; VariablesInitializer.setInitializer(new DefaultVariableInitializer(variableValues)); createJavaProject("P2", new String[] {}, new String[] {"TEST_LIB,TEST_SRC,TEST_ROOT"}, ""); // change value of TEST_LIB createFile("/P1/lib2.jar", ""); VariablesInitializer.setInitializer(new DefaultVariableInitializer(new String[] { "TEST_LIB", "/P1/lib2.jar", "TEST_SRC", "/P1/src.zip", "TEST_ROOT", "src", })); // simulate state on startup simulateExitRestart(); startDeltas(); //JavaModelManager.CP_RESOLVE_VERBOSE=true; getJavaProject("P2").getResolvedClasspath(true); assertDeltas( "Unexpected delta on startup", "P2[*]: {CHILDREN | RESOLVED CLASSPATH CHANGED}\n" + " /P1/lib.jar[*]: {REMOVED FROM CLASSPATH}\n" + " /P1/lib2.jar[*]: {ADDED TO CLASSPATH}" ); } finally { //JavaModelManager.CP_RESOLVE_VERBOSE=false; stopDeltas(); deleteProject("P1"); deleteProject("P2"); VariablesInitializer.reset(); } } /* * Ensure that an OperationCanceledException goes through * (regression test for bug 59363 Should surface cancellation exceptions) */ public void testVariableInitializer08() throws CoreException { try { boolean gotException = false; try { VariablesInitializer.setInitializer(new DefaultVariableInitializer(new String[] {"TEST_LIB", "/P1/lib.jar"}) { public void initialize(String variable) throws JavaModelException { throw new OperationCanceledException("test"); } }); IJavaProject p1 = createJavaProject("P1", new String[] {}, new String[] {"TEST_LIB"}, ""); p1.getResolvedClasspath(true); } catch (OperationCanceledException e) { gotException = true; } assertTrue("Should get an OperationCanceledException", gotException); } finally { deleteProject("P1"); VariablesInitializer.reset(); } } /* * Ensure that removing a classpath variable while initializing it doesn't throw a StackOverFlowError * (regression test for bug 112609 StackOverflow when initializing Java Core) */ public void testVariableInitializer09() throws CoreException { try { VariablesInitializer.setInitializer(new DefaultVariableInitializer(new String[] {"TEST_LIB", "/P1/lib.jar"}) { public void initialize(String variable) throws JavaModelException { JavaCore.removeClasspathVariable("TEST_LIB", null); } }); IJavaProject p1 = createJavaProject("P1", new String[] {}, new String[] {"TEST_LIB"}, ""); IClasspathEntry[] resolvedClasspath = p1.getResolvedClasspath(true); assertClasspathEquals( resolvedClasspath, "" ); } finally { deleteProject("P1"); VariablesInitializer.reset(); } } /* * Ensures that not initializing a classpath variable and asking for its value returns null * (regression test for bug 113110 TestFailures in DebugSuite) */ public void testVariableInitializer10() throws CoreException { try { VariablesInitializer.setInitializer(new DefaultVariableInitializer(new String[] {"TEST_LIB", "/P1/lib.jar"}) { public void initialize(String variable) throws JavaModelException { // don't initialize } }); // force resolution JavaCore.getClasspathVariable("TEST_LIB"); // second call should still be null assertEquals("TEST_LIB should be null", null, JavaCore.getClasspathVariable("TEST_LIB")); } finally { deleteProject("P1"); VariablesInitializer.reset(); } } /** * Bug 125965: [prefs] "Export/Import preferences" should let user to choose wich preference to export/import * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=125965" */ public void testVariableInitializer11() throws CoreException { try { // Create initializer String varName = "TEST_LIB"; String initialValue = "/P1/lib.jar"; String newValue = "/tmp/file.jar"; VariablesInitializer.setInitializer(new DefaultVariableInitializer(new String[] {varName, initialValue})); assertEquals("JavaCore classpath value should have been initialized", JavaCore.getClasspathVariable(varName).toString(), initialValue); // Modify preference JavaModelManager manager = JavaModelManager.getJavaModelManager(); IEclipsePreferences preferences = manager.getInstancePreferences(); preferences.put(JavaModelManager.CP_VARIABLE_PREFERENCES_PREFIX+varName, newValue); // verify that JavaCore preferences have been reset assertEquals("JavaCore classpath value should be unchanged", JavaCore.getClasspathVariable(varName).toString(), initialValue); assertEquals("JavaCore preferences value should be unchanged", preferences.get(varName, "X"), initialValue); } finally { VariablesInitializer.reset(); } } /** * @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, IOException { try { // Create initializer String varName = "TEST_DEPRECATED"; String filePath = "/P1/lib.jar"; VariablesInitializer.setInitializer(new DefaultVariableInitializer(new String[] {varName, filePath})); assertEquals("JavaCore classpath value should have been initialized", JavaCore.getClasspathVariable(varName).toString(), filePath); // Verify that Classpath Variable is deprecated assertEquals("JavaCore classpath variable should be deprecated", "Test deprecated flag", JavaCore.getClasspathVariableDeprecationMessage(varName)); // Create project IJavaProject project = createJavaProject("P1"); 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); assertFalse("Status should not be OK", status.isOK()); assertEquals("Status should have WARNING severity", IStatus.WARNING, status.getSeverity()); assertEquals("Status should have deprecated code", IJavaModelStatusConstants.DEPRECATED_VARIABLE, status.getCode()); } finally { VariablesInitializer.reset(); deleteProject("P1"); } } public void testVariableInitializerUnboundAndDeprecated() throws CoreException { try { // Create initializer String varName = "TEST_DEPRECATED"; String filePath = "/P1/lib.jar"; VariablesInitializer.setInitializer(new DefaultVariableInitializer(new String[] {varName, filePath})); assertEquals("JavaCore classpath value should have been initialized", JavaCore.getClasspathVariable(varName).toString(), filePath); // Verify that Classpath Variable is deprecated assertEquals("JavaCore classpath variable should be deprecated", "Test deprecated flag", JavaCore.getClasspathVariableDeprecationMessage(varName)); // Create project IJavaProject project = createJavaProject("P1"); IClasspathEntry variable = JavaCore.newVariableEntry(new Path("TEST_DEPRECATED"), null, null); IJavaModelStatus status = JavaConventions.validateClasspathEntry(project, variable, false); assertStatus("Project 'P1' is missing required library: 'lib.jar'", status); assertFalse("Status should not be OK", status.isOK()); assertEquals("Status should have WARNING severity", IStatus.ERROR, status.getSeverity()); assertEquals("Status should have deprecated code", IJavaModelStatusConstants.INVALID_CLASSPATH, status.getCode()); } finally { VariablesInitializer.reset(); deleteProject("P1"); } } /** * @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, IOException { try { // Create initializer String varName = "TEST_READ_ONLY"; String path = "/P1/lib.jar"; VariablesInitializer.setInitializer(new DefaultVariableInitializer(new String[] { varName, path })); assertEquals("JavaCore classpath value should have been initialized", JavaCore.getClasspathVariable(varName).toString(), path); // verify that Classpath Variable is read-only assertTrue("JavaCore classpath variable should be read-only", JavaCore.isClasspathVariableReadOnly(varName)); // Create project IJavaProject project = createJavaProject("P1"); 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); assertTrue("Status should be OK", status.isOK()); assertEquals("Status should be VERIFIED_OK", JavaModelStatus.VERIFIED_OK, status); } finally { VariablesInitializer.reset(); deleteProject("P1"); } } public void testVariableInitializerDeprecatedAndReadOnly() throws CoreException, IOException { try { // Create initializer String varName = "TEST_DEPRECATED_READ_ONLY"; String path = "/P1/lib.jar"; VariablesInitializer.setInitializer(new DefaultVariableInitializer(new String[] { varName, path })); assertEquals("JavaCore classpath value should have been initialized", JavaCore.getClasspathVariable(varName).toString(), path); // verify that Classpath Variable is read-only assertEquals("JavaCore classpath variable should be deprecated", "A deprecated and read-only initializer", JavaCore.getClasspathVariableDeprecationMessage(varName)); assertTrue("JavaCore classpath variable should be read-only", JavaCore.isClasspathVariableReadOnly(varName)); // Create project IJavaProject project = createJavaProject("P1"); 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); assertFalse("Status should not be OK", status.isOK()); assertEquals("Status should have WARNING severity", IStatus.WARNING, status.getSeverity()); assertEquals("Status should have deprecated code", IJavaModelStatusConstants.DEPRECATED_VARIABLE, status.getCode()); } finally { VariablesInitializer.reset(); deleteProject("P1"); } } /** * @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, IOException { try { // Create initializer String varName = "TEST_DEPRECATED_READ_ONLY"; String path = "/P1/lib.jar"; VariablesInitializer.setInitializer(new DefaultVariableInitializer(new String[] { varName, path })); assertEquals("JavaCore classpath value should have been initialized", JavaCore.getClasspathVariable(varName).toString(), path); // verify that Classpath Variable is read-only assertEquals("JavaCore classpath variable should be deprecated", "A deprecated and read-only initializer", JavaCore.getClasspathVariableDeprecationMessage(varName)); assertTrue("JavaCore classpath variable should be read-only", JavaCore.isClasspathVariableReadOnly(varName)); // Create project IJavaProject project = createJavaProject("P1"); 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; System.arraycopy(entries, 0, entries = new IClasspathEntry[length+1], 0, length); entries[length] = variable; project.setRawClasspath(entries, null); // verify markers waitForAutoBuild(); IMarker[] markers = project.getProject().findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO); sortMarkers(markers); assertMarkers("Unexpected marker(s)", "Classpath variable 'TEST_DEPRECATED_READ_ONLY' in project 'P1' is deprecated: A deprecated and read-only initializer", markers); assertEquals("Marker on deprecated variable should be a WARNING", IMarker.SEVERITY_WARNING, markers[0].getAttribute(IMarker.SEVERITY, -1)); } finally { VariablesInitializer.reset(); deleteProject("P1"); } } /** * @bug 186113: [model] classpath variable deprecation messages not initialized when called * @test a) Verify that deprecation message can be get through {@link JavaCore#getClasspathVariableDeprecationMessage(String)} * even if the variable initializer was not called before * b) Verify that message is not stored in cache when variable is not initialized (othwerise we could not free it up...) * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=186113" */ public void testVariableInitializerBug186113a() throws CoreException { assertEquals("Invalid deprecation message!", "Test deprecated flag", JavaCore.getClasspathVariableDeprecationMessage("TEST_DEPRECATED") ); } public void testVariableInitializerBug186113b() throws CoreException { JavaCore.getClasspathVariableDeprecationMessage("TEST_DEPRECATED"); assertNull("Deprecation message should not have been stored!", JavaModelManager.getJavaModelManager().deprecatedVariables.get("TEST_DEPRECATED")); } /** * @bug 200449: [model] classpath variable deprecation messages not initialized when called * @test a) Verify that deprecation message is well stored in cache when variable is iniatialized * b) Verify that deprecation message is well removed in cache when variable is removed * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=200449" */ public void testVariableInitializerBug200449() throws CoreException { try { // Create initializer String varName = "TEST_DEPRECATED"; String filePath = "/P1/lib.jar"; VariablesInitializer.setInitializer(new DefaultVariableInitializer(new String[] {varName, filePath})); JavaCore.getClasspathVariable(varName); // init variable // Verify that deprecation message has been stored assertNotNull("Deprecation message should have been stored!", JavaModelManager.getJavaModelManager().deprecatedVariables.get("TEST_DEPRECATED")); } finally { VariablesInitializer.reset(); deleteProject("P1"); } } public void testVariableInitializerBug200449b() throws CoreException { // Verify that deprecated variable has been removed assertNull("Deprecation message should have been removed!", JavaModelManager.getJavaModelManager().deprecatedVariables.get("TEST_DEPRECATED")); } /** * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=61872" */ public void testUserLibraryInitializer1() throws Exception { try { // Create new user library "SWT" ClasspathContainerInitializer initializer= JavaCore.getClasspathContainerInitializer(JavaCore.USER_LIBRARY_CONTAINER_ID); String libraryName = "SWT"; IPath containerPath = new Path(JavaCore.USER_LIBRARY_CONTAINER_ID); UserLibraryClasspathContainer containerSuggestion = new UserLibraryClasspathContainer(libraryName); initializer.requestClasspathContainerUpdate(containerPath.append(libraryName), null, containerSuggestion); // Create java project createJavaProject("p61872"); IFile jarFile = createFile("/p61872/swt.jar", ""); IFile srcFile = createFile("/p61872/swtsrc.zip", ""); // Modify user library IEclipsePreferences preferences = InstanceScope.INSTANCE.getNode(JavaCore.PLUGIN_ID); String propertyName = JavaModelManager.CP_USERLIBRARY_PREFERENCES_PREFIX+"SWT"; StringBuffer propertyValue = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<userlibrary systemlibrary=\"false\" version=\"1\">\r\n<archive"); String jarFullPath = getWorkspaceRoot().getLocation().append(jarFile.getFullPath()).toString(); propertyValue.append(" path=\""+jarFullPath); propertyValue.append("\"/>\r\n</userlibrary>\r\n"); preferences.put(propertyName, propertyValue.toString()); preferences.flush(); // Modify project classpath editFile( "/p61872/.classpath", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<classpath>\n" + " <classpathentry kind=\"con\" path=\"org.eclipse.jdt.USER_LIBRARY/SWT\"/>\n" + " <classpathentry kind=\"output\" path=\"\"/>\n" + "</classpath>" ); // Verify IClasspathEntry[] entries = getJavaProject("p61872").getResolvedClasspath(true); assertEquals("Invalid entries number in resolved classpath for project p61872!", 1, entries.length); assertEquals("Invalid path for project 61872 classpath entry!", jarFullPath.toLowerCase(), entries[0].getPath().toString().toLowerCase()); assertNull("Project 61872 classpath entry should not have any source attached!", entries[0].getSourceAttachmentPath()); // Modify user library propertyValue = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<userlibrary systemlibrary=\"false\" version=\"1\">\r\n<archive"); String srcFullPath = getWorkspaceRoot().getLocation().append(srcFile.getFullPath()).toString(); propertyValue.append(" sourceattachment=\""+srcFullPath); propertyValue.append("\" path=\""+jarFullPath); propertyValue.append("\"/>\r\n</userlibrary>\r\n"); preferences.put(propertyName, propertyValue.toString()); preferences.flush(); // Verify entries = getJavaProject("p61872").getResolvedClasspath(true); assertEquals("Invalid entries number in resolved classpath for project p61872!", 1, entries.length); assertEquals("Invalid path for project 61872 classpath entry!", jarFullPath.toLowerCase(), entries[0].getPath().toString().toLowerCase()); assertEquals("Invalid source attachement path for project 61872 classpath entry!", srcFullPath.toLowerCase(), entries[0].getSourceAttachmentPath().toString().toLowerCase()); } finally { deleteProject("p61872"); } } /** * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=346002" * @throws Exception */ public void testBug346002() throws Exception { ClasspathContainerInitializer initializer = JavaCore.getClasspathContainerInitializer(JavaCore.USER_LIBRARY_CONTAINER_ID); String libraryName = "TEST"; IPath containerPath = new Path(JavaCore.USER_LIBRARY_CONTAINER_ID); UserLibraryClasspathContainer containerSuggestion = new UserLibraryClasspathContainer(libraryName); initializer.requestClasspathContainerUpdate(containerPath.append(libraryName), null, containerSuggestion); String libPath = "C:/test/test.jar"; IEclipsePreferences preferences = InstanceScope.INSTANCE.getNode(JavaCore.PLUGIN_ID); String propertyName = JavaModelManager.CP_USERLIBRARY_PREFERENCES_PREFIX+ "TEST"; StringBuffer propertyValue = new StringBuffer( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<userlibrary systemlibrary=\"false\" version=\"2\">\r\n<archive"); propertyValue.append(" path=\"" + libPath + "\"/>\r\n"); propertyValue.append("</userlibrary>\r\n"); preferences.put(propertyName, propertyValue.toString()); propertyName = JavaModelManager.CP_USERLIBRARY_PREFERENCES_PREFIX + "INVALID"; propertyValue = new StringBuffer( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<userlibrary systemlibrary=\"false\" version=\"2\">\r\n<archive"); propertyValue.append(" path=\"\"/>"); propertyValue.append("</userlibrary>\r\n"); preferences.put(propertyName, propertyValue.toString()); preferences.flush(); try { simulateExitRestart(); UserLibrary userLibrary = JavaModelManager.getUserLibraryManager().getUserLibrary(libraryName); assertNotNull(userLibrary); IPath entryPath = userLibrary.getEntries()[0].getPath(); assertEquals("Path should be absolute", true, entryPath.isAbsolute()); userLibrary = JavaModelManager.getUserLibraryManager().getUserLibrary("INVALID"); assertNull(userLibrary); } catch (ClasspathEntry.AssertionFailedException e) { fail("Should not throw AssertionFailedException"); } } }