R3_6Maintenance: Fix for 372687:org.eclipse.jdt.core.LRUCache.get(Object
key) returns an empty list from a class that has methods
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClassFileTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClassFileTests.java
index f2afc82..ce676c1 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClassFileTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClassFileTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 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
@@ -1543,5 +1543,46 @@
assertStringsEqual("Type parameter bounds signatures",
"TT;\n", typeParam.getBoundsSignatures());
}
-
+
+ /*
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=372687
+ * Ensures that if more than one thread try to open a class file at the same time, the children are correct.
+ */
+ public void testBug372687() throws CoreException {
+ String expected = "X.class\n" +
+ " class X\n" +
+ " X()\n" +
+ " void foo()";
+ class GetClassThread extends Thread {
+ public String childString;
+ public void run(){
+ IClassFile clazz = ClassFileTests.this.jarRoot.getPackageFragment("workingcopy").getClassFile("X.class");
+ try {
+ this.childString = expandAll(clazz);
+ } catch (CoreException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ for (int i = 0; i < 10; i++) {
+ GetClassThread th1 = new GetClassThread();
+ GetClassThread th2 = new GetClassThread();
+ GetClassThread th3 = new GetClassThread();
+ th1.start();
+ th2.start();
+ th3.start();
+ try {
+ th1.join();
+ th2.join();
+ th3.join();
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ assertEquals("Unexpected children", expected, th1.childString);
+ assertEquals("Unexpected children", expected, th2.childString);
+ assertEquals("Unexpected children", expected, th3.childString);
+ IClassFile clazz = ClassFileTests.this.jarRoot.getPackageFragment("workingcopy").getClassFile("X.class");
+ clazz.close();
+ }
+ }
}
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
index a2a1d5e..5905aa8 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
@@ -1,5 +1,5 @@
###############################################################################
-# Copyright (c) 2000, 2011 IBM Corporation and others.
+# Copyright (c) 2000, 2012 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
@@ -15,8 +15,8 @@
#Format: compiler.name = word1 word2 word3
compiler.name = Eclipse Compiler for Java(TM)
#Format: compiler.version = 0.XXX[, other words (don't forget the comma if adding other words)]
-compiler.version = 0.A80_R36x, 3.6.4
-compiler.copyright = Copyright IBM Corp 2000, 2011. All rights reserved.
+compiler.version = 0.A81_R36x, 3.6.4
+compiler.copyright = Copyright IBM Corp 2000, 2012. All rights reserved.
### progress
progress.compiling = Compiling
diff --git a/org.eclipse.jdt.core/buildnotes_jdt-core.html b/org.eclipse.jdt.core/buildnotes_jdt-core.html
index 73aa7be..b790af6 100644
--- a/org.eclipse.jdt.core/buildnotes_jdt-core.html
+++ b/org.eclipse.jdt.core/buildnotes_jdt-core.html
@@ -40,6 +40,21 @@
</td>
</tr>
</table>
+<a name="v_A81_R36x"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.6.4 - %date% - April 13, 2012
+<br>Project org.eclipse.jdt.core v_A81_R36x
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A81_R36x">cvs</a>).
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=372687">372687</a>
+org.eclipse.jdt.core.LRUCache.get(Object key) returns an empty list from a class that has methods
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=185601">185601</a>
+.apt_generated is not restored as a source folder
+
<a name="v_A80_R36x"></a>
<hr><h1>
Eclipse Platform Build Notes<br>
@@ -57,7 +72,7 @@
<hr><h1>
Eclipse Platform Build Notes<br>
Java development tools core</h1>
-Eclipse SDK 3.6.4 - October 21, 2011
+Eclipse SDK 3.6.4
<br>Project org.eclipse.jdt.core v_A79_R36x
(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A79_R36x">cvs</a>).
<h2>What's new in this drop</h2>
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BecomeWorkingCopyOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BecomeWorkingCopyOperation.java
index a132158..7f5be9a 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BecomeWorkingCopyOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BecomeWorkingCopyOperation.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 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
@@ -35,7 +35,7 @@
// open the working copy now to ensure contents are that of the current state of this element
CompilationUnit workingCopy = getWorkingCopy();
JavaModelManager.getJavaModelManager().getPerWorkingCopyInfo(workingCopy, true/*create if needed*/, true/*record usage*/, this.problemRequestor);
- workingCopy.openWhenClosed(workingCopy.createElementInfo(), this.progressMonitor);
+ workingCopy.openWhenClosed(workingCopy.createElementInfo(), true, this.progressMonitor);
if (!workingCopy.isPrimary()) {
// report added java delta for a non-primary working copy
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryType.java
index ef32aad..d89361a 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryType.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryType.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 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
@@ -283,7 +283,7 @@
JavaModelManager manager = JavaModelManager.getJavaModelManager();
Object info = manager.getInfo(this);
if (info != null && info != JavaModelCache.NON_EXISTING_JAR_TYPE_INFO) return info;
- return openWhenClosed(createElementInfo(), monitor);
+ return openWhenClosed(createElementInfo(), false, monitor);
}
/*
* @see IJavaElement
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java
index 2d62037..2231ac1 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 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
@@ -1076,12 +1076,12 @@
info.resolveBindings = resolveBindings;
info.reconcileFlags = reconcileFlags;
info.problems = problems;
- openWhenClosed(info, monitor);
+ openWhenClosed(info, true, monitor);
org.eclipse.jdt.core.dom.CompilationUnit result = info.ast;
info.ast = null;
return result;
} else {
- openWhenClosed(createElementInfo(), monitor);
+ openWhenClosed(createElementInfo(), true, monitor);
return null;
}
} finally {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java
index dd1afbf..13669d2 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 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
@@ -249,7 +249,7 @@
JavaModelManager manager = JavaModelManager.getJavaModelManager();
Object info = manager.getInfo(this);
if (info != null) return info;
- return openWhenClosed(createElementInfo(), monitor);
+ return openWhenClosed(createElementInfo(), false, monitor);
}
/**
* @see IAdaptable
@@ -507,7 +507,7 @@
* Opens an <code>Openable</code> that is known to be closed (no check for <code>isOpen()</code>).
* Returns the created element info.
*/
- protected Object openWhenClosed(Object info, IProgressMonitor monitor) throws JavaModelException {
+ protected Object openWhenClosed(Object info, boolean forceAdd, IProgressMonitor monitor) throws JavaModelException {
JavaModelManager manager = JavaModelManager.getJavaModelManager();
boolean hadTemporaryCache = manager.hasTemporaryCache();
try {
@@ -526,7 +526,7 @@
throw newNotPresentException();
}
if (!hadTemporaryCache) {
- manager.putInfos(this, newElements);
+ manager.putInfos(this, info, forceAdd, newElements);
}
} finally {
if (!hadTemporaryCache) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
index b5a0313..8744967 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 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
@@ -3446,13 +3446,26 @@
public void prepareToSave(ISaveContext context) /*throws CoreException*/ {
// nothing to do
}
+
/*
* Puts the infos in the given map (keys are IJavaElements and values are JavaElementInfos)
- * in the Java model cache in an atomic way.
+ * in the Java model cache in an atomic way if the info is not already present in the cache.
+ * If the info is already present in the cache, it depends upon the forceAdd parameter.
+ * If forceAdd is false it just returns the existing info and if true, this element and it's children are closed and then
+ * this particular info is added to the cache.
*/
- protected synchronized void putInfos(IJavaElement openedElement, Map newElements) {
+ protected synchronized Object putInfos(IJavaElement openedElement, Object newInfo, boolean forceAdd, Map newElements) {
// remove existing children as the are replaced with the new children contained in newElements
Object existingInfo = this.cache.peekAtInfo(openedElement);
+ if (existingInfo != null && !forceAdd) {
+ // If forceAdd is false, then it could mean that the particular element
+ // wasn't in cache at that point of time, but would have got added through
+ // another thread. In that case, removing the children could remove it's own
+ // children. So, we should not remove the children but return the already existing
+ // info.
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=372687
+ return existingInfo;
+ }
if (openedElement instanceof IParent) {
closeChildren(existingInfo);
}
@@ -3482,6 +3495,7 @@
Map.Entry entry = (Map.Entry) iterator.next();
this.cache.putInfo((IJavaElement) entry.getKey(), entry.getValue());
}
+ return newInfo;
}
private void closeChildren(Object info) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
index 9fb59c6..b9f4ce4 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2012 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
@@ -485,7 +485,7 @@
JavaModelManager manager = JavaModelManager.getJavaModelManager();
PackageFragmentRootInfo info = (PackageFragmentRootInfo) manager.peekAtInfo(this);
if (info == null) {
- info = (PackageFragmentRootInfo) openWhenClosed(createElementInfo(), null);
+ info = (PackageFragmentRootInfo) openWhenClosed(createElementInfo(), false, null);
}
return info.getRootKind();
}