Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » [CDO] eStore() returns null which results in a NPE
[CDO] eStore() returns null which results in a NPE [message #424807] Wed, 05 November 2008 23:08 Go to next message
Stephen McCants is currently offline Stephen McCantsFriend
Messages: 92
Registered: July 2009
Member
Hi,

I'm running into problems where I make calls to CDO objects and down inside the getter code it calls
eStore() and gets null returned to it. It then tries to make the calls on the eStore() null pointer
and so it throws a NPE. Here is one of the exceptions:

java.lang.NullPointerException
at org.eclipse.emf.ecore.impl.EStoreEObjectImpl.dynamicGet(ESto reEObjectImpl.java:646)
at
org.eclipse.emf.ecore.impl.EStructuralFeatureImpl$InternalSe ttingDelegateSingleData.dynamicGet(EStructuralFeatureImpl.ja va:1953)
at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1027)
at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1012)
at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1004)
at .... (my call to the CDO object is here)

I just checked out the code from HEAD today, which solved some problems but not this problem.

Any ideas on where I should be looking to figure this one out?

Thanks!

Sincerely,
Stephen McCants
Re: [CDO] eStore() returns null which results in a NPE [message #424809 is a reply to message #424807] Wed, 05 November 2008 23:33 Go to previous messageGo to next message
Simon Mc Duff is currently offline Simon Mc DuffFriend
Messages: 596
Registered: July 2009
Senior Member
Can you copy/paste the code to make that happens ?

What do you do exactly ?

Simon

Stephen McCants wrote:
> Hi,
>
> I'm running into problems where I make calls to CDO objects and down
> inside the getter code it calls eStore() and gets null returned to it.
> It then tries to make the calls on the eStore() null pointer and so it
> throws a NPE. Here is one of the exceptions:
>
> java.lang.NullPointerException
> at
> org.eclipse.emf.ecore.impl.EStoreEObjectImpl.dynamicGet(ESto reEObjectImpl.java:646)
>
> at
> org.eclipse.emf.ecore.impl.EStructuralFeatureImpl$InternalSe ttingDelegateSingleData.dynamicGet(EStructuralFeatureImpl.ja va:1953)
>
> at
> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1027)
>
> at
> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1012)
>
> at
> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1004)
>
> at .... (my call to the CDO object is here)
>
> I just checked out the code from HEAD today, which solved some problems
> but not this problem.
>
> Any ideas on where I should be looking to figure this one out?
>
> Thanks!
>
> Sincerely,
> Stephen McCants
Re: [CDO] eStore() returns null which results in a NPE [message #424810 is a reply to message #424809] Wed, 05 November 2008 23:40 Go to previous messageGo to next message
Simon Mc Duff is currently offline Simon Mc DuffFriend
Messages: 596
Registered: July 2009
Senior Member
Can you double check that "this" is instanceof CDOObjectImpl ?

We override eStore() and

/**
* @since 2.0
*/
@Override
public InternalEObject.EStore eStore()
{
if (FSMUtil.isTransient(this))
{
return CDOStoreSettingsImpl.INSTANCE;
}

return cdoStore();





cdoStore(); could return null only if you close your CDOView that is
attached to this EObject.

I will add a checkOpen() in CDOViewimpl.getStore() for next time :-))

Simon

Simon McDuff wrote:
> Can you copy/paste the code to make that happens ?
>
> What do you do exactly ?
>
> Simon
>
> Stephen McCants wrote:
>> Hi,
>>
>> I'm running into problems where I make calls to CDO objects and down
>> inside the getter code it calls eStore() and gets null returned to
>> it. It then tries to make the calls on the eStore() null pointer and
>> so it throws a NPE. Here is one of the exceptions:
>>
>> java.lang.NullPointerException
>> at
>> org.eclipse.emf.ecore.impl.EStoreEObjectImpl.dynamicGet(ESto reEObjectImpl.java:646)
>>
>> at
>> org.eclipse.emf.ecore.impl.EStructuralFeatureImpl$InternalSe ttingDelegateSingleData.dynamicGet(EStructuralFeatureImpl.ja va:1953)
>>
>> at
>> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1027)
>>
>> at
>> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1012)
>>
>> at
>> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1004)
>>
>> at .... (my call to the CDO object is here)
>>
>> I just checked out the code from HEAD today, which solved some
>> problems but not this problem.
>>
>> Any ideas on where I should be looking to figure this one out?
>>
>> Thanks!
>>
>> Sincerely,
>> Stephen McCants
Re: [CDO] eStore() returns null which results in a NPE [message #424812 is a reply to message #424809] Thu, 06 November 2008 00:34 Go to previous messageGo to next message
Stephen McCants is currently offline Stephen McCantsFriend
Messages: 92
Registered: July 2009
Member
Hi Simon,
Here is what I'm doing to essentially:

0) Create transaction1.
1) Create one object (call it a Folder) and store it in a resource.
2) Commit the transaction1.
3) Create transaction2.
4) Next, create two objects in the CDO model under transaction2 and store the first one (a Config)
in a different resource. Store the second object (call it a ConfigPointer) as a child of the Folder
object.
5) The second object has a "URI" (string) that identifies the location of the first object (set
before the commit).
6) Commit that transaction2.
7) Now, if a different transaction, get the ConfigPointer and try to read the "URI". That is when I
get the NPE.

Here is the code for steps 0-2

CDOTransaction transaction = session.openTransaction();

if(!transaction.hasResource(Constants.CONFIG_DIRECTORY_RESOU RCE))
{
Resource resource = transaction.createResource(Constants.CONFIG_DIRECTORY_RESOUR CE);
Folder root = DirectoryFactory.eINSTANCE.createFolder();
root.setName("");
resource.getContents().add(root);
transaction.commit();
}

Here is the code for steps 3-6:

Resource resource = transaction.createResource(modelPage.getModelPath().toString ());

// Build a default LLJobConfig object
Config config = ConfigFactory.eINSTANCE.createConfig();
jobConfig.setName(modelPage.getModelPath().lastSegment());
resource.getContents().add(jobConfig);

ConfigPointer configPointer = DirectoryFactory.eINSTANCE.createConfigPointer();
configPointer.setName(modelPage.getModelPath().lastSegment() );
configPointer.setURI(modelPage.getModelPath().toString());
Folder folder = modelPage.getSelectedFolder();

// If it belongs to the root of the tree - this code runs on the specific case
if (folder == null)
folder = (Folder) directoryResource.getContents().get(0);

folder.getChildren().add(configPointer);
transaction.commit();

Code for step 7:

IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
Object selected = selection.getFirstElement();
if(selected instanceof ConfigResource)
{
String uri = ((ConfigResource)selected).getURI();
....
NPE on the last line.

Feel free to ask if you have any questions. I tried to create a simple test case, but that case works.

Thanks for your help!

--Stephen

Simon McDuff wrote:
> Can you copy/paste the code to make that happens ?
>
> What do you do exactly ?
>
> Simon
>
> Stephen McCants wrote:
>> Hi,
>>
>> I'm running into problems where I make calls to CDO objects and down
>> inside the getter code it calls eStore() and gets null returned to
>> it. It then tries to make the calls on the eStore() null pointer and
>> so it throws a NPE. Here is one of the exceptions:
>>
>> java.lang.NullPointerException
>> at
>> org.eclipse.emf.ecore.impl.EStoreEObjectImpl.dynamicGet(ESto reEObjectImpl.java:646)
>>
>> at
>> org.eclipse.emf.ecore.impl.EStructuralFeatureImpl$InternalSe ttingDelegateSingleData.dynamicGet(EStructuralFeatureImpl.ja va:1953)
>>
>> at
>> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1027)
>>
>> at
>> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1012)
>>
>> at
>> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1004)
>>
>> at .... (my call to the CDO object is here)
>>
>> I just checked out the code from HEAD today, which solved some
>> problems but not this problem.
>>
>> Any ideas on where I should be looking to figure this one out?
>>
>> Thanks!
>>
>> Sincerely,
>> Stephen McCants
Re: [CDO] eStore() returns null which results in a NPE [message #424813 is a reply to message #424810] Thu, 06 November 2008 01:04 Go to previous messageGo to next message
Stephen McCants is currently offline Stephen McCantsFriend
Messages: 92
Registered: July 2009
Member
Hi Simon,
You are correct, the transaction is closed. What is more puzzling is that it is the wrong transaction.

The Eclipse debugger shows the object as a "ConfigResource" (what I called a ConfigPointer in the
earlier email). This is an EMF object that "extends CDOObjectImpl implements CDOObject".

When the ConfigResource is created, it is created inside transaction (id=277), so the ConfigResource
in that code shows that it's "view" object is transaction(277). After creating the ConfigResource
and committing, then the transaction is closed.

Now, a different part of the code has an open transaction (id=146) which loads the ConfigResource.
However, the ConfigResource has a the original transaction (277) that it was created with, not the
one it should have been loaded with. This, of course, leads to the NPE.

The confusing part (and maybe the bug), is how did a ConfigResource end up with a transaction that
is different than the CDOTransaction it was loaded with? They are two separate objects in two
separate parts of the code. The only thing I can find that they have in common is they share the
same CDOSession. Is it possible the session is somehow corrupting the ConfigResource that the 146
Transaction loads?

I'm still working on figuring out what is reallying going on here...
My simple test case still doesn't show the bug.

--Stephen

Simon McDuff wrote:
> Can you double check that "this" is instanceof CDOObjectImpl ?
>
> We override eStore() and
>
> /**
> * @since 2.0
> */
> @Override
> public InternalEObject.EStore eStore()
> {
> if (FSMUtil.isTransient(this))
> {
> return CDOStoreSettingsImpl.INSTANCE;
> }
>
> return cdoStore();
>
>
>
>
>
> cdoStore(); could return null only if you close your CDOView that is
> attached to this EObject.
>
> I will add a checkOpen() in CDOViewimpl.getStore() for next time :-))
>
> Simon
>
> Simon McDuff wrote:
>> Can you copy/paste the code to make that happens ?
>>
>> What do you do exactly ?
>>
>> Simon
>>
>> Stephen McCants wrote:
>>> Hi,
>>>
>>> I'm running into problems where I make calls to CDO objects and down
>>> inside the getter code it calls eStore() and gets null returned to
>>> it. It then tries to make the calls on the eStore() null pointer and
>>> so it throws a NPE. Here is one of the exceptions:
>>>
>>> java.lang.NullPointerException
>>> at
>>> org.eclipse.emf.ecore.impl.EStoreEObjectImpl.dynamicGet(ESto reEObjectImpl.java:646)
>>>
>>> at
>>> org.eclipse.emf.ecore.impl.EStructuralFeatureImpl$InternalSe ttingDelegateSingleData.dynamicGet(EStructuralFeatureImpl.ja va:1953)
>>>
>>> at
>>> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1027)
>>>
>>> at
>>> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1012)
>>>
>>> at
>>> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1004)
>>>
>>> at .... (my call to the CDO object is here)
>>>
>>> I just checked out the code from HEAD today, which solved some
>>> problems but not this problem.
>>>
>>> Any ideas on where I should be looking to figure this one out?
>>>
>>> Thanks!
>>>
>>> Sincerely,
>>> Stephen McCants
Re: [CDO] eStore() returns null which results in a NPE [message #424814 is a reply to message #424812] Thu, 06 November 2008 01:09 Go to previous messageGo to next message
Simon Mc Duff is currently offline Simon Mc DuffFriend
Messages: 596
Registered: July 2009
Senior Member
DO you close any Transaction ?
Do you close transaction2 at some point ?

Where comes directoryResource from ?

Does ConfigPointer extends ConfigResource ? (Otherwise where are you
creating instance of ConfigResource)

Steps 7 you said...
>7) Now, if a different transaction, get the ConfigPointer and try to
> read the "URI". That is when I get the NPE.
WHat do you mean by if a different transaction ? I don't see that ?

