Home » Modeling » EMF » The Wrong Exception Thrown From A Bad Reference
The Wrong Exception Thrown From A Bad Reference [message #380730] |
Tue, 02 December 2003 10:27  |
Eclipse User |
|
|
|
Hi All,
I'm currently testing how EMF behaves with corrupted models. More
specifically, bad references. I have been taking models and purposefully
corrupting references, changing certain attributes of various xml tags and
even corrupting the xml itself to see how EMF responds. In most cases, the
exceptions are understandable and it is easy to interpret them to discover
what is wrong with the model.
In the process of testing how EMF handles the case where one end of a
bidirectional reference is corrupted, I stumbled across a case where the
completely wrong exception is thrown.
I can demonstrate the problem by using a slight variation of the library
model. I will describe the changes here but I can easily email a copy of
my Rose model, library plugins and example models to anyone who is
interested.
I change the library model so that there is an additional composition
relationship on the Library class and itself called "collection" with a
multiplicity of "*" Also, the association between Writer and Book is
changed to have a multiplicity of "1..*" on the author end and "*" on the
books end.
Having made these changes, I create the following three variations of a
model:
<?xml version="1.0" encoding="ASCII"?>
<library:Library xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"
xmlns:library="http:///library.ecore" name="theLibrary">
<collection name="SpecialtyBooks">
<books title="TheTwoTowers" author="//@collection.1/@writers.0"/>
</collection>
<collection name="FamousWriters">
<writers name="Tolkien" books="//@collection.0/@books.0"/>
</collection>
</library:Library>
* This is the uncorrupted model *
<?xml version="1.0" encoding="ASCII"?>
<library:Library xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"
xmlns:library="http:///library.ecore" name="theLibrary">
<collection name="SpecialtyBooks">
<books title="TheTwoTowers" author="//@collection.1/@writers.1"/>
</collection>
<collection name="FamousWriters">
<writers name="Tolkien" books="//@collection.0/@books.0"/>
</collection>
</library:Library>
* This model has the book's author reference corrupted and the following
(correct) exception is thrown by the eclipse editor*
org.eclipse.emf.ecore.xmi.UnresolvedReferenceException: Unresolved
reference '//@collection.1/@writers.1'.
(platform:/resource/test/CorrectException.library, 4, -1)
<?xml version="1.0" encoding="ASCII"?>
<library:Library xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"
xmlns:library="http:///library.ecore" name="theLibrary">
<collection name="SpecialtyBooks">
<books title="TheTwoTowers" author="//@collection.1/@writers.0"/>
</collection>
<collection name="FamousWriters">
<writers name="Tolkien" books="//@collection.1/@books.0"/>
</collection>
</library:Library>
* This model has the author's books reference corrupted and the following
(incorrect) exception is thrown by the eclipse editor*
java.lang.IndexOutOfBoundsException: targetIndex=0, size=0
at org.eclipse.emf.common.util.BasicEList.move(BasicEList.java: 915)
at
org.eclipse.emf.common.notify.impl.NotifyingListImpl.move(No tifyingListImpl.java:811)
at org.eclipse.emf.common.util.BasicEList.move(BasicEList.java: 899)
at
org.eclipse.emf.ecore.xmi.impl.XMLHelperImpl.setValue(XMLHel perImpl.java:479)
at
org.eclipse.emf.ecore.xmi.impl.XMLHandler.setFeatureValue(XM LHandler.java:1052)
at
org.eclipse.emf.ecore.xmi.impl.XMLHandler.endDocument(XMLHan dler.java:455)
at
org.eclipse.emf.ecore.xmi.impl.SAXWrapper.endDocument(SAXWra pper.java:55)
at org.apache.crimson.parser.Parser2.parseInternal(Unknown Source)
at org.apache.crimson.parser.Parser2.parse(Unknown Source)
at org.apache.crimson.parser.XMLReaderImpl.parse(Unknown Source)
at javax.xml.parsers.SAXParser.parse(Unknown Source)
at org.eclipse.emf.ecore.xmi.impl.XMLLoadImpl.load(XMLLoadImpl. java:76)
at
org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.doLoad(XMLRes ourceImpl.java:135)
at
org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(Resour ceImpl.java:881)
at
org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(Resour ceImpl.java:755)
at
org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.demandLo ad(ResourceSetImpl.java:220)
at
org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.getResou rce(ResourceSetImpl.java:286)
at
org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain.load Resource(AdapterFactoryEditingDomain.java:284)
at library.presentation.LibraryEditor.createPages(LibraryEditor .java:703)
at
org.eclipse.ui.part.MultiPageEditorPart.createPartControl(Mu ltiPageEditorPart.java:166)
at org.eclipse.ui.internal.PartPane$4.run(PartPane.java:141)
at
org.eclipse.core.internal.runtime.InternalPlatform.run(Inter nalPlatform.java:1006)
at org.eclipse.core.runtime.Platform.run(Platform.java:413)
at org.eclipse.ui.internal.PartPane.createChildControl(PartPane .java:137)
at org.eclipse.ui.internal.PartPane.createControl(PartPane.java :186)
at
org.eclipse.ui.internal.EditorWorkbook.createPage(EditorWork book.java:387)
at org.eclipse.ui.internal.EditorWorkbook.add(EditorWorkbook.ja va:123)
at org.eclipse.ui.internal.EditorArea.addEditor(EditorArea.java :55)
at
org.eclipse.ui.internal.EditorPresentation.openEditor(Editor Presentation.java:351)
at org.eclipse.ui.internal.EditorManager$2.run(EditorManager.ja va:585)
at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator .java:69)
at
org.eclipse.ui.internal.EditorManager.createEditorTab(Editor Manager.java:574)
at
org.eclipse.ui.internal.EditorManager.openInternalEditor(Edi torManager.java:668)
at
org.eclipse.ui.internal.EditorManager.openEditorFromDescript or(EditorManager.java:459)
at
org.eclipse.ui.internal.EditorManager.openEditorFromInput(Ed itorManager.java:333)
at
org.eclipse.ui.internal.EditorManager.openEditor(EditorManag er.java:424)
at
org.eclipse.ui.internal.WorkbenchPage.busyOpenEditor(Workben chPage.java:2056)
at org.eclipse.ui.internal.WorkbenchPage.access$6(WorkbenchPage .java:2004)
at org.eclipse.ui.internal.WorkbenchPage$9.run(WorkbenchPage.ja va:1991)
at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator .java:69)
at
org.eclipse.ui.internal.WorkbenchPage.openEditor(WorkbenchPa ge.java:1986)
at
org.eclipse.ui.internal.WorkbenchPage.openEditor(WorkbenchPa ge.java:1887)
at org.eclipse.ui.actions.OpenFileAction.openFile(OpenFileActio n.java:96)
at
org.eclipse.ui.actions.OpenSystemEditorAction.run(OpenSystem EditorAction.java:96)
at
org.eclipse.ui.views.navigator.OpenActionGroup.runDefaultAct ion(OpenActionGroup.java:111)
at
org.eclipse.ui.views.navigator.MainActionGroup.runDefaultAct ion(MainActionGroup.java:250)
at
org.eclipse.ui.views.navigator.ResourceNavigator.handleOpen( ResourceNavigator.java:613)
at
org.eclipse.ui.views.navigator.ResourceNavigator$6.open(Reso urceNavigator.java:384)
at
org.eclipse.jface.viewers.StructuredViewer$2.run(StructuredV iewer.java:397)
at
org.eclipse.core.internal.runtime.InternalPlatform.run(Inter nalPlatform.java:1006)
at org.eclipse.core.runtime.Platform.run(Platform.java:413)
at
org.eclipse.jface.viewers.StructuredViewer.fireOpen(Structur edViewer.java:395)
at
org.eclipse.jface.viewers.StructuredViewer.handleOpen(Struct uredViewer.java:605)
at
org.eclipse.jface.viewers.StructuredViewer$6.handleOpen(Stru cturedViewer.java:694)
at
org.eclipse.jface.util.OpenStrategy.fireOpenEvent(OpenStrate gy.java:209)
at org.eclipse.jface.util.OpenStrategy.access$2(OpenStrategy.ja va:204)
at
org.eclipse.jface.util.OpenStrategy$1.handleEvent(OpenStrate gy.java:233)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java :81)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:840)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.ja va:2022)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :1729)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:1402)
at org.eclipse.ui.internal.Workbench.run(Workbench.java:1385)
at
org.eclipse.core.internal.boot.InternalBootLoader.run(Intern alBootLoader.java:858)
at org.eclipse.core.boot.BootLoader.run(BootLoader.java:461)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.core.launcher.Main.basicRun(Main.java:291)
at org.eclipse.core.launcher.Main.run(Main.java:747)
at org.eclipse.core.launcher.Main.main(Main.java:583)
I have included the stack trace for debugging purposes. The best I can
figure out is that EMF is assuming that an object is already contained in
this EList because of a fundamental assumption that at least one end of a
bidirectional reference will have been resolved during the first pass. If
the corrupted end of the reference appears after the uncorrupted end then
neither end of the reference is resolved in the first pass and the list is
empty when it should have already contained the object. EMF attempts to
move the object that isn't already in the list (gets a -1 for the position
of the object in the list) and the EList class throws an IndexOutOfBounds
exception.
Does anyone have a suggestion for what should be the correct behaviour in
this case? As far as I'm concerned, the correct exception that should be
thrown is UnresolvedReferenceException as in the first case.
Thanks,
Chris McGee
IBM Ottawa
|
|
|
Re: The Wrong Exception Thrown From A Bad Reference [message #380734 is a reply to message #380730] |
Tue, 02 December 2003 12:28   |
Eclipse User |
|
|
|
--------------C92C4A7BB4E987AFD3C51007
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Chris,
I think that XMLHandler.setValueValue should be creating an IllegalValueException because it's written like
this:
protected void setFeatureValue(EObject object, EStructuralFeature feature, Object value, int
position)
{
try
{
helper.setValue(object, feature, value, position);
}
catch (RuntimeException e)
{
error
(new IllegalValueException
(object,
feature,
value,
e,
getLocation(),
getLineNumber(),
getColumnNumber()));
}
}
The exception implementation does stack trace printing like this:
public void printStackTrace()
{
if (exception != null)
{
exception.printStackTrace();
}
else
{
super.printStackTrace();
}
}
Which is different from WrappedException, which prints like this:
public void printStackTrace()
{
System.err.println("Wrapped exception");
wrappedException.printStackTrace();
System.err.println("Wrapped by");
super.printStackTrace();
}
The former will not show the information about where the exception was wrapped and will tend to mislead you
about the type of exception actually being thrown.
In the code that does the move, we could change it like this to detect the problem (with no real loss of
efficiency):
else
{
int index = list.indexOf(value);
if (index == -1)
{
... what do do?
}
else
{
list.move(position, index);
}
}
But at this point we don't have all the location information to give a good error message. So we could throw
some other useful exception and allow it to be wrapped later to provide the location information. Is this
what you are looking for?
Chris McGee wrote:
> Hi All,
>
> I'm currently testing how EMF behaves with corrupted models. More
> specifically, bad references. I have been taking models and purposefully
> corrupting references, changing certain attributes of various xml tags and
> even corrupting the xml itself to see how EMF responds. In most cases, the
> exceptions are understandable and it is easy to interpret them to discover
> what is wrong with the model.
>
> In the process of testing how EMF handles the case where one end of a
> bidirectional reference is corrupted, I stumbled across a case where the
> completely wrong exception is thrown.
>
> I can demonstrate the problem by using a slight variation of the library
> model. I will describe the changes here but I can easily email a copy of
> my Rose model, library plugins and example models to anyone who is
> interested.
>
> I change the library model so that there is an additional composition
> relationship on the Library class and itself called "collection" with a
> multiplicity of "*" Also, the association between Writer and Book is
> changed to have a multiplicity of "1..*" on the author end and "*" on the
> books end.
>
> Having made these changes, I create the following three variations of a
> model:
>
> <?xml version="1.0" encoding="ASCII"?>
> <library:Library xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"
> xmlns:library="http:///library.ecore" name="theLibrary">
> <collection name="SpecialtyBooks">
> <books title="TheTwoTowers" author="//@collection.1/@writers.0"/>
> </collection>
> <collection name="FamousWriters">
> <writers name="Tolkien" books="//@collection.0/@books.0"/>
> </collection>
> </library:Library>
>
> * This is the uncorrupted model *
>
> <?xml version="1.0" encoding="ASCII"?>
> <library:Library xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"
> xmlns:library="http:///library.ecore" name="theLibrary">
> <collection name="SpecialtyBooks">
> <books title="TheTwoTowers" author="//@collection.1/@writers.1"/>
> </collection>
> <collection name="FamousWriters">
> <writers name="Tolkien" books="//@collection.0/@books.0"/>
> </collection>
> </library:Library>
>
> * This model has the book's author reference corrupted and the following
> (correct) exception is thrown by the eclipse editor*
> org.eclipse.emf.ecore.xmi.UnresolvedReferenceException: Unresolved
> reference '//@collection.1/@writers.1'.
> (platform:/resource/test/CorrectException.library, 4, -1)
>
> <?xml version="1.0" encoding="ASCII"?>
> <library:Library xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"
> xmlns:library="http:///library.ecore" name="theLibrary">
> <collection name="SpecialtyBooks">
> <books title="TheTwoTowers" author="//@collection.1/@writers.0"/>
> </collection>
> <collection name="FamousWriters">
> <writers name="Tolkien" books="//@collection.1/@books.0"/>
> </collection>
> </library:Library>
>
> * This model has the author's books reference corrupted and the following
> (incorrect) exception is thrown by the eclipse editor*
>
> java.lang.IndexOutOfBoundsException: targetIndex=0, size=0
> at org.eclipse.emf.common.util.BasicEList.move(BasicEList.java: 915)
> at
> org.eclipse.emf.common.notify.impl.NotifyingListImpl.move(No tifyingListImpl.java:811)
> at org.eclipse.emf.common.util.BasicEList.move(BasicEList.java: 899)
> at
> org.eclipse.emf.ecore.xmi.impl.XMLHelperImpl.setValue(XMLHel perImpl.java:479)
> at
> org.eclipse.emf.ecore.xmi.impl.XMLHandler.setFeatureValue(XM LHandler.java:1052)
> at
> org.eclipse.emf.ecore.xmi.impl.XMLHandler.endDocument(XMLHan dler.java:455)
> at
> org.eclipse.emf.ecore.xmi.impl.SAXWrapper.endDocument(SAXWra pper.java:55)
> at org.apache.crimson.parser.Parser2.parseInternal(Unknown Source)
> at org.apache.crimson.parser.Parser2.parse(Unknown Source)
> at org.apache.crimson.parser.XMLReaderImpl.parse(Unknown Source)
> at javax.xml.parsers.SAXParser.parse(Unknown Source)
> at org.eclipse.emf.ecore.xmi.impl.XMLLoadImpl.load(XMLLoadImpl. java:76)
> at
> org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.doLoad(XMLRes ourceImpl.java:135)
> at
> org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(Resour ceImpl.java:881)
> at
> org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(Resour ceImpl.java:755)
> at
> org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.demandLo ad(ResourceSetImpl.java:220)
> at
> org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.getResou rce(ResourceSetImpl.java:286)
> at
> org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain.load Resource(AdapterFactoryEditingDomain.java:284)
> at library.presentation.LibraryEditor.createPages(LibraryEditor .java:703)
> at
> org.eclipse.ui.part.MultiPageEditorPart.createPartControl(Mu ltiPageEditorPart.java:166)
> at org.eclipse.ui.internal.PartPane$4.run(PartPane.java:141)
> at
> org.eclipse.core.internal.runtime.InternalPlatform.run(Inter nalPlatform.java:1006)
> at org.eclipse.core.runtime.Platform.run(Platform.java:413)
> at org.eclipse.ui.internal.PartPane.createChildControl(PartPane .java:137)
> at org.eclipse.ui.internal.PartPane.createControl(PartPane.java :186)
> at
> org.eclipse.ui.internal.EditorWorkbook.createPage(EditorWork book.java:387)
> at org.eclipse.ui.internal.EditorWorkbook.add(EditorWorkbook.ja va:123)
> at org.eclipse.ui.internal.EditorArea.addEditor(EditorArea.java :55)
> at
> org.eclipse.ui.internal.EditorPresentation.openEditor(Editor Presentation.java:351)
> at org.eclipse.ui.internal.EditorManager$2.run(EditorManager.ja va:585)
> at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator .java:69)
> at
> org.eclipse.ui.internal.EditorManager.createEditorTab(Editor Manager.java:574)
> at
> org.eclipse.ui.internal.EditorManager.openInternalEditor(Edi torManager.java:668)
> at
> org.eclipse.ui.internal.EditorManager.openEditorFromDescript or(EditorManager.java:459)
> at
> org.eclipse.ui.internal.EditorManager.openEditorFromInput(Ed itorManager.java:333)
> at
> org.eclipse.ui.internal.EditorManager.openEditor(EditorManag er.java:424)
> at
> org.eclipse.ui.internal.WorkbenchPage.busyOpenEditor(Workben chPage.java:2056)
> at org.eclipse.ui.internal.WorkbenchPage.access$6(WorkbenchPage .java:2004)
> at org.eclipse.ui.internal.WorkbenchPage$9.run(WorkbenchPage.ja va:1991)
> at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator .java:69)
> at
> org.eclipse.ui.internal.WorkbenchPage.openEditor(WorkbenchPa ge.java:1986)
> at
> org.eclipse.ui.internal.WorkbenchPage.openEditor(WorkbenchPa ge.java:1887)
> at org.eclipse.ui.actions.OpenFileAction.openFile(OpenFileActio n.java:96)
> at
> org.eclipse.ui.actions.OpenSystemEditorAction.run(OpenSystem EditorAction.java:96)
> at
> org.eclipse.ui.views.navigator.OpenActionGroup.runDefaultAct ion(OpenActionGroup.java:111)
> at
> org.eclipse.ui.views.navigator.MainActionGroup.runDefaultAct ion(MainActionGroup.java:250)
> at
> org.eclipse.ui.views.navigator.ResourceNavigator.handleOpen( ResourceNavigator.java:613)
> at
> org.eclipse.ui.views.navigator.ResourceNavigator$6.open(Reso urceNavigator.java:384)
> at
> org.eclipse.jface.viewers.StructuredViewer$2.run(StructuredV iewer.java:397)
> at
> org.eclipse.core.internal.runtime.InternalPlatform.run(Inter nalPlatform.java:1006)
> at org.eclipse.core.runtime.Platform.run(Platform.java:413)
> at
> org.eclipse.jface.viewers.StructuredViewer.fireOpen(Structur edViewer.java:395)
> at
> org.eclipse.jface.viewers.StructuredViewer.handleOpen(Struct uredViewer.java:605)
> at
> org.eclipse.jface.viewers.StructuredViewer$6.handleOpen(Stru cturedViewer.java:694)
> at
> org.eclipse.jface.util.OpenStrategy.fireOpenEvent(OpenStrate gy.java:209)
> at org.eclipse.jface.util.OpenStrategy.access$2(OpenStrategy.ja va:204)
> at
> org.eclipse.jface.util.OpenStrategy$1.handleEvent(OpenStrate gy.java:233)
> at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java :81)
> at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:840)
> at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.ja va:2022)
> at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :1729)
> at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:1402)
> at org.eclipse.ui.internal.Workbench.run(Workbench.java:1385)
> at
> org.eclipse.core.internal.boot.InternalBootLoader.run(Intern alBootLoader.java:858)
> at org.eclipse.core.boot.BootLoader.run(BootLoader.java:461)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
> at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
> at java.lang.reflect.Method.invoke(Unknown Source)
> at org.eclipse.core.launcher.Main.basicRun(Main.java:291)
> at org.eclipse.core.launcher.Main.run(Main.java:747)
> at org.eclipse.core.launcher.Main.main(Main.java:583)
>
> I have included the stack trace for debugging purposes. The best I can
> figure out is that EMF is assuming that an object is already contained in
> this EList because of a fundamental assumption that at least one end of a
> bidirectional reference will have been resolved during the first pass. If
> the corrupted end of the reference appears after the uncorrupted end then
> neither end of the reference is resolved in the first pass and the list is
> empty when it should have already contained the object. EMF attempts to
> move the object that isn't already in the list (gets a -1 for the position
> of the object in the list) and the EList class throws an IndexOutOfBounds
> exception.
>
> Does anyone have a suggestion for what should be the correct behaviour in
> this case? As far as I'm concerned, the correct exception that should be
> thrown is UnresolvedReferenceException as in the first case.
>
> Thanks,
>
> Chris McGee
> IBM Ottawa
--------------C92C4A7BB4E987AFD3C51007
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
Chris,
<p>I think that XMLHandler.setValueValue should be creating an IllegalValueException
because it's written like this:
<blockquote><tt> protected void setFeatureValue(EObject object, EStructuralFeature
feature, Object value, int position)</tt>
<br><tt> {</tt>
<br><tt> try</tt>
<br><tt> {</tt>
<br><tt> helper.setValue(object, feature,
value, position);</tt>
<br><tt> }</tt>
<br><tt> catch (RuntimeException e)</tt>
<br><tt> {</tt>
<br><tt> error</tt>
<br><tt> (new IllegalValueException</tt>
<br><tt> (object,</tt>
<br><tt>
feature,</tt>
<br><tt>
value,</tt>
<br><tt>
e,</tt>
<br><tt>
getLocation(),</tt>
<br><tt>
getLineNumber(),</tt>
<br><tt>
getColumnNumber()));</tt>
<br><tt> }</tt>
<br><tt> }</tt></blockquote>
The exception implementation does stack trace printing like this:
<blockquote><tt> public void printStackTrace()</tt>
<br><tt> {</tt>
<br><tt> if (exception != null)</tt>
<br><tt> {</tt>
<br><tt> exception.printStackTrace();</tt>
<br><tt> }</tt>
<br><tt> else</tt>
<br><tt> {</tt>
<br><tt> super.printStackTrace();</tt>
<br><tt> }</tt>
<br><tt> }</tt></blockquote>
Which is different from WrappedException, which prints like this:
<blockquote><tt> public void printStackTrace()</tt>
<br><tt> {</tt>
<br><tt> System.err.println("Wrapped exception");</tt>
<br><tt> wrappedException.printStackTrace();</tt>
<br><tt> System.err.println("Wrapped by");</tt>
<br><tt> super.printStackTrace();</tt>
<br><tt> }</tt></blockquote>
The former will not show the information about where the exception was
wrapped and will tend to mislead you about the type of exception actually
being thrown.
<p>In the code that does the move, we could change it like this to detect
the problem (with no real loss of efficiency):
<p> else
<br> {
<br> int index =
list.indexOf(value);
<br> if (index ==
-1)
<br> {
<br> <font color="#3333FF">
.... what do do?</font>
<br> }
<br> else
<br> {
<br>
list.move(position, index);
<br> }
<br> }
<p>But at this point we don't have all the location information to give
a good error message. So we could throw some other useful exception
and allow it to be wrapped later to provide the location information.
Is this what you are looking for?
<br>
<p>Chris McGee wrote:
<blockquote TYPE=CITE>Hi All,
<p>I'm currently testing how EMF behaves with corrupted models. More
<br>specifically, bad references. I have been taking models and purposefully
<br>corrupting references, changing certain attributes of various xml tags
and
<br>even corrupting the xml itself to see how EMF responds. In most cases,
the
<br>exceptions are understandable and it is easy to interpret them to discover
<br>what is wrong with the model.
<p>In the process of testing how EMF handles the case where one end of
a
<br>bidirectional reference is corrupted, I stumbled across a case where
the
<br>completely wrong exception is thrown.
<p>I can demonstrate the problem by using a slight variation of the library
<br>model. I will describe the changes here but I can easily email a copy
of
<br>my Rose model, library plugins and example models to anyone who is
<br>interested.
<p>I change the library model so that there is an additional composition
<br>relationship on the Library class and itself called "collection" with
a
<br>multiplicity of "*" Also, the association between Writer and Book is
<br>changed to have a multiplicity of "1..*" on the author end and "*"
on the
<br>books end.
<p>Having made these changes, I create the following three variations of
a
<br>model:
<p><?xml version="1.0" encoding="ASCII"?>
<br><library:Library xmi:version="2.0" xmlns:xmi="<a href="http://www.omg.org/XMI">http://www.omg.org/XMI</a>"
<br>xmlns:library="<a href="http:///library.ecore">http:///library.ecore</a>"
name="theLibrary">
<br> <collection name="SpecialtyBooks">
<br> <books title="TheTwoTowers" author="//@collection.1/@writers.0"/>
<br> </collection>
<br> <collection name="FamousWriters">
<br> <writers name="Tolkien" books="//@collection.0/@books.0"/>
<br> </collection>
<br></library:Library>
<p>* This is the uncorrupted model *
<p><?xml version="1.0" encoding="ASCII"?>
<br><library:Library xmi:version="2.0" xmlns:xmi="<a href="http://www.omg.org/XMI">http://www.omg.org/XMI</a>"
<br>xmlns:library="<a href="http:///library.ecore">http:///library.ecore</a>"
name="theLibrary">
<br> <collection name="SpecialtyBooks">
<br> <books title="TheTwoTowers" author="//@collection.1/@writers.1"/>
<br> </collection>
<br> <collection name="FamousWriters">
<br> <writers name="Tolkien" books="//@collection.0/@books.0"/>
<br> </collection>
<br></library:Library>
<p>* This model has the book's author reference corrupted and the following
<br>(correct) exception is thrown by the eclipse editor*
<br>org.eclipse.emf.ecore.xmi.UnresolvedReferenceException: Unresolved
<br>reference '//@collection.1/@writers.1'.
<br>(platform:/resource/test/CorrectException.library, 4, -1)
<p><?xml version="1.0" encoding="ASCII"?>
<br><library:Library xmi:version="2.0" xmlns:xmi="<a href="http://www.omg.org/XMI">http://www.omg.org/XMI</a>"
<br>xmlns:library="<a href="http:///library.ecore">http:///library.ecore</a>"
name="theLibrary">
<br> <collection name="SpecialtyBooks">
<br> <books title="TheTwoTowers" author="//@collection.1/@writers.0"/>
<br> </collection>
<br> <collection name="FamousWriters">
<br> <writers name="Tolkien" books="//@collection.1/@books.0"/>
<br> </collection>
<br></library:Library>
<p>* This model has the author's books reference corrupted and the following
<br>(incorrect) exception is thrown by the eclipse editor*
<p>java.lang.IndexOutOfBoundsException: targetIndex=0, size=0
<br> at org.eclipse.emf.common.util.BasicEList.move(BasicEList.java: 915)
<br> at
<br> org.eclipse.emf.common.notify.impl.NotifyingListImpl.move(No tifyingListImpl.java:811)
<br> at org.eclipse.emf.common.util.BasicEList.move(BasicEList.java: 899)
<br> at
<br> org.eclipse.emf.ecore.xmi.impl.XMLHelperImpl.setValue(XMLHel perImpl.java:479)
<br> at
<br> org.eclipse.emf.ecore.xmi.impl.XMLHandler.setFeatureValue(XM LHandler.java:1052)
<br> at
<br> org.eclipse.emf.ecore.xmi.impl.XMLHandler.endDocument(XMLHan dler.java:455)
<br> at
<br> org.eclipse.emf.ecore.xmi.impl.SAXWrapper.endDocument(SAXWra pper.java:55)
<br> at org.apache.crimson.parser.Parser2.parseInternal(Unknown
Source)
<br> at org.apache.crimson.parser.Parser2.parse(Unknown
Source)
<br> at org.apache.crimson.parser.XMLReaderImpl.parse(Unknown
Source)
<br> at javax.xml.parsers.SAXParser.parse(Unknown
Source)
<br> at org.eclipse.emf.ecore.xmi.impl.XMLLoadImpl.load(XMLLoadImpl. java:76)
<br> at
<br> org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.doLoad(XMLRes ourceImpl.java:135)
<br> at
<br> org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(Resour ceImpl.java:881)
<br> at
<br> org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(Resour ceImpl.java:755)
<br> at
<br> org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.demandLo ad(ResourceSetImpl.java:220)
<br> at
<br> org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.getResou rce(ResourceSetImpl.java:286)
<br> at
<br> org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain.load Resource(AdapterFactoryEditingDomain.java:284)
<br> at library.presentation.LibraryEditor.createPages(LibraryEditor .java:703)
<br> at
<br> org.eclipse.ui.part.MultiPageEditorPart.createPartControl(Mu ltiPageEditorPart.java:166)
<br> at org.eclipse.ui.internal.PartPane$4.run(PartPane.java:141)
<br> at
<br> org.eclipse.core.internal.runtime.InternalPlatform.run(Inter nalPlatform.java:1006)
<br> at org.eclipse.core.runtime.Platform.run(Platform.java:413)
<br> at org.eclipse.ui.internal.PartPane.createChildControl(PartPane .java:137)
<br> at org.eclipse.ui.internal.PartPane.createControl(PartPane.java :186)
<br> at
<br> org.eclipse.ui.internal.EditorWorkbook.createPage(EditorWork book.java:387)
<br> at org.eclipse.ui.internal.EditorWorkbook.add(EditorWorkbook.ja va:123)
<br> at org.eclipse.ui.internal.EditorArea.addEditor(EditorArea.java :55)
<br> at
<br> org.eclipse.ui.internal.EditorPresentation.openEditor(Editor Presentation.java:351)
<br> at org.eclipse.ui.internal.EditorManager$2.run(EditorManager.ja va:585)
<br> at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator .java:69)
<br> at
<br> org.eclipse.ui.internal.EditorManager.createEditorTab(Editor Manager.java:574)
<br> at
<br> org.eclipse.ui.internal.EditorManager.openInternalEditor(Edi torManager.java:668)
<br> at
<br> org.eclipse.ui.internal.EditorManager.openEditorFromDescript or(EditorManager.java:459)
<br> at
<br> org.eclipse.ui.internal.EditorManager.openEditorFromInput(Ed itorManager.java:333)
<br> at
<br> org.eclipse.ui.internal.EditorManager.openEditor(EditorManag er.java:424)
<br> at
<br> org.eclipse.ui.internal.WorkbenchPage.busyOpenEditor(Workben chPage.java:2056)
<br> at org.eclipse.ui.internal.WorkbenchPage.access$6(WorkbenchPage .java:2004)
<br> at org.eclipse.ui.internal.WorkbenchPage$9.run(WorkbenchPage.ja va:1991)
<br> at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator .java:69)
<br> at
<br> org.eclipse.ui.internal.WorkbenchPage.openEditor(WorkbenchPa ge.java:1986)
<br> at
<br> org.eclipse.ui.internal.WorkbenchPage.openEditor(WorkbenchPa ge.java:1887)
<br> at org.eclipse.ui.actions.OpenFileAction.openFile(OpenFileActio n.java:96)
<br> at
<br> org.eclipse.ui.actions.OpenSystemEditorAction.run(OpenSystem EditorAction.java:96)
<br> at
<br> org.eclipse.ui.views.navigator.OpenActionGroup.runDefaultAct ion(OpenActionGroup.java:111)
<br> at
<br> org.eclipse.ui.views.navigator.MainActionGroup.runDefaultAct ion(MainActionGroup.java:250)
<br> at
<br> org.eclipse.ui.views.navigator.ResourceNavigator.handleOpen( ResourceNavigator.java:613)
<br> at
<br> org.eclipse.ui.views.navigator.ResourceNavigator$6.open(Reso urceNavigator.java:384)
<br> at
<br> org.eclipse.jface.viewers.StructuredViewer$2.run(StructuredV iewer.java:397)
<br> at
<br> org.eclipse.core.internal.runtime.InternalPlatform.run(Inter nalPlatform.java:1006)
<br> at org.eclipse.core.runtime.Platform.run(Platform.java:413)
<br> at
<br> org.eclipse.jface.viewers.StructuredViewer.fireOpen(Structur edViewer.java:395)
<br> at
<br> org.eclipse.jface.viewers.StructuredViewer.handleOpen(Struct uredViewer.java:605)
<br> at
<br> org.eclipse.jface.viewers.StructuredViewer$6.handleOpen(Stru cturedViewer.java:694)
<br> at
<br> org.eclipse.jface.util.OpenStrategy.fireOpenEvent(OpenStrate gy.java:209)
<br> at org.eclipse.jface.util.OpenStrategy.access$2(OpenStrategy.ja va:204)
<br> at
<br> org.eclipse.jface.util.OpenStrategy$1.handleEvent(OpenStrate gy.java:233)
<br> at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java :81)
<br> at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:840)
<br> at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.ja va:2022)
<br> at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :1729)
<br> at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:1402)
<br> at org.eclipse.ui.internal.Workbench.run(Workbench.java:1385)
<br> at
<br> org.eclipse.core.internal.boot.InternalBootLoader.run(Intern alBootLoader.java:858)
<br> at org.eclipse.core.boot.BootLoader.run(BootLoader.java:461)
<br> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native
Method)
<br> at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown
Source)
<br> at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown
Source)
<br> at java.lang.reflect.Method.invoke(Unknown
Source)
<br> at org.eclipse.core.launcher.Main.basicRun(Main.java:291)
<br> at org.eclipse.core.launcher.Main.run(Main.java:747)
<br> at org.eclipse.core.launcher.Main.main(Main.java:583)
<p>I have included the stack trace for debugging purposes. The best I can
<br>figure out is that EMF is assuming that an object is already contained
in
<br>this EList because of a fundamental assumption that at least one end
of a
<br>bidirectional reference will have been resolved during the first pass.
If
<br>the corrupted end of the reference appears after the uncorrupted end
then
<br>neither end of the reference is resolved in the first pass and the
list is
<br>empty when it should have already contained the object. EMF attempts
to
<br>move the object that isn't already in the list (gets a -1 for the position
<br>of the object in the list) and the EList class throws an IndexOutOfBounds
<br>exception.
<p>Does anyone have a suggestion for what should be the correct behaviour
in
<br>this case? As far as I'm concerned, the correct exception that should
be
<br>thrown is UnresolvedReferenceException as in the first case.
<p>Thanks,
<p>Chris McGee
<br>IBM Ottawa</blockquote>
</html>
--------------C92C4A7BB4E987AFD3C51007--
|
|
|
Re: The Wrong Exception Thrown From A Bad Reference [message #380735 is a reply to message #380734] |
Tue, 02 December 2003 13:48   |
Eclipse User |
|
|
|
Hi Ed,
Thanks for your quick reply. I now more fully understand what is
happening. These exceptions are being handled but also placed into a
collection of errors on the resource. At the end of the document load, the
first error is extracted and thrown.
I can retrieve all of the exceptions from the resource and pick the one
that helps me the most to track down the problem. Was this the intent?
Chris
Ed Merks wrote:
> Chris,
> I think that XMLHandler.setValueValue should be creating an
IllegalValueException because it's written like
> this:
> protected void setFeatureValue(EObject object, EStructuralFeature
feature, Object value, int
> position)
> {
> try
> {
> helper.setValue(object, feature, value, position);
> }
> catch (RuntimeException e)
> {
> error
> (new IllegalValueException
> (object,
> feature,
> value,
> e,
> getLocation(),
> getLineNumber(),
> getColumnNumber()));
> }
> }
> The exception implementation does stack trace printing like this:
> public void printStackTrace()
> {
> if (exception != null)
> {
> exception.printStackTrace();
> }
> else
> {
> super.printStackTrace();
> }
> }
> Which is different from WrappedException, which prints like this:
> public void printStackTrace()
> {
> System.err.println("Wrapped exception");
> wrappedException.printStackTrace();
> System.err.println("Wrapped by");
> super.printStackTrace();
> }
> The former will not show the information about where the exception was
wrapped and will tend to mislead you
> about the type of exception actually being thrown.
> In the code that does the move, we could change it like this to detect the
problem (with no real loss of
> efficiency):
> else
> {
> int index = list.indexOf(value);
> if (index == -1)
> {
> ... what do do?
> }
> else
> {
> list.move(position, index);
> }
> }
> But at this point we don't have all the location information to give a good
error message. So we could throw
> some other useful exception and allow it to be wrapped later to provide the
location information. Is this
> what you are looking for?
> Chris McGee wrote:
> > Hi All,
> >
> > I'm currently testing how EMF behaves with corrupted models. More
> > specifically, bad references. I have been taking models and purposefully
> > corrupting references, changing certain attributes of various xml tags and
> > even corrupting the xml itself to see how EMF responds. In most cases, the
> > exceptions are understandable and it is easy to interpret them to discover
> > what is wrong with the model.
> >
> > In the process of testing how EMF handles the case where one end of a
> > bidirectional reference is corrupted, I stumbled across a case where the
> > completely wrong exception is thrown.
> >
> > I can demonstrate the problem by using a slight variation of the library
> > model. I will describe the changes here but I can easily email a copy of
> > my Rose model, library plugins and example models to anyone who is
> > interested.
> >
> > I change the library model so that there is an additional composition
> > relationship on the Library class and itself called "collection" with a
> > multiplicity of "*" Also, the association between Writer and Book is
> > changed to have a multiplicity of "1..*" on the author end and "*" on the
> > books end.
> >
> > Having made these changes, I create the following three variations of a
> > model:
> >
> > <?xml version="1.0" encoding="ASCII"?>
> > <library:Library xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"
> > xmlns:library="http:///library.ecore" name="theLibrary">
> > <collection name="SpecialtyBooks">
> > <books title="TheTwoTowers" author="//@collection.1/@writers.0"/>
> > </collection>
> > <collection name="FamousWriters">
> > <writers name="Tolkien" books="//@collection.0/@books.0"/>
> > </collection>
> > </library:Library>
> >
> > * This is the uncorrupted model *
> >
> > <?xml version="1.0" encoding="ASCII"?>
> > <library:Library xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"
> > xmlns:library="http:///library.ecore" name="theLibrary">
> > <collection name="SpecialtyBooks">
> > <books title="TheTwoTowers" author="//@collection.1/@writers.1"/>
> > </collection>
> > <collection name="FamousWriters">
> > <writers name="Tolkien" books="//@collection.0/@books.0"/>
> > </collection>
> > </library:Library>
> >
> > * This model has the book's author reference corrupted and the following
> > (correct) exception is thrown by the eclipse editor*
> > org.eclipse.emf.ecore.xmi.UnresolvedReferenceException: Unresolved
> > reference '//@collection.1/@writers.1'.
> > (platform:/resource/test/CorrectException.library, 4, -1)
> >
> > <?xml version="1.0" encoding="ASCII"?>
> > <library:Library xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"
> > xmlns:library="http:///library.ecore" name="theLibrary">
> > <collection name="SpecialtyBooks">
> > <books title="TheTwoTowers" author="//@collection.1/@writers.0"/>
> > </collection>
> > <collection name="FamousWriters">
> > <writers name="Tolkien" books="//@collection.1/@books.0"/>
> > </collection>
> > </library:Library>
> >
> > * This model has the author's books reference corrupted and the following
> > (incorrect) exception is thrown by the eclipse editor*
> >
> > java.lang.IndexOutOfBoundsException: targetIndex=0, size=0
> > at org.eclipse.emf.common.util.BasicEList.move(BasicEList.java: 915)
> > at
> >
org.eclipse.emf.common.notify.impl.NotifyingListImpl.move(No tifyingListImpl.java:811)
> > at org.eclipse.emf.common.util.BasicEList.move(BasicEList.java: 899)
> > at
> >
org.eclipse.emf.ecore.xmi.impl.XMLHelperImpl.setValue(XMLHel perImpl.java:479)
> > at
> >
org.eclipse.emf.ecore.xmi.impl.XMLHandler.setFeatureValue(XM LHandler.java:1052)
> > at
> > org.eclipse.emf.ecore.xmi.impl.XMLHandler.endDocument(XMLHan dler.java:455)
> > at
> > org.eclipse.emf.ecore.xmi.impl.SAXWrapper.endDocument(SAXWra pper.java:55)
> > at org.apache.crimson.parser.Parser2.parseInternal(Unknown Source)
> > at org.apache.crimson.parser.Parser2.parse(Unknown Source)
> > at org.apache.crimson.parser.XMLReaderImpl.parse(Unknown Source)
> > at javax.xml.parsers.SAXParser.parse(Unknown Source)
> > at
org.eclipse.emf.ecore.xmi.impl.XMLLoadImpl.load(XMLLoadImpl. java:76)
> > at
> >
org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.doLoad(XMLRes ourceImpl.java:135)
> > at
> >
org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(Resour ceImpl.java:881)
> > at
> >
org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(Resour ceImpl.java:755)
> > at
> >
org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.demandLo ad(ResourceSetImpl.java:220)
> > at
> >
org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.getResou rce(ResourceSetImpl.java:286)
> > at
> >
org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain.load Resource(AdapterFactoryEditingDomain.java:284)
> > at
library.presentation.LibraryEditor.createPages(LibraryEditor .java:703)
> > at
> >
org.eclipse.ui.part.MultiPageEditorPart.createPartControl(Mu ltiPageEditorPart.java:166)
> > at org.eclipse.ui.internal.PartPane$4.run(PartPane.java:141)
> > at
> >
org.eclipse.core.internal.runtime.InternalPlatform.run(Inter nalPlatform.java:1006)
> > at org.eclipse.core.runtime.Platform.run(Platform.java:413)
> > at
org.eclipse.ui.internal.PartPane.createChildControl(PartPane .java:137)
> > at
org.eclipse.ui.internal.PartPane.createControl(PartPane.java :186)
> > at
> > org.eclipse.ui.internal.EditorWorkbook.createPage(EditorWork book.java:387)
> > at
org.eclipse.ui.internal.EditorWorkbook.add(EditorWorkbook.ja va:123)
> > at org.eclipse.ui.internal.EditorArea.addEditor(EditorArea.java :55)
> > at
> >
org.eclipse.ui.internal.EditorPresentation.openEditor(Editor Presentation.java:351)
> > at
org.eclipse.ui.internal.EditorManager$2.run(EditorManager.ja va:585)
> > at
org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator .java:69)
> > at
> >
org.eclipse.ui.internal.EditorManager.createEditorTab(Editor Manager.java:574)
> > at
> >
org.eclipse.ui.internal.EditorManager.openInternalEditor(Edi torManager.java:668)
> > at
> >
org.eclipse.ui.internal.EditorManager.openEditorFromDescript or(EditorManager.java:459)
> > at
> >
org.eclipse.ui.internal.EditorManager.openEditorFromInput(Ed itorManager.java:333)
> > at
> > org.eclipse.ui.internal.EditorManager.openEditor(EditorManag er.java:424)
> > at
> >
org.eclipse.ui.internal.WorkbenchPage.busyOpenEditor(Workben chPage.java:2056)
> > at
org.eclipse.ui.internal.WorkbenchPage.access$6(WorkbenchPage .java:2004)
> > at
org.eclipse.ui.internal.WorkbenchPage$9.run(WorkbenchPage.ja va:1991)
> > at
org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator .java:69)
> > at
> > org.eclipse.ui.internal.WorkbenchPage.openEditor(WorkbenchPa ge.java:1986)
> > at
> > org.eclipse.ui.internal.WorkbenchPage.openEditor(WorkbenchPa ge.java:1887)
> > at
org.eclipse.ui.actions.OpenFileAction.openFile(OpenFileActio n.java:96)
> > at
> >
org.eclipse.ui.actions.OpenSystemEditorAction.run(OpenSystem EditorAction.java:96)
> > at
> >
org.eclipse.ui.views.navigator.OpenActionGroup.runDefaultAct ion(OpenActionGroup.java:111)
> > at
> >
org.eclipse.ui.views.navigator.MainActionGroup.runDefaultAct ion(MainActionGroup.java:250)
> > at
> >
org.eclipse.ui.views.navigator.ResourceNavigator.handleOpen( ResourceNavigator.java:613)
> > at
> >
org.eclipse.ui.views.navigator.ResourceNavigator$6.open(Reso urceNavigator.java:384)
> > at
> > org.eclipse.jface.viewers.StructuredViewer$2.run(StructuredV iewer.java:397)
> > at
> >
org.eclipse.core.internal.runtime.InternalPlatform.run(Inter nalPlatform.java:1006)
> > at org.eclipse.core.runtime.Platform.run(Platform.java:413)
> > at
> >
org.eclipse.jface.viewers.StructuredViewer.fireOpen(Structur edViewer.java:395)
> > at
> >
org.eclipse.jface.viewers.StructuredViewer.handleOpen(Struct uredViewer.java:605)
> > at
> >
org.eclipse.jface.viewers.StructuredViewer$6.handleOpen(Stru cturedViewer.java:694)
> > at
> > org.eclipse.jface.util.OpenStrategy.fireOpenEvent(OpenStrate gy.java:209)
> > at
org.eclipse.jface.util.OpenStrategy.access$2(OpenStrategy.ja va:204)
> > at
> > org.eclipse.jface.util.OpenStrategy$1.handleEvent(OpenStrate gy.java:233)
> > at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java :81)
> > at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:840)
> > at
org.eclipse.swt.widgets.Display.runDeferredEvents(Display.ja va:2022)
> > at
org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :1729)
> > at
org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:1402)
> > at org.eclipse.ui.internal.Workbench.run(Workbench.java:1385)
> > at
> >
org.eclipse.core.internal.boot.InternalBootLoader.run(Intern alBootLoader.java:858)
> > at org.eclipse.core.boot.BootLoader.run(BootLoader.java:461)
> > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> > at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
> > at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
> > at java.lang.reflect.Method.invoke(Unknown Source)
> > at org.eclipse.core.launcher.Main.basicRun(Main.java:291)
> > at org.eclipse.core.launcher.Main.run(Main.java:747)
> > at org.eclipse.core.launcher.Main.main(Main.java:583)
> >
> > I have included the stack trace for debugging purposes. The best I can
> > figure out is that EMF is assuming that an object is already contained in
> > this EList because of a fundamental assumption that at least one end of a
> > bidirectional reference will have been resolved during the first pass. If
> > the corrupted end of the reference appears after the uncorrupted end then
> > neither end of the reference is resolved in the first pass and the list is
> > empty when it should have already contained the object. EMF attempts to
> > move the object that isn't already in the list (gets a -1 for the position
> > of the object in the list) and the EList class throws an IndexOutOfBounds
> > exception.
> >
> > Does anyone have a suggestion for what should be the correct behaviour in
> > this case? As far as I'm concerned, the correct exception that should be
> > thrown is UnresolvedReferenceException as in the first case.
> >
> > Thanks,
> >
> > Chris McGee
> > IBM Ottawa
|
|
|
Re: The Wrong Exception Thrown From A Bad Reference [message #380736 is a reply to message #380735] |
Tue, 02 December 2003 15:03  |
Eclipse User |
|
|
|
Chris,
Yes, I was going to explain that tidbit as well, but I didn't want to confuse the discussion. The delayed
throwing is very useful, since it allows the whole document to be processed as much as possible, but it can be
kind of confusing sometimes to get the exception so long after it really happened. Having access to all the
exceptions allows you to report all the errors to the user at once rather than just the first one...
Chris McGee wrote:
> Hi Ed,
>
> Thanks for your quick reply. I now more fully understand what is
> happening. These exceptions are being handled but also placed into a
> collection of errors on the resource. At the end of the document load, the
> first error is extracted and thrown.
>
> I can retrieve all of the exceptions from the resource and pick the one
> that helps me the most to track down the problem. Was this the intent?
>
> Chris
>
> Ed Merks wrote:
>
> > Chris,
>
> > I think that XMLHandler.setValueValue should be creating an
> IllegalValueException because it's written like
> > this:
>
> > protected void setFeatureValue(EObject object, EStructuralFeature
> feature, Object value, int
> > position)
> > {
> > try
> > {
> > helper.setValue(object, feature, value, position);
> > }
> > catch (RuntimeException e)
> > {
> > error
> > (new IllegalValueException
> > (object,
> > feature,
> > value,
> > e,
> > getLocation(),
> > getLineNumber(),
> > getColumnNumber()));
> > }
> > }
>
> > The exception implementation does stack trace printing like this:
>
> > public void printStackTrace()
> > {
> > if (exception != null)
> > {
> > exception.printStackTrace();
> > }
> > else
> > {
> > super.printStackTrace();
> > }
> > }
>
> > Which is different from WrappedException, which prints like this:
>
> > public void printStackTrace()
> > {
> > System.err.println("Wrapped exception");
> > wrappedException.printStackTrace();
> > System.err.println("Wrapped by");
> > super.printStackTrace();
> > }
>
> > The former will not show the information about where the exception was
> wrapped and will tend to mislead you
> > about the type of exception actually being thrown.
>
> > In the code that does the move, we could change it like this to detect the
> problem (with no real loss of
> > efficiency):
>
> > else
> > {
> > int index = list.indexOf(value);
> > if (index == -1)
> > {
> > ... what do do?
> > }
> > else
> > {
> > list.move(position, index);
> > }
> > }
>
> > But at this point we don't have all the location information to give a good
> error message. So we could throw
> > some other useful exception and allow it to be wrapped later to provide the
> location information. Is this
> > what you are looking for?
>
> > Chris McGee wrote:
>
> > > Hi All,
> > >
> > > I'm currently testing how EMF behaves with corrupted models. More
> > > specifically, bad references. I have been taking models and purposefully
> > > corrupting references, changing certain attributes of various xml tags and
> > > even corrupting the xml itself to see how EMF responds. In most cases, the
> > > exceptions are understandable and it is easy to interpret them to discover
> > > what is wrong with the model.
> > >
> > > In the process of testing how EMF handles the case where one end of a
> > > bidirectional reference is corrupted, I stumbled across a case where the
> > > completely wrong exception is thrown.
> > >
> > > I can demonstrate the problem by using a slight variation of the library
> > > model. I will describe the changes here but I can easily email a copy of
> > > my Rose model, library plugins and example models to anyone who is
> > > interested.
> > >
> > > I change the library model so that there is an additional composition
> > > relationship on the Library class and itself called "collection" with a
> > > multiplicity of "*" Also, the association between Writer and Book is
> > > changed to have a multiplicity of "1..*" on the author end and "*" on the
> > > books end.
> > >
> > > Having made these changes, I create the following three variations of a
> > > model:
> > >
> > > <?xml version="1.0" encoding="ASCII"?>
> > > <library:Library xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"
> > > xmlns:library="http:///library.ecore" name="theLibrary">
> > > <collection name="SpecialtyBooks">
> > > <books title="TheTwoTowers" author="//@collection.1/@writers.0"/>
> > > </collection>
> > > <collection name="FamousWriters">
> > > <writers name="Tolkien" books="//@collection.0/@books.0"/>
> > > </collection>
> > > </library:Library>
> > >
> > > * This is the uncorrupted model *
> > >
> > > <?xml version="1.0" encoding="ASCII"?>
> > > <library:Library xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"
> > > xmlns:library="http:///library.ecore" name="theLibrary">
> > > <collection name="SpecialtyBooks">
> > > <books title="TheTwoTowers" author="//@collection.1/@writers.1"/>
> > > </collection>
> > > <collection name="FamousWriters">
> > > <writers name="Tolkien" books="//@collection.0/@books.0"/>
> > > </collection>
> > > </library:Library>
> > >
> > > * This model has the book's author reference corrupted and the following
> > > (correct) exception is thrown by the eclipse editor*
> > > org.eclipse.emf.ecore.xmi.UnresolvedReferenceException: Unresolved
> > > reference '//@collection.1/@writers.1'.
> > > (platform:/resource/test/CorrectException.library, 4, -1)
> > >
> > > <?xml version="1.0" encoding="ASCII"?>
> > > <library:Library xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"
> > > xmlns:library="http:///library.ecore" name="theLibrary">
> > > <collection name="SpecialtyBooks">
> > > <books title="TheTwoTowers" author="//@collection.1/@writers.0"/>
> > > </collection>
> > > <collection name="FamousWriters">
> > > <writers name="Tolkien" books="//@collection.1/@books.0"/>
> > > </collection>
> > > </library:Library>
> > >
> > > * This model has the author's books reference corrupted and the following
> > > (incorrect) exception is thrown by the eclipse editor*
> > >
> > > java.lang.IndexOutOfBoundsException: targetIndex=0, size=0
> > > at org.eclipse.emf.common.util.BasicEList.move(BasicEList.java: 915)
> > > at
> > >
> org.eclipse.emf.common.notify.impl.NotifyingListImpl.move(No tifyingListImpl.java:811)
> > > at org.eclipse.emf.common.util.BasicEList.move(BasicEList.java: 899)
> > > at
> > >
> org.eclipse.emf.ecore.xmi.impl.XMLHelperImpl.setValue(XMLHel perImpl.java:479)
> > > at
> > >
> org.eclipse.emf.ecore.xmi.impl.XMLHandler.setFeatureValue(XM LHandler.java:1052)
> > > at
> > > org.eclipse.emf.ecore.xmi.impl.XMLHandler.endDocument(XMLHan dler.java:455)
> > > at
> > > org.eclipse.emf.ecore.xmi.impl.SAXWrapper.endDocument(SAXWra pper.java:55)
> > > at org.apache.crimson.parser.Parser2.parseInternal(Unknown Source)
> > > at org.apache.crimson.parser.Parser2.parse(Unknown Source)
> > > at org.apache.crimson.parser.XMLReaderImpl.parse(Unknown Source)
> > > at javax.xml.parsers.SAXParser.parse(Unknown Source)
> > > at
> org.eclipse.emf.ecore.xmi.impl.XMLLoadImpl.load(XMLLoadImpl. java:76)
> > > at
> > >
> org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.doLoad(XMLRes ourceImpl.java:135)
> > > at
> > >
> org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(Resour ceImpl.java:881)
> > > at
> > >
> org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(Resour ceImpl.java:755)
> > > at
> > >
> org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.demandLo ad(ResourceSetImpl.java:220)
> > > at
> > >
> org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.getResou rce(ResourceSetImpl.java:286)
> > > at
> > >
> org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain.load Resource(AdapterFactoryEditingDomain.java:284)
> > > at
> library.presentation.LibraryEditor.createPages(LibraryEditor .java:703)
> > > at
> > >
> org.eclipse.ui.part.MultiPageEditorPart.createPartControl(Mu ltiPageEditorPart.java:166)
> > > at org.eclipse.ui.internal.PartPane$4.run(PartPane.java:141)
> > > at
> > >
> org.eclipse.core.internal.runtime.InternalPlatform.run(Inter nalPlatform.java:1006)
> > > at org.eclipse.core.runtime.Platform.run(Platform.java:413)
> > > at
> org.eclipse.ui.internal.PartPane.createChildControl(PartPane .java:137)
> > > at
> org.eclipse.ui.internal.PartPane.createControl(PartPane.java :186)
> > > at
> > > org.eclipse.ui.internal.EditorWorkbook.createPage(EditorWork book.java:387)
> > > at
> org.eclipse.ui.internal.EditorWorkbook.add(EditorWorkbook.ja va:123)
> > > at org.eclipse.ui.internal.EditorArea.addEditor(EditorArea.java :55)
> > > at
> > >
> org.eclipse.ui.internal.EditorPresentation.openEditor(Editor Presentation.java:351)
> > > at
> org.eclipse.ui.internal.EditorManager$2.run(EditorManager.ja va:585)
> > > at
> org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator .java:69)
> > > at
> > >
> org.eclipse.ui.internal.EditorManager.createEditorTab(Editor Manager.java:574)
> > > at
> > >
> org.eclipse.ui.internal.EditorManager.openInternalEditor(Edi torManager.java:668)
> > > at
> > >
> org.eclipse.ui.internal.EditorManager.openEditorFromDescript or(EditorManager.java:459)
> > > at
> > >
> org.eclipse.ui.internal.EditorManager.openEditorFromInput(Ed itorManager.java:333)
> > > at
> > > org.eclipse.ui.internal.EditorManager.openEditor(EditorManag er.java:424)
> > > at
> > >
> org.eclipse.ui.internal.WorkbenchPage.busyOpenEditor(Workben chPage.java:2056)
> > > at
> org.eclipse.ui.internal.WorkbenchPage.access$6(WorkbenchPage .java:2004)
> > > at
> org.eclipse.ui.internal.WorkbenchPage$9.run(WorkbenchPage.ja va:1991)
> > > at
> org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator .java:69)
> > > at
> > > org.eclipse.ui.internal.WorkbenchPage.openEditor(WorkbenchPa ge.java:1986)
> > > at
> > > org.eclipse.ui.internal.WorkbenchPage.openEditor(WorkbenchPa ge.java:1887)
> > > at
> org.eclipse.ui.actions.OpenFileAction.openFile(OpenFileActio n.java:96)
> > > at
> > >
> org.eclipse.ui.actions.OpenSystemEditorAction.run(OpenSystem EditorAction.java:96)
> > > at
> > >
> org.eclipse.ui.views.navigator.OpenActionGroup.runDefaultAct ion(OpenActionGroup.java:111)
> > > at
> > >
> org.eclipse.ui.views.navigator.MainActionGroup.runDefaultAct ion(MainActionGroup.java:250)
> > > at
> > >
> org.eclipse.ui.views.navigator.ResourceNavigator.handleOpen( ResourceNavigator.java:613)
> > > at
> > >
> org.eclipse.ui.views.navigator.ResourceNavigator$6.open(Reso urceNavigator.java:384)
> > > at
> > > org.eclipse.jface.viewers.StructuredViewer$2.run(StructuredV iewer.java:397)
> > > at
> > >
> org.eclipse.core.internal.runtime.InternalPlatform.run(Inter nalPlatform.java:1006)
> > > at org.eclipse.core.runtime.Platform.run(Platform.java:413)
> > > at
> > >
> org.eclipse.jface.viewers.StructuredViewer.fireOpen(Structur edViewer.java:395)
> > > at
> > >
> org.eclipse.jface.viewers.StructuredViewer.handleOpen(Struct uredViewer.java:605)
> > > at
> > >
> org.eclipse.jface.viewers.StructuredViewer$6.handleOpen(Stru cturedViewer.java:694)
> > > at
> > > org.eclipse.jface.util.OpenStrategy.fireOpenEvent(OpenStrate gy.java:209)
> > > at
> org.eclipse.jface.util.OpenStrategy.access$2(OpenStrategy.ja va:204)
> > > at
> > > org.eclipse.jface.util.OpenStrategy$1.handleEvent(OpenStrate gy.java:233)
> > > at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java :81)
> > > at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:840)
> > > at
> org.eclipse.swt.widgets.Display.runDeferredEvents(Display.ja va:2022)
> > > at
> org.eclipse.swt.widgets.Display.readAndDispatch(Display.java :1729)
> > > at
> org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.jav a:1402)
> > > at org.eclipse.ui.internal.Workbench.run(Workbench.java:1385)
> > > at
> > >
> org.eclipse.core.internal.boot.InternalBootLoader.run(Intern alBootLoader.java:858)
> > > at org.eclipse.core.boot.BootLoader.run(BootLoader.java:461)
> > > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> > > at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
> > > at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
> > > at java.lang.reflect.Method.invoke(Unknown Source)
> > > at org.eclipse.core.launcher.Main.basicRun(Main.java:291)
> > > at org.eclipse.core.launcher.Main.run(Main.java:747)
> > > at org.eclipse.core.launcher.Main.main(Main.java:583)
> > >
> > > I have included the stack trace for debugging purposes. The best I can
> > > figure out is that EMF is assuming that an object is already contained in
> > > this EList because of a fundamental assumption that at least one end of a
> > > bidirectional reference will have been resolved during the first pass. If
> > > the corrupted end of the reference appears after the uncorrupted end then
> > > neither end of the reference is resolved in the first pass and the list is
> > > empty when it should have already contained the object. EMF attempts to
> > > move the object that isn't already in the list (gets a -1 for the position
> > > of the object in the list) and the EList class throws an IndexOutOfBounds
> > > exception.
> > >
> > > Does anyone have a suggestion for what should be the correct behaviour in
> > > this case? As far as I'm concerned, the correct exception that should be
> > > thrown is UnresolvedReferenceException as in the first case.
> > >
> > > Thanks,
> > >
> > > Chris McGee
> > > IBM Ottawa
|
|
|
Goto Forum:
Current Time: Tue Sep 23 05:29:41 EDT 2025
Powered by FUDForum. Page generated in 0.05796 seconds
|