| /******************************************************************************* |
| * Copyright (c) 2000, 2018 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * 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 java.util.concurrent.atomic.AtomicInteger; |
| import java.util.concurrent.atomic.AtomicReference; |
| |
| 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.core.tests.model.Semaphore.TimeOutException; |
| 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); |
| assertBuildPathMarkers( |
| "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"); |
| } |
| } |
| |
| /* |
| * Ensures that when multiple threads enter the batch container initialization, |
| * a second thread does not initialize a container if the first thread has already completed it |
| */ |
| public void testBug525597() throws CoreException { |
| try { |
| createProject("P1"); |
| createFile("/P1/lib.jar", ""); |
| ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P2", "/P1/lib.jar", "P3", "/P1/lib.jar"})); |
| 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"}, |
| ""); |
| createJavaProject( |
| "P4", |
| new String[] {}, |
| new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, |
| ""); |
| |
| // simulate state on startup |
| simulateExitRestart(); |
| |
| Thread helperThread = new Thread() { |
| @Override |
| public void run() { |
| try { |
| JavaModelManager javaModelManager = JavaModelManager.getJavaModelManager(); |
| javaModelManager.containerRemove(null); |
| javaModelManager.forceBatchInitializations(false); |
| javaModelManager.getClasspathContainer(Path.EMPTY, null); |
| } catch (JavaModelException e) { |
| e.printStackTrace(); |
| } |
| } |
| }; |
| helperThread.setName("ClasspathInitializerTests Helper"); |
| AtomicInteger p3Counter=new AtomicInteger(0); |
| Thread mainThread=Thread.currentThread(); |
| Semaphore s1=new Semaphore(0); |
| Semaphore s2=new Semaphore(0); |
| |
| ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P2", "/P1/lib.jar", "P3", "/P1/lib.jar"}) { |
| public void initialize(IPath containerPath, IJavaProject project) throws CoreException { |
| if (Thread.currentThread() == helperThread) { |
| if (project.getElementName().equals("P2")) { |
| s1.release(); |
| try { |
| s2.acquire(10000); |
| } catch (TimeOutException e) { |
| // ignore |
| } |
| } else if (project.getElementName().equals("P3")) { |
| p3Counter.incrementAndGet(); |
| } |
| } else if (Thread.currentThread() == mainThread) { |
| if (project.getElementName().equals("P3")) { |
| p3Counter.incrementAndGet(); |
| } else if (project.getElementName().equals("P4")) { |
| // this point is reached when helperThread is still waiting in P2 |
| // and already has P3 on its TODO list. |
| s2.release(); |
| } |
| } |
| super.initialize(containerPath, project); |
| } |
| }); |
| helperThread.start(); |
| // wait till helperThread has reached initializer |
| try { |
| s1.acquire(10000); |
| } catch (TimeOutException e1) { |
| // ignore |
| } |
| JavaModelManager.getJavaModelManager().getClasspathContainer(Path.EMPTY, null); |
| try { |
| helperThread.join(); |
| } catch (InterruptedException e) { |
| e.printStackTrace(); |
| } |
| assertEquals("P3 initialized more than once.", 1, p3Counter.get()); |
| } finally { |
| deleteProject("P1"); |
| deleteProject("P2"); |
| deleteProject("P3"); |
| deleteProject("P4"); |
| } |
| } |
| /* |
| * Ensures that when multiple threads enter the batch container initialization, |
| * and two threads both initialize a container, only one result is used. |
| */ |
| public void testBug525597B() throws CoreException { |
| try { |
| createProject("P1"); |
| createFile("/P1/lib.jar", ""); |
| ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P2", "/P1/lib.jar", "P3", "/P1/lib.jar"})); |
| 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(); |
| |
| Thread helperThread = new Thread() { |
| @Override |
| public void run() { |
| try { |
| JavaModelManager javaModelManager = JavaModelManager.getJavaModelManager(); |
| javaModelManager.containerRemove(null); |
| javaModelManager.forceBatchInitializations(false); |
| javaModelManager.getClasspathContainer(Path.EMPTY, null); |
| } catch (JavaModelException e) { |
| e.printStackTrace(); |
| } |
| } |
| }; |
| helperThread.setName("ClasspathInitializerTests Helper"); |
| AtomicInteger p2Counter=new AtomicInteger(0); |
| AtomicReference<IClasspathContainer> helperContainer=new AtomicReference<>(); |
| AtomicReference<IClasspathContainer> mainContainer=new AtomicReference<>(); |
| Thread mainThread=Thread.currentThread(); |
| Semaphore s1=new Semaphore(0); |
| Semaphore s2=new Semaphore(0); |
| Semaphore s3=new Semaphore(0); |
| Semaphore s4=new Semaphore(0); |
| AtomicReference<IJavaProject> p2Project=new AtomicReference<>(); |
| |
| ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P2", "/P1/lib.jar", "P3", "/P1/lib.jar"}) { |
| public void initialize(IPath containerPath, IJavaProject project) throws CoreException { |
| if (Thread.currentThread() == helperThread) { |
| if (project.getElementName().equals("P2")) { |
| p2Project.set(project); |
| s1.release(); |
| try { |
| s2.acquire(10000); |
| } catch (TimeOutException e) { |
| // ignore |
| } |
| } else if (project.getElementName().equals("P3")) { |
| s3.release(); |
| try { |
| s4.acquire(10000); |
| } catch (TimeOutException e) { |
| // ignore |
| } |
| if (JavaModelManager.getJavaModelManager().containerBeingInitializedGet(p2Project.get(), |
| containerPath) != null) { |
| p2Counter.incrementAndGet(); |
| } |
| helperContainer.set(JavaModelManager.getJavaModelManager().getClasspathContainer(containerPath, p2Project.get())); |
| } |
| } else if (Thread.currentThread() == mainThread) { |
| if (project.getElementName().equals("P2")) { |
| // this point is reached when helperThread is also still waiting in P2 |
| s2.release(); |
| } else if (project.getElementName().equals("P3")) { |
| try { |
| s3.acquire(10000); |
| } catch (TimeOutException e) { |
| // ignore |
| } |
| s4.release(); |
| if (JavaModelManager.getJavaModelManager().containerBeingInitializedGet(p2Project.get(), |
| containerPath) != null) { |
| p2Counter.incrementAndGet(); |
| } |
| mainContainer.set(JavaModelManager.getJavaModelManager().getClasspathContainer(containerPath, p2Project.get())); |
| } |
| } |
| super.initialize(containerPath, project); |
| } |
| }); |
| helperThread.start(); |
| // wait till helperThread has reached initializer |
| try { |
| s1.acquire(10000); |
| } catch (TimeOutException e1) { |
| // ignore |
| } |
| JavaModelManager.getJavaModelManager().getClasspathContainer(Path.EMPTY, null); |
| try { |
| helperThread.join(); |
| } catch (InterruptedException e) { |
| e.printStackTrace(); |
| } |
| assertEquals("more than one result for P2 used.", 1, p2Counter.get()); |
| assertEquals("main and helper threads did not see the same container.", helperContainer.get(), mainContainer.get()); |
| } finally { |
| deleteProject("P1"); |
| deleteProject("P2"); |
| deleteProject("P3"); |
| } |
| } |
| |
| } |