IStructuredSelection selection =
> (IStructuredSelection)viewer.getSelection();
> Object selected = selection.getFirstElement();
> if(selected instanceof ConfigResource)
> {
> String uri = ((ConfigResource)selected).getURI();




Stephen McCants wrote:
> Hi Simon,
> Here is what I'm doing to essentially:
>
> 0) Create transaction1.
> 1) Create one object (call it a Folder) and store it in a resource.
> 2) Commit the transaction1.
> 3) Create transaction2.
> 4) Next, create two objects in the CDO model under transaction2 and
> store the first one (a Config) in a different resource. Store the
> second object (call it a ConfigPointer) as a child of the Folder object.
> 5) The second object has a "URI" (string) that identifies the location
> of the first object (set before the commit).
> 6) Commit that transaction2.
> 7) Now, if a different transaction, get the ConfigPointer and try to
> read the "URI". That is when I get the NPE.
>
> Here is the code for steps 0-2
>
> CDOTransaction transaction = session.openTransaction();
>
> if(!transaction.hasResource(Constants.CONFIG_DIRECTORY_RESOU RCE))
> {
> Resource resource =
> transaction.createResource(Constants.CONFIG_DIRECTORY_RESOUR CE);
> Folder root = DirectoryFactory.eINSTANCE.createFolder();
> root.setName("");
> resource.getContents().add(root);
> transaction.commit();
> }
>
> Here is the code for steps 3-6:
>
> Resource resource =
> transaction.createResource(modelPage.getModelPath().toString ());
>
> // Build a default LLJobConfig object
> Config config = ConfigFactory.eINSTANCE.createConfig();
> jobConfig.setName(modelPage.getModelPath().lastSegment());
> resource.getContents().add(jobConfig);
>
> ConfigPointer configPointer =
> DirectoryFactory.eINSTANCE.createConfigPointer();
> configPointer.setName(modelPage.getModelPath().lastSegment() );
> configPointer.setURI(modelPage.getModelPath().toString());
> Folder folder = modelPage.getSelectedFolder();
>
> // If it belongs to the root of the tree - this code runs on the
> specific case
> if (folder == null)
> folder = (Folder) directoryResource.getContents().get(0);
>
> folder.getChildren().add(configPointer);
> transaction.commit();
>
> Code for step 7:
>
> IStructuredSelection selection =
> (IStructuredSelection)viewer.getSelection();
> Object selected = selection.getFirstElement();
> if(selected instanceof ConfigResource)
> {
> String uri = ((ConfigResource)selected).getURI();
> ....
> NPE on the last line.
>
> Feel free to ask if you have any questions. I tried to create a simple
> test case, but that case works.
>
> Thanks for your help!
>
> --Stephen
>
> Simon McDuff wrote:
>> Can you copy/paste the code to make that happens ?
>>
>> What do you do exactly ?
>>
>> Simon
>>
>> Stephen McCants wrote:
>>> Hi,
>>>
>>> I'm running into problems where I make calls to CDO objects and down
>>> inside the getter code it calls eStore() and gets null returned to
>>> it. It then tries to make the calls on the eStore() null pointer and
>>> so it throws a NPE. Here is one of the exceptions:
>>>
>>> java.lang.NullPointerException
>>> at
>>> org.eclipse.emf.ecore.impl.EStoreEObjectImpl.dynamicGet(ESto reEObjectImpl.java:646)
>>>
>>> at
>>> org.eclipse.emf.ecore.impl.EStructuralFeatureImpl$InternalSe ttingDelegateSingleData.dynamicGet(EStructuralFeatureImpl.ja va:1953)
>>>
>>> at
>>> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1027)
>>>
>>> at
>>> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1012)
>>>
>>> at
>>> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1004)
>>>
>>> at .... (my call to the CDO object is here)
>>>
>>> I just checked out the code from HEAD today, which solved some
>>> problems but not this problem.
>>>
>>> Any ideas on where I should be looking to figure this one out?
>>>
>>> Thanks!
>>>
>>> Sincerely,
>>> Stephen McCants
Re: [CDO] eStore() returns null which results in a NPE [message #424815 is a reply to message #424814] Thu, 06 November 2008 01:17 Go to previous messageGo to next message
Simon Mc Duff is currently offline Simon Mc DuffFriend
Messages: 596
Registered: July 2009
Senior Member
What is that

Folder folder = modelPage.getSelectedFolder();

if (folder == null)
folder = (Folder) directoryResource.getContents().get(0);

folder.getChildren().add(configPointer);
transaction.commit();

Where modelPage comes from ? Is it a UI things ?
From there we get folder... and attach the configPointer.

What are the links between

- modelPage
and
-(IStructuredSelection)viewer.getSelection();
Object selected = selection.getFirstElement();



Simon

Simon McDuff wrote:
>
> DO you close any Transaction ?
> Do you close transaction2 at some point ?
>
> Where comes directoryResource from ?
>
> Does ConfigPointer extends ConfigResource ? (Otherwise where are you
> creating instance of ConfigResource)
>
> Steps 7 you said...
> >7) Now, if a different transaction, get the ConfigPointer and try to
> > read the "URI". That is when I get the NPE.
> WHat do you mean by if a different transaction ? I don't see that ?
>
> IStructuredSelection selection =
> > (IStructuredSelection)viewer.getSelection();
> > Object selected = selection.getFirstElement();
> > if(selected instanceof ConfigResource)
> > {
> > String uri = ((ConfigResource)selected).getURI();
>
>
>
>
> Stephen McCants wrote:
>> Hi Simon,
>> Here is what I'm doing to essentially:
>>
>> 0) Create transaction1.
>> 1) Create one object (call it a Folder) and store it in a resource.
>> 2) Commit the transaction1.
>> 3) Create transaction2.
>> 4) Next, create two objects in the CDO model under transaction2 and
>> store the first one (a Config) in a different resource. Store the
>> second object (call it a ConfigPointer) as a child of the Folder object.
>> 5) The second object has a "URI" (string) that identifies the location
>> of the first object (set before the commit).
>> 6) Commit that transaction2.
>> 7) Now, if a different transaction, get the ConfigPointer and try to
>> read the "URI". That is when I get the NPE.
>>
>> Here is the code for steps 0-2
>>
>> CDOTransaction transaction = session.openTransaction();
>>
>> if(!transaction.hasResource(Constants.CONFIG_DIRECTORY_RESOU RCE))
>> {
>> Resource resource =
>> transaction.createResource(Constants.CONFIG_DIRECTORY_RESOUR CE);
>> Folder root = DirectoryFactory.eINSTANCE.createFolder();
>> root.setName("");
>> resource.getContents().add(root);
>> transaction.commit();
>> }
>>
>> Here is the code for steps 3-6:
>>
>> Resource resource =
>> transaction.createResource(modelPage.getModelPath().toString ());
>>
>> // Build a default LLJobConfig object
>> Config config = ConfigFactory.eINSTANCE.createConfig();
>> jobConfig.setName(modelPage.getModelPath().lastSegment());
>> resource.getContents().add(jobConfig);
>>
>> ConfigPointer configPointer =
>> DirectoryFactory.eINSTANCE.createConfigPointer();
>> configPointer.setName(modelPage.getModelPath().lastSegment() );
>> configPointer.setURI(modelPage.getModelPath().toString());
>> Folder folder = modelPage.getSelectedFolder();
>>
>> // If it belongs to the root of the tree - this code runs on
>> the specific case
>> if (folder == null)
>> folder = (Folder) directoryResource.getContents().get(0);
>>
>> folder.getChildren().add(configPointer);
>> transaction.commit();
>>
>> Code for step 7:
>>
>> IStructuredSelection selection =
>> (IStructuredSelection)viewer.getSelection();
>> Object selected = selection.getFirstElement();
>> if(selected instanceof ConfigResource)
>> {
>> String uri = ((ConfigResource)selected).getURI();
>> ....
>> NPE on the last line.
>>
>> Feel free to ask if you have any questions. I tried to create a
>> simple test case, but that case works.
>>
>> Thanks for your help!
>>
>> --Stephen
>>
>> Simon McDuff wrote:
>>> Can you copy/paste the code to make that happens ?
>>>
>>> What do you do exactly ?
>>>
>>> Simon
>>>
>>> Stephen McCants wrote:
>>>> Hi,
>>>>
>>>> I'm running into problems where I make calls to CDO objects and down
>>>> inside the getter code it calls eStore() and gets null returned to
>>>> it. It then tries to make the calls on the eStore() null pointer
>>>> and so it throws a NPE. Here is one of the exceptions:
>>>>
>>>> java.lang.NullPointerException
>>>> at
>>>> org.eclipse.emf.ecore.impl.EStoreEObjectImpl.dynamicGet(ESto reEObjectImpl.java:646)
>>>>
>>>> at
>>>> org.eclipse.emf.ecore.impl.EStructuralFeatureImpl$InternalSe ttingDelegateSingleData.dynamicGet(EStructuralFeatureImpl.ja va:1953)
>>>>
>>>> at
>>>> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1027)
>>>>
>>>> at
>>>> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1012)
>>>>
>>>> at
>>>> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1004)
>>>>
>>>> at .... (my call to the CDO object is here)
>>>>
>>>> I just checked out the code from HEAD today, which solved some
>>>> problems but not this problem.
>>>>
>>>> Any ideas on where I should be looking to figure this one out?
>>>>
>>>> Thanks!
>>>>
>>>> Sincerely,
>>>> Stephen McCants
Re: [CDO] eStore() returns null which results in a NPE [message #424816 is a reply to message #424814] Thu, 06 November 2008 01:22 Go to previous messageGo to next message
Stephen McCants is currently offline Stephen McCantsFriend
Messages: 92
Registered: July 2009
Member
Hi Simon,
I think I've made a confusing mess with my emails, so let my try to clear up what is going on.
> DO you close any Transaction ?
> Do you close transaction2 at some point ?
Yes, both transaction1 and 2 are closed after the commit. I missed that detail in my earlier email.
Sorry.
> Where comes directoryResource from ?
Was loaded earlier through transaction2. Sorry, my code should have included that.
>
> Does ConfigPointer extends ConfigResource ? (Otherwise where are you
> creating instance of ConfigResource)
Again, I made things confusing because I changed the name of the Object on you. ConfigPointer and
ConfigResource are the same class. Sorry.
>
> Steps 7 you said...
> >7) Now, if a different transaction, get the ConfigPointer and try to
> > read the "URI". That is when I get the NPE.
> WHat do you mean by if a different transaction ? I don't see that ?

So, this is where things get interesting. This code resides in an Eclipse View and I should have
shown it more fully:

viewer = new TreeViewer(parent, SWT.NONE);
viewer.setContentProvider(new
ObservableListTreeContentProvider(EMFObservables.listFactory (Realm.getDefault(),
DirectoryPackage.Literals.FOLDER__CHILDREN), new DirectoryTreeStructureAdvisor()));
viewer.setLabelProvider(new ConfigDirectoryTreeLabelProvider());
transaction = CDOSessionManager.getSession().openTransaction();
transaction.setChangeSubscriptionPolicy(CDOChangeSubscriptio nPolicy.ALL);
Resource resource = transaction.getResource("/config.dir");
viewer.setInput(resource.getContents().get(0));

// Open an editor double click action
viewer.addDoubleClickListener(new IDoubleClickListener()
{
public void doubleClick(DoubleClickEvent event)
{
IStructuredSelection selection =(IStructuredSelection)viewer.getSelection();
Object selected = selection.getFirstElement();
if(selected instanceof ConfigResource)
{
String uri = ((ConfigResource)selected).getURI();
.....
So this Viewer is setup with the resource loaded through this transaction (transaction3). Then, I
go a create the ConfigResource. The View automatically detects the change through the
ObservaleListTreeContentProvider, but when I double click and the viewer returns the selected
ConfigResource with the wrong Transaction inside the selected ConfigResource.

Does that make sense?
Sorry I made this so confusing.

--Stephen
Re: [CDO] eStore() returns null which results in a NPE [message #424817 is a reply to message #424815] Thu, 06 November 2008 01:23 Go to previous messageGo to next message
Stephen McCants is currently offline Stephen McCantsFriend
Messages: 92
Registered: July 2009
Member
ModelPage is a WizardPage for the Wizard that creates the ResourceConfig.
--Stephen

Simon McDuff wrote:
> What is that
>
> Folder folder = modelPage.getSelectedFolder();
>
> if (folder == null)
> folder = (Folder) directoryResource.getContents().get(0);
>
> folder.getChildren().add(configPointer);
> transaction.commit();
>
> Where modelPage comes from ? Is it a UI things ?
> From there we get folder... and attach the configPointer.
>
> What are the links between
>
> - modelPage
> and
> -(IStructuredSelection)viewer.getSelection();
> Object selected = selection.getFirstElement();
>
>
>
> Simon
>
> Simon McDuff wrote:
>>
>> DO you close any Transaction ?
>> Do you close transaction2 at some point ?
>>
>> Where comes directoryResource from ?
>>
>> Does ConfigPointer extends ConfigResource ? (Otherwise where are you
>> creating instance of ConfigResource)
>>
>> Steps 7 you said...
>> >7) Now, if a different transaction, get the ConfigPointer and try to
>> > read the "URI". That is when I get the NPE.
>> WHat do you mean by if a different transaction ? I don't see that ?
>>
>> IStructuredSelection selection =
>> > (IStructuredSelection)viewer.getSelection();
>> > Object selected = selection.getFirstElement();
>> > if(selected instanceof ConfigResource)
>> > {
>> > String uri = ((ConfigResource)selected).getURI();
>>
>>
>>
>>
>> Stephen McCants wrote:
>>> Hi Simon,
>>> Here is what I'm doing to essentially:
>>>
>>> 0) Create transaction1.
>>> 1) Create one object (call it a Folder) and store it in a resource.
>>> 2) Commit the transaction1.
>>> 3) Create transaction2.
>>> 4) Next, create two objects in the CDO model under transaction2 and
>>> store the first one (a Config) in a different resource. Store the
>>> second object (call it a ConfigPointer) as a child of the Folder object.
>>> 5) The second object has a "URI" (string) that identifies the
>>> location of the first object (set before the commit).
>>> 6) Commit that transaction2.
>>> 7) Now, if a different transaction, get the ConfigPointer and try to
>>> read the "URI". That is when I get the NPE.
>>>
>>> Here is the code for steps 0-2
>>>
>>> CDOTransaction transaction = session.openTransaction();
>>>
>>> if(!transaction.hasResource(Constants.CONFIG_DIRECTORY_RESOU RCE))
>>> {
>>> Resource resource =
>>> transaction.createResource(Constants.CONFIG_DIRECTORY_RESOUR CE);
>>> Folder root = DirectoryFactory.eINSTANCE.createFolder();
>>> root.setName("");
>>> resource.getContents().add(root);
>>> transaction.commit();
>>> }
>>>
>>> Here is the code for steps 3-6:
>>>
>>> Resource resource =
>>> transaction.createResource(modelPage.getModelPath().toString ());
>>>
>>> // Build a default LLJobConfig object
>>> Config config = ConfigFactory.eINSTANCE.createConfig();
>>> jobConfig.setName(modelPage.getModelPath().lastSegment());
>>> resource.getContents().add(jobConfig);
>>>
>>> ConfigPointer configPointer =
>>> DirectoryFactory.eINSTANCE.createConfigPointer();
>>> configPointer.setName(modelPage.getModelPath().lastSegment() );
>>> configPointer.setURI(modelPage.getModelPath().toString());
>>> Folder folder = modelPage.getSelectedFolder();
>>>
>>> // If it belongs to the root of the tree - this code runs on
>>> the specific case
>>> if (folder == null)
>>> folder = (Folder) directoryResource.getContents().get(0);
>>>
>>> folder.getChildren().add(configPointer);
>>> transaction.commit();
>>>
>>> Code for step 7:
>>>
>>> IStructuredSelection selection =
>>> (IStructuredSelection)viewer.getSelection();
>>> Object selected = selection.getFirstElement();
>>> if(selected instanceof ConfigResource)
>>> {
>>> String uri = ((ConfigResource)selected).getURI();
>>> ....
>>> NPE on the last line.
>>>
>>> Feel free to ask if you have any questions. I tried to create a
>>> simple test case, but that case works.
>>>
>>> Thanks for your help!
>>>
>>> --Stephen
>>>
>>> Simon McDuff wrote:
>>>> Can you copy/paste the code to make that happens ?
>>>>
>>>> What do you do exactly ?
>>>>
>>>> Simon
>>>>
>>>> Stephen McCants wrote:
>>>>> Hi,
>>>>>
>>>>> I'm running into problems where I make calls to CDO objects and
>>>>> down inside the getter code it calls eStore() and gets null
>>>>> returned to it. It then tries to make the calls on the eStore()
>>>>> null pointer and so it throws a NPE. Here is one of the exceptions:
>>>>>
>>>>> java.lang.NullPointerException
>>>>> at
>>>>> org.eclipse.emf.ecore.impl.EStoreEObjectImpl.dynamicGet(ESto reEObjectImpl.java:646)
>>>>>
>>>>> at
>>>>> org.eclipse.emf.ecore.impl.EStructuralFeatureImpl$InternalSe ttingDelegateSingleData.dynamicGet(EStructuralFeatureImpl.ja va:1953)
>>>>>
>>>>> at
>>>>> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1027)
>>>>>
>>>>> at
>>>>> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1012)
>>>>>
>>>>> at
>>>>> org.eclipse.emf.ecore.impl.BasicEObjectImpl.eGet(BasicEObjec tImpl.java:1004)
>>>>>
>>>>> at .... (my call to the CDO object is here)
>>>>>
>>>>> I just checked out the code from HEAD today, which solved some
>>>>> problems but not this problem.
>>>>>
>>>>> Any ideas on where I should be looking to figure this one out?
>>>>>
>>>>> Thanks!
>>>>>
>>>>> Sincerely,
>>>>> Stephen McCants
Re: [CDO] eStore() returns null which results in a NPE [message #424818 is a reply to message #424816] Thu, 06 November 2008 01:42 Go to previous messageGo to next message
Simon Mc Duff is currently offline Simon Mc DuffFriend
Messages: 596
Registered: July 2009
Senior Member
Thank you for yours answers:

The things I do not understand is the following:

>Folder folder = modelPage.getSelectedFolder();
>
> // If it belongs to the root of the tree - this code runs on
>the specific case
> if (folder == null)
> folder = (Folder) directoryResource.getContents().get(0);
>
> folder.getChildren().add(configPointer);


Folder belongs to which transaction it comes from
modelPage.getSelectedFolder() ? (probably transaction 3 right?)

DirectoryResource comes from transaction2 right ?

IF folder != null modify transaction3(from modelPage.getSleectedFOlder)
and commit transaction2

if folder == null modify transaction2(from directoryResource) and
commit transaction2

humm...Make sense for you ?


Can you paste as much code as you can to include ?
- Where come from directoryResource ? (you said transaction2.. but I
want to see)
- Where do you create transaction2 ?

For me it doesn't make sense.. but we certainly have a problem
somewhere! :-) (it helps you I know!!:-))



Stephen McCants wrote:
> Hi Simon,
> I think I've made a confusing mess with my emails, so let my try to
> clear up what is going on.
>> DO you close any Transaction ?
>> Do you close transaction2 at some point ?
> Yes, both transaction1 and 2 are closed after the commit. I missed that
> detail in my earlier email. Sorry.
>> Where comes directoryResource from ?
> Was loaded earlier through transaction2. Sorry, my code should have
> included that.
>>
>> Does ConfigPointer extends ConfigResource ? (Otherwise where are you
>> creating instance of ConfigResource)
> Again, I made things confusing because I changed the name of the Object
> on you. ConfigPointer and ConfigResource are the same class. Sorry.
>>
>> Steps 7 you said...
>> >7) Now, if a different transaction, get the ConfigPointer and try to
>> > read the "URI". That is when I get the NPE.
>> WHat do you mean by if a different transaction ? I don't see that ?
>
> So, this is where things get interesting. This code resides in an
> Eclipse View and I should have shown it more fully:
>
> viewer = new TreeViewer(parent, SWT.NONE);
> viewer.setContentProvider(new
> ObservableListTreeContentProvider(EMFObservables.listFactory (Realm.getDefault(),
> DirectoryPackage.Literals.FOLDER__CHILDREN), new
> DirectoryTreeStructureAdvisor()));
> viewer.setLabelProvider(new ConfigDirectoryTreeLabelProvider());
> transaction = CDOSessionManager.getSession().openTransaction();
> transaction.setChangeSubscriptionPolicy(CDOChangeSubscriptio nPolicy.ALL);
>
> Resource resource = transaction.getResource("/config.dir");
> viewer.setInput(resource.getContents().get(0));
>
> // Open an editor double click action
> viewer.addDoubleClickListener(new IDoubleClickListener()
> {
> public void doubleClick(DoubleClickEvent event)
> {
> IStructuredSelection selection
> =(IStructuredSelection)viewer.getSelection();
> Object selected = selection.getFirstElement();
> if(selected instanceof ConfigResource)
> {
> String uri = ((ConfigResource)selected).getURI();
> ....
> So this Viewer is setup with the resource loaded through this
> transaction (transaction3). Then, I go a create the ConfigResource.
> The View automatically detects the change through the
> ObservaleListTreeContentProvider, but when I double click and the viewer
> returns the selected ConfigResource with the wrong Transaction inside
> the selected ConfigResource.
>
> Does that make sense?
> Sorry I made this so confusing.
>
> --Stephen
Re: [CDO] eStore() returns null which results in a NPE [message #424819 is a reply to message #424816] Thu, 06 November 2008 02:12 Go to previous messageGo to next message
Stephen McCants is currently offline Stephen McCantsFriend
Messages: 92
Registered: July 2009
Member
Hi Simon,
Sorry for making such a confusing mess of this, but I think I now understand the problem better.
Let me try to explain it as a sanity check for myself and hopefully I will communicate it well also.

I have CDOModel. It has one Folder Object in it. I have an Eclipse UI View, which loads that loads
the CDOModel through CDOTransaction B and puts it into a TreeViewer (via setInput()). The
TreeViewer uses EMF/Eclipse DataBinding to observe the CDOModel. Here is the databinding line:

treeViewer.setContentProvider(new
ObservableListTreeContentProvider(EMFObservables.listFactory (Realm.getDefault(),
DirectoryPackage.Literals.FOLDER__CHILDREN), new DirectoryTreeStructureAdvisor()));

That all works as expected. The View shows the TreeViewer with the Folder in it.

Now, I open a Wizard which creates a new CDOTransaction (CDOTransaction C) and loads the Folder
object from it. It then creates a new ConfigResource object and makes it a child of the Folder
object.

The Folder object that was loaded from CDOTransaction C calls eNotify() which lets the
ObservableListTreeContentProvider know about the change. I haven't even committed CDOTransaction C
yet! How does the Folder object loaded from CDOTransaction C finds the
ObservableListTreeContentProvider that put an adpater on the Folder object loaded from
CDOTransaction B? Especially, given that I haven't committed the change yet? Maybe because
adapters are also passed through CDO, so CDOTransaction C can see adapters on the Folder object that
were committed by CDOTransaction B.

Now, the ObservableListTreeContentProvider sees a copy of the ConfigResource object under the Folder
object, but that ConfigResource object's CDOStore is CDOTransaction C! It should be CDOTransaction B!

The ObservableListTreeContentProvider updates the TreeViewer with the new ConfigResource. So now
the TreeViewer has a ConfigResource from CDOTransaction C, even though it was originally loaded with
content from CDOTransaction B.

The Wizard then commits and closes CDOTransaction C!

Now, when I double click on the ResourceConfig in the TreeViewer, the TreeViewer returns the
selected object, with is a ResourceConfig which holds on to CDOTransaction C (which is closed).
Then the DoubleClickListener tries to read the content of the ResourceConfig, which asks
CDOTransaction C for help. But, CDOTransaction C is, of course, closed (by the Wizard) and so it
throws a NPE.

So, that is the problem I'm seeing. Maybe the Observable shouldn't be seeing a CDOObject with the
'wrong' CDOTransaction. Maybe it should be smart enough to switch the CDOTransaction out (that
would make it a CDO Databinding, not an EMF Databinding). Maybe there is something I've completely
overlooked, but it is clear that the TreeViewer is getting it's CDOTransaction switched from B to C
underneath it.

Did that make sense?

It is late here, but tomorrow I will work on my 'simple' test case with an EMFObservable in the
middle and see if I can't reproduce the problem.

Thanks again for your help and sorry for the confusion!

--Stephen
Re: [CDO] eStore() returns null which results in a NPE [message #424820 is a reply to message #424819] Thu, 06 November 2008 02:57 Go to previous messageGo to next message
Simon Mc Duff is currently offline Simon Mc DuffFriend
Messages: 596
Registered: July 2009
Senior Member
Stephen McCants wrote:
> Hi Simon,
> Sorry for making such a confusing mess of this, but I think I now
> understand the problem better. Let me try to explain it as a sanity
> check for myself and hopefully I will communicate it well also.
>
> I have CDOModel. It has one Folder Object in it. I have an Eclipse UI
> View, which loads that loads the CDOModel through CDOTransaction B and
> puts it into a TreeViewer (via setInput()). The TreeViewer uses
> EMF/Eclipse DataBinding to observe the CDOModel. Here is the
> databinding line:
>
> treeViewer.setContentProvider(new
> ObservableListTreeContentProvider(EMFObservables.listFactory (Realm.getDefault(),
> DirectoryPackage.Literals.FOLDER__CHILDREN), new
> DirectoryTreeStructureAdvisor()));
>
> That all works as expected. The View shows the TreeViewer with the
> Folder in it.
>
> Now, I open a Wizard which creates a new CDOTransaction (CDOTransaction
> C) and loads the Folder object from it. It then creates a new
> ConfigResource object and makes it a child of the Folder object.
>
How do you loads Folder in transaction C ? Based on what I've seen the
object could get from modelPage.getSelectedFolder() ? Which transaction
is that ?
Please paste/attached all the code related to where folder is being
loaded and modified and committed...

> The Folder object that was loaded from CDOTransaction C calls eNotify()
> which lets the ObservableListTreeContentProvider know about the change.
> I haven't even committed CDOTransaction C yet! How does the Folder
> object loaded from CDOTransaction C finds the
> ObservableListTreeContentProvider that put an adpater on the Folder
> object loaded from CDOTransaction B? Especially, given that I haven't
> committed the change yet?
I think it is how you load folder in transaction C. Folder that you
loaded belong to transaction B. and when you are modified it... it
notify adapters!!

Maybe because adapters are also passed
> through CDO, so CDOTransaction C can see adapters on the Folder object
> that were committed by CDOTransaction B.
>
> Now, the ObservableListTreeContentProvider sees a copy of the
> ConfigResource object under the Folder object, but that ConfigResource
> object's CDOStore is CDOTransaction C! It should be CDOTransaction B!
>
> The ObservableListTreeContentProvider updates the TreeViewer with the
> new ConfigResource. So now the TreeViewer has a ConfigResource from
> CDOTransaction C, even though it was originally loaded with content from
> CDOTransaction B.
>
> The Wizard then commits and closes CDOTransaction C!
>
> Now, when I double click on the ResourceConfig in the TreeViewer, the
> TreeViewer returns the selected object, with is a ResourceConfig which
> holds on to CDOTransaction C (which is closed). Then the
> DoubleClickListener tries to read the content of the ResourceConfig,
> which asks CDOTransaction C for help. But, CDOTransaction C is, of
> course, closed (by the Wizard) and so it throws a NPE.
>
> So, that is the problem I'm seeing. Maybe the Observable shouldn't be
> seeing a CDOObject with the 'wrong' CDOTransaction. Maybe it should be
> smart enough to switch the CDOTransaction out (that would make it a CDO
> Databinding, not an EMF Databinding). Maybe there is something I've
> completely overlooked, but it is clear that the TreeViewer is getting
> it's CDOTransaction switched from B to C underneath it.
>
> Did that make sense?
>
> It is late here, but tomorrow I will work on my 'simple' test case with
> an EMFObservable in the middle and see if I can't reproduce the problem.
>
It is late here as well :-)


> Thanks again for your help and sorry for the confusion!
>
> --Stephen
>
>
>
>
Re: [CDO] eStore() returns null which results in a NPE [message #424846 is a reply to message #424820] Thu, 06 November 2008 17:39 Go to previous messageGo to next message
Stephen McCants is currently offline Stephen McCantsFriend
Messages: 92
Registered: July 2009
Member
Hi Simon,
I have good news. I've managed to reproduce the problem in a 'simple' test case. I'd say the
problem comes down to the way the EMF Databinding is working, particularly the
ObservableListTreeContentProvider. It is caching the values it observes (which happen to be from
the 'wrong' transaction). You'll see I'm doing something similar in my test case with the same bad
results.
Without further ado, here is the failing test case:

// Create a Folder in transaction 1
CDOTransaction transaction1 = session.openTransaction();
Resource resource = transaction1.getOrCreateResource(CONFIG_DIRECTORY_URI);
Folder folder = DirectoryFactory.eINSTANCE.createFolder();
folder.setName("");
resource.getContents().add(folder);
transaction1.commit();
transaction1.close();

// Read the folder from transaction 2, and start observing it
CDOTransaction transaction2 = session.openTransaction();
transaction2.setChangeSubscriptionPolicy(CDOChangeSubscripti onPolicy.ALL);
Resource resourceRead = transaction2.getResource(CONFIG_DIRECTORY_URI);
Folder readFolder = (Folder) resourceRead.getContents().get(0);
System.out.println("readFolder's view is "+readFolder.cdoView().getViewID());
assertThat(readFolder.getName(), is(""));

// Setup an observable (but first create a fake realm, since we don't have a real one from a GUI)
Realm fakeRealm = new Realm(){
@Override
public boolean isCurrent()
{
// This is only for a unit test case, so it is always true
return true;
}
};
IObservableValue observable = EMFObservables.observeValue(fakeRealm, readFolder,
DirectoryPackage.Literals.FOLDER__CHILDREN);
observable.addValueChangeListener(new IValueChangeListener(){
public void handleValueChange(ValueChangeEvent event)
{
Object newValue = event.diff.getNewValue();
if(newValue instanceof ConfigResource)
cachedConfig = (ConfigResource) newValue;
System.out.println("New value's view is "+((CDOObject)cachedConfig).cdoView().getViewID());
}
});

// Now in a third transaction, alter the CDO Model, commit and close
CDOTransaction transaction3 = session.openTransaction();
LLJobConfig jobConfig = LLConfigFactory.eINSTANCE.createLLJobConfig();
Resource llConfigResource = transaction3.getOrCreateResource("/lltest");
llConfigResource.getContents().add(jobConfig);
Resource resourceWrite = transaction3.getResource(CONFIG_DIRECTORY_URI);
Folder writeFolder = (Folder) resourceWrite.getContents().get(0);
ConfigResource configResource = DirectoryFactory.eINSTANCE.createConfigResource();
configResource.setURI("/lltest");
writeFolder.getChildren().add(configResource);
transaction3.commit();
transaction3.close();

// Now we return to the cached value of the changes and read the URI
assertThat(cachedConfig.getURI(), is("/lltest"));

It fails on the last line on the call 'cachedConfig.getURI()' with an NPE, since the cached value is
from transaction3, which is closed.
I don't know what your plans are for allowing use of CDO with JFace/EMF Databinding, but I don't
think this is a simple problem for CDO to solve. My current plan is to work around the problem by
extending the Observer that is caching the value (the listener in the test case and in my real code
a jface.databinding.viewers.ObservableListTreeContentProvider) and making it get the value from the
correct transaction.
Please let me know what you think, and of course, if you have any questions feel free to ask. I'm
glad to help.
As always, thanks for your help! You put me on the right track to unraveling this bug.

Sincerely,
Stephen McCants
Re: [CDO] eStore() returns null which results in a NPE [message #424847 is a reply to message #424846] Thu, 06 November 2008 17:59 Go to previous messageGo to next message
Simon Mc Duff is currently offline Simon Mc DuffFriend
Messages: 596
Registered: July 2009
Senior Member
With your great testcase I think the problem is in CDO.

ChangeSubscription mechanism is given the newvalue from the other
transaction and shouldn't. CDOTransaction.postCommit should
adjustReference and it doesn't happen.

Can you fill a bugzilla for that? It will be fix for tomorrow!

Stephen McCants wrote:
> Hi Simon,
> I have good news. I've managed to reproduce the problem in a
> 'simple' test case. I'd say the problem comes down to the way the EMF
> Databinding is working, particularly the
> ObservableListTreeContentProvider. It is caching the values it observes
> (which happen to be from the 'wrong' transaction). You'll see I'm doing
> something similar in my test case with the same bad results.
> Without further ado, here is the failing test case:
>
> // Create a Folder in transaction 1
> CDOTransaction transaction1 = session.openTransaction();
> Resource resource =
> transaction1.getOrCreateResource(CONFIG_DIRECTORY_URI);
> Folder folder = DirectoryFactory.eINSTANCE.createFolder();
> folder.setName("");
> resource.getContents().add(folder);
> transaction1.commit();
> transaction1.close();
>
> // Read the folder from transaction 2, and start observing it
> CDOTransaction transaction2 = session.openTransaction();
> transaction2.setChangeSubscriptionPolicy(CDOChangeSubscripti onPolicy.ALL);
>
> Resource resourceRead = transaction2.getResource(CONFIG_DIRECTORY_URI);
> Folder readFolder = (Folder) resourceRead.getContents().get(0);
> System.out.println("readFolder's view is
> "+readFolder.cdoView().getViewID());
> assertThat(readFolder.getName(), is(""));
>
> // Setup an observable (but first create a fake realm, since we
> don't have a real one from a GUI)
> Realm fakeRealm = new Realm(){
> @Override
> public boolean isCurrent()
> {
> // This is only for a unit test case, so it is always true
> return true;
> }
> };
> IObservableValue observable = EMFObservables.observeValue(fakeRealm,
> readFolder, DirectoryPackage.Literals.FOLDER__CHILDREN);
> observable.addValueChangeListener(new IValueChangeListener(){
> public void handleValueChange(ValueChangeEvent event)
> {
> Object newValue = event.diff.getNewValue();
> if(newValue instanceof ConfigResource)
> cachedConfig = (ConfigResource) newValue;
> System.out.println("New value's view is
> "+((CDOObject)cachedConfig).cdoView().getViewID());
> }
> });
>
> // Now in a third transaction, alter the CDO Model, commit and close
> CDOTransaction transaction3 = session.openTransaction();
> LLJobConfig jobConfig = LLConfigFactory.eINSTANCE.createLLJobConfig();
> Resource llConfigResource =
> transaction3.getOrCreateResource("/lltest");
> llConfigResource.getContents().add(jobConfig);
> Resource resourceWrite =
> transaction3.getResource(CONFIG_DIRECTORY_URI);
> Folder writeFolder = (Folder) resourceWrite.getContents().get(0);
> ConfigResource configResource =
> DirectoryFactory.eINSTANCE.createConfigResource();
> configResource.setURI("/lltest");
> writeFolder.getChildren().add(configResource);
> transaction3.commit();
> transaction3.close();
>
> // Now we return to the cached value of the changes and read the URI
> assertThat(cachedConfig.getURI(), is("/lltest"));
>
> It fails on the last line on the call 'cachedConfig.getURI()' with an
> NPE, since the cached value is from transaction3, which is closed.
> I don't know what your plans are for allowing use of CDO with
> JFace/EMF Databinding, but I don't think this is a simple problem for
> CDO to solve. My current plan is to work around the problem by
> extending the Observer that is caching the value (the listener in the
> test case and in my real code a
> jface.databinding.viewers.ObservableListTreeContentProvider) and making
> it get the value from the correct transaction.
> Please let me know what you think, and of course, if you have any
> questions feel free to ask. I'm glad to help.
> As always, thanks for your help! You put me on the right track to
> unraveling this bug.
>
> Sincerely,
> Stephen McCants
Re: [CDO] eStore() returns null which results in a NPE [message #424849 is a reply to message #424847] Thu, 06 November 2008 18:32 Go to previous message
Stephen McCants is currently offline Stephen McCantsFriend
Messages: 92
Registered: July 2009
Member
Hi Simon,
I open https://bugs.eclipse.org/bugs/show_bug.cgi?id=254489 for this problem.
Thanks again for your patience and your help!

--Stephen

Simon McDuff wrote:
> With your great testcase I think the problem is in CDO.
>
> ChangeSubscription mechanism is given the newvalue from the other
> transaction and shouldn't. CDOTransaction.postCommit should
> adjustReference and it doesn't happen.
>
> Can you fill a bugzilla for that? It will be fix for tomorrow!
>
> Stephen McCants wrote:
>> Hi Simon,
>> I have good news. I've managed to reproduce the problem in a
>> 'simple' test case. I'd say the problem comes down to the way the EMF
>> Databinding is working, particularly the
>> ObservableListTreeContentProvider. It is caching the values it
>> observes (which happen to be from the 'wrong' transaction). You'll
>> see I'm doing something similar in my test case with the same bad
>> results.
>> Without further ado, here is the failing test case:
>>
>> // Create a Folder in transaction 1
>> CDOTransaction transaction1 = session.openTransaction();
>> Resource resource =
>> transaction1.getOrCreateResource(CONFIG_DIRECTORY_URI);
>> Folder folder = DirectoryFactory.eINSTANCE.createFolder();
>> folder.setName("");
>> resource.getContents().add(folder);
>> transaction1.commit();
>> transaction1.close();
>> // Read the folder from transaction 2, and start observing it
>> CDOTransaction transaction2 = session.openTransaction();
>>
>> transaction2.setChangeSubscriptionPolicy(CDOChangeSubscripti onPolicy.ALL);
>>
>> Resource resourceRead =
>> transaction2.getResource(CONFIG_DIRECTORY_URI);
>> Folder readFolder = (Folder) resourceRead.getContents().get(0);
>> System.out.println("readFolder's view is
>> "+readFolder.cdoView().getViewID());
>> assertThat(readFolder.getName(), is(""));
>> // Setup an observable (but first create a fake realm,
>> since we don't have a real one from a GUI) Realm fakeRealm = new
>> Realm(){
>> @Override
>> public boolean isCurrent()
>> {
>> // This is only for a unit test case, so it is always true
>> return true;
>> }
>> };
>> IObservableValue observable =
>> EMFObservables.observeValue(fakeRealm, readFolder,
>> DirectoryPackage.Literals.FOLDER__CHILDREN);
>> observable.addValueChangeListener(new IValueChangeListener(){
>> public void handleValueChange(ValueChangeEvent event)
>> {
>> Object newValue = event.diff.getNewValue();
>> if(newValue instanceof ConfigResource)
>> cachedConfig = (ConfigResource) newValue;
>> System.out.println("New value's view is
>> "+((CDOObject)cachedConfig).cdoView().getViewID());
>> }
>> });
>> // Now in a third transaction, alter the CDO Model, commit
>> and close
>> CDOTransaction transaction3 = session.openTransaction();
>> LLJobConfig jobConfig =
>> LLConfigFactory.eINSTANCE.createLLJobConfig();
>> Resource llConfigResource =
>> transaction3.getOrCreateResource("/lltest");
>> llConfigResource.getContents().add(jobConfig);
>> Resource resourceWrite =
>> transaction3.getResource(CONFIG_DIRECTORY_URI);
>> Folder writeFolder = (Folder) resourceWrite.getContents().get(0);
>> ConfigResource configResource =
>> DirectoryFactory.eINSTANCE.createConfigResource();
>> configResource.setURI("/lltest");
>> writeFolder.getChildren().add(configResource);
>> transaction3.commit();
>> transaction3.close();
>> // Now we return to the cached value of the changes and
>> read the URI
>> assertThat(cachedConfig.getURI(), is("/lltest"));
>>
>> It fails on the last line on the call 'cachedConfig.getURI()' with an
>> NPE, since the cached value is from transaction3, which is closed.
>> I don't know what your plans are for allowing use of CDO with
>> JFace/EMF Databinding, but I don't think this is a simple problem for
>> CDO to solve. My current plan is to work around the problem by
>> extending the Observer that is caching the value (the listener in the
>> test case and in my real code a
>> jface.databinding.viewers.ObservableListTreeContentProvider) and
>> making it get the value from the correct transaction.
>> Please let me know what you think, and of course, if you have any
>> questions feel free to ask. I'm glad to help.
>> As always, thanks for your help! You put me on the right track to
>> unraveling this bug.
>>
>> Sincerely,
>> Stephen McCants
Previous Topic:Invalid thread access
Next Topic:[EMF] copy of referenced object between models
Goto Forum:
  


Current Time: Sat Apr 27 01:19:32 GMT 2024

Powered by FUDForum. Page generated in 0.04794 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top