Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian W. Damus2013-04-05 08:30:57 -0400
committerChristian W. Damus2013-04-05 08:31:25 -0400
commitb0a698bc30310fd540a01a1b9d76179890de5315 (patch)
tree0c6ea4a0a08052f18ec2649ddfc57479a0329cef
parentea01b6f2e7d00f946dec8eca9356ee4036c79daa (diff)
downloadcdo-b0a698bc30310fd540a01a1b9d76179890de5315.tar.gz
cdo-b0a698bc30310fd540a01a1b9d76179890de5315.tar.xz
cdo-b0a698bc30310fd540a01a1b9d76179890de5315.zip
[404318] DynamicCDOObjects throw NPEs when their Ecore models are unloadeddrops/I20130405-0847
https://bugs.eclipse.org/bugs/show_bug.cgi?id=404318
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOClassInfoImpl.java5
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/model/Bug404318.ecore9
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/model/Bug404318.xmi9
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_404318_Test.java99
4 files changed, 121 insertions, 1 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOClassInfoImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOClassInfoImpl.java
index 9db71b24d1..13300a754b 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOClassInfoImpl.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOClassInfoImpl.java
@@ -8,6 +8,7 @@
* Contributors:
* Eike Stepper - initial API and implementation
* Christian W. Damus (CEA) - support partially persistent features
+ * Christian W. Damus (CEA) - bug 404318: NPEs in dynamic objects whose EClasses are unloaded
*/
package org.eclipse.emf.cdo.internal.common.model;
@@ -112,7 +113,9 @@ public final class CDOClassInfoImpl implements InternalCDOClassInfo, Adapter.Int
public void unsetTarget(Notifier oldTarget)
{
- eClass = null;
+ // pass. In particular, don't forget the EClass because it may still
+ // be required by dependents such as DynamicCDOObjectImpls that retain
+ // me as a descriptor of their class
}
public EClass getEClass()
diff --git a/plugins/org.eclipse.emf.cdo.tests/model/Bug404318.ecore b/plugins/org.eclipse.emf.cdo.tests/model/Bug404318.ecore
new file mode 100644
index 0000000000..b24fac7171
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.tests/model/Bug404318.ecore
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="bug404318" nsURI="http://www.eclipse.org/schema/cdo/test/bug404318"
+ nsPrefix="bug">
+ <eClassifiers xsi:type="ecore:EClass" name="A"/>
+ <eClassifiers xsi:type="ecore:EClass" name="B">
+ <eStructuralFeatures xsi:type="ecore:EReference" name="a" eType="#//A"/>
+ </eClassifiers>
+</ecore:EPackage>
diff --git a/plugins/org.eclipse.emf.cdo.tests/model/Bug404318.xmi b/plugins/org.eclipse.emf.cdo.tests/model/Bug404318.xmi
new file mode 100644
index 0000000000..5699ee3684
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.tests/model/Bug404318.xmi
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="ASCII"?>
+<xmi:XMI xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:bug="http://www.eclipse.org/schema/cdo/test/bug404318"
+ xsi:schemaLocation="http://www.eclipse.org/schema/cdo/test/bug404318 Bug404318.ecore">
+ <bug:A/>
+ <bug:B a="/0"/>
+</xmi:XMI>
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_404318_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_404318_Test.java
new file mode 100644
index 0000000000..9225f7bb6a
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_404318_Test.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2004 - 2013 Eike Stepper (Berlin, Germany) 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:
+ * Christian W. Damus (CEA) - initial API and implementation
+ */
+package org.eclipse.emf.cdo.tests.bugzilla;
+
+import org.eclipse.emf.cdo.server.IRepository;
+import org.eclipse.emf.cdo.session.CDOSession;
+import org.eclipse.emf.cdo.tests.AbstractCDOTest;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.xmi.impl.EcoreResourceFactoryImpl;
+import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
+
+import java.net.URL;
+import java.util.Map;
+
+/**
+ * Bug 404318: Tests that we don't get certain NPEs when processing dynamic objects whose
+ * EClasses have been unloaded.
+ *
+ * @author Christian W. Damus (CEA)
+ */
+public class Bugzilla_404318_Test extends AbstractCDOTest
+{
+ public void testUnloadedEClass() throws Exception
+ {
+ CDOSession session = openSession();
+
+ CDOTransaction transaction = session.openTransaction();
+
+ // get our dynamic package
+ EPackage epackage = getTestPackage(transaction.getResourceSet());
+
+ // and the instance model
+ Resource resource = getTestInstance(transaction.getResourceSet());
+
+ session.getPackageRegistry().putEPackage(epackage);
+
+ EObject anA = resource.getContents().get(0);
+ EObject aB = resource.getContents().get(1);
+
+ // sanity check
+ assertSame(anA, aB.eGet(aB.eClass().getEStructuralFeature("a")));
+
+ try
+ {
+ // unload the models. This would NPE without the fix
+ epackage.eResource().unload();
+ resource.unload();
+
+ // unloaded EClass still supports the unloaded instance
+ assertSame(anA, aB.eGet(aB.eClass().getEStructuralFeature("a")));
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ fail("Threw exception: " + e.getLocalizedMessage());
+ }
+ }
+
+ //
+ // test framework
+
+ @Override
+ public Map<String, String> getRepositoryProperties()
+ {
+ Map<String, String> result = super.getRepositoryProperties();
+ result.put(IRepository.Props.SUPPORTING_ECORE, Boolean.toString(true));
+ return result;
+ }
+
+ protected EPackage getTestPackage(ResourceSet rset) throws Exception
+ {
+ rset.getResourceFactoryRegistry().getExtensionToFactoryMap().put("ecore", new EcoreResourceFactoryImpl());
+ URL location = getClass().getClassLoader().getResource("Bug404318.ecore");
+ Resource result = rset.getResource(URI.createURI(location.toExternalForm(), true), true);
+ return (EPackage)result.getContents().get(0);
+ }
+
+ protected Resource getTestInstance(ResourceSet rset) throws Exception
+ {
+ rset.getResourceFactoryRegistry().getExtensionToFactoryMap().put("xmi", new XMIResourceFactoryImpl());
+ URL location = getClass().getClassLoader().getResource("Bug404318.xmi");
+ Resource result = rset.getResource(URI.createURI(location.toExternalForm(), true), true);
+ return result;
+ }
+}

Back to the top