Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » Problem 2: eInverseAdd() null pointer exceptions in 1.1
Problem 2: eInverseAdd() null pointer exceptions in 1.1 [message #377699] Thu, 05 June 2003 15:37 Go to next message
Henrietta Slack is currently offline Henrietta SlackFriend
Messages: 63
Registered: July 2009
Member
I've just upgraded to the latest EMF 1.1, recreated my models and run
straight into null pointer exceptions. It happens in the call to
eDynamicInverseAdd() after its failed to get its settings (sorry I've lost
the stack trace for the moment).

I've gone back to 1.02 for now where I'm working quite happily; do you
think this is likely to be a bug in 1.1?

Thanks,
Henrietta

P.S. Any idea why AClass gets a basicAdd() and BClass gets
eDynamicInverseAdd()? That looks wrong to me. I've boiled this example
out of a lot of code but I'm certain the classes and relationships are
defined in the same way.


/**
* @model
*/
public interface ContainerClass extends EObject {
/**
* @model type="AClass" opposite="containerClass"
*/
EList getAClasses();

/**
* @model type="BClass" opposite="containerClass"
*/
EList getBClasses();
}

/**
* @model
*/
public interface AClass extends EObject {
/**
* @model opposite="aClasses"
*/
LillyModel getLillyModel();
}

/**
* @model
*/
public interface BClass extends EObject {
/**
* @model opposite="bClasses"
*/
LillyModel getLillyModel();
}

--------< Gen'd ContainerClass implementation >----------

/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public NotificationChain eInverseAdd(InternalEObject otherEnd, int
featureID, Class baseClass, NotificationChain msgs)
{
if (featureID >= 0)
{
switch (eDerivedStructuralFeatureID(featureID, baseClass))
{
case MyPackage.CONTAINER_CLASS__A_CLASSES :
return ((InternalEList) getAClasses()).basicAdd(otherEnd, msgs);
default :
return eDynamicInverseAdd(otherEnd, featureID, baseClass, msgs);
}
}
if (eContainer != null)
msgs = eBasicRemoveFromContainer(msgs);
return eBasicSetContainer(otherEnd, featureID, msgs);
}
Re: Problem 2: eInverseAdd() null pointer exceptions in 1.1 [message #377803 is a reply to message #377699] Mon, 09 June 2003 01:05 Go to previous messageGo to next message
Frank Budinsky is currently offline Frank BudinskyFriend
Messages: 478
Registered: July 2009
Senior Member
Henrietta,

The call to eDynamicInverseAdd() indicates a codegen problem. Did you regen you're
model in 1.1?

The three model classes you show don't match. If they're supposed to work together
then ContainerClass would need to be named LillyModel and the opposite tags on
getAClasses() and getBClasses() would need to say opposite="lillyModel".

Frank.


Henrietta wrote:

> I've just upgraded to the latest EMF 1.1, recreated my models and run
> straight into null pointer exceptions. It happens in the call to
> eDynamicInverseAdd() after its failed to get its settings (sorry I've lost
> the stack trace for the moment).
>
> I've gone back to 1.02 for now where I'm working quite happily; do you
> think this is likely to be a bug in 1.1?
>
> Thanks,
> Henrietta
>
> P.S. Any idea why AClass gets a basicAdd() and BClass gets
> eDynamicInverseAdd()? That looks wrong to me. I've boiled this example
> out of a lot of code but I'm certain the classes and relationships are
> defined in the same way.
>
> /**
> * @model
> */
> public interface ContainerClass extends EObject {
> /**
> * @model type="AClass" opposite="containerClass"
> */
> EList getAClasses();
>
> /**
> * @model type="BClass" opposite="containerClass"
> */
> EList getBClasses();
> }
>
> /**
> * @model
> */
> public interface AClass extends EObject {
> /**
> * @model opposite="aClasses"
> */
> LillyModel getLillyModel();
> }
>
> /**
> * @model
> */
> public interface BClass extends EObject {
> /**
> * @model opposite="bClasses"
> */
> LillyModel getLillyModel();
> }
>
> --------< Gen'd ContainerClass implementation >----------
>
> /**
> * <!-- begin-user-doc -->
> * <!-- end-user-doc -->
> * @generated
> */
> public NotificationChain eInverseAdd(InternalEObject otherEnd, int
> featureID, Class baseClass, NotificationChain msgs)
> {
> if (featureID >= 0)
> {
> switch (eDerivedStructuralFeatureID(featureID, baseClass))
> {
> case MyPackage.CONTAINER_CLASS__A_CLASSES :
> return ((InternalEList) getAClasses()).basicAdd(otherEnd, msgs);
> default :
> return eDynamicInverseAdd(otherEnd, featureID, baseClass, msgs);
> }
> }
> if (eContainer != null)
> msgs = eBasicRemoveFromContainer(msgs);
> return eBasicSetContainer(otherEnd, featureID, msgs);
> }
Re: Problem 2: eInverseAdd() null pointer exceptions in 1.1 [message #377822 is a reply to message #377803] Mon, 09 June 2003 23:18 Go to previous messageGo to next message
Henrietta Slack is currently offline Henrietta SlackFriend
Messages: 63
Registered: July 2009
Member
I beg your pardon, Frank, that\'s just my manual find and replace gone
awry. I did do a complete rebuild (removed all model and autogen\'d files
and created a new model) in 1.1. It looks like a codegen problem to me
and I should have written:

/**
* @model
*/
public interface AClass extends EObject {
/**
* @model opposite=\"aClasses\"
*/
ContainerClass getContainerClass();
}

/**
* @model
*/
public interface BClass extends EObject {
/**
* @model opposite=\"bClasses\"
*/
ContainerClass getContainerClass();
}


Frank Budinsky wrote:

> Henrietta,

> The call to eDynamicInverseAdd() indicates a codegen problem. Did you regen
you\'re
> model in 1.1?

> The three model classes you show don\'t match. If they\'re supposed to work
together
> then ContainerClass would need to be named LillyModel and the opposite tags
on
> getAClasses() and getBClasses() would need to say opposite=\"lillyModel\".

> Frank.


> Henrietta wrote:

> > I\'ve just upgraded to the latest EMF 1.1, recreated my models and run
> > straight into null pointer exceptions. It happens in the call to
> > eDynamicInverseAdd() after its failed to get its settings (sorry I\'ve lost
> > the stack trace for the moment).
> >
> > I\'ve gone back to 1.02 for now where I\'m working quite happily; do you
> > think this is likely to be a bug in 1.1?
> >
> > Thanks,
> > Henrietta
> >
> > P.S. Any idea why AClass gets a basicAdd() and BClass gets
> > eDynamicInverseAdd()? That looks wrong to me. I\'ve boiled this example
> > out of a lot of code but I\'m certain the classes and relationships are
> > defined in the same way.
> >
> > /**
> > * @model
> > */
> > public interface ContainerClass extends EObject {
> > /**
> > * @model type=\"AClass\" opposite=\"containerClass\"
> > */
> > EList getAClasses();
> >
> > /**
> > * @model type=\"BClass\" opposite=\"containerClass\"
> > */
> > EList getBClasses();
> > }
> >
> > /**
> > * @model
> > */
> > public interface AClass extends EObject {
> > /**
> > * @model opposite=\"aClasses\"
> > */
> > LillyModel getLillyModel();
> > }
> >
> > /**
> > * @model
> > */
> > public interface BClass extends EObject {
> > /**
> > * @model opposite=\"bClasses\"
> > */
> > LillyModel getLillyModel();
> > }
> >
> > --------< Gen\'d ContainerClass implementation >----------
> >
> > /**
> > * <!-- begin-user-doc -->
> > * <!-- end-user-doc -->
> > * @generated
> > */
> > public NotificationChain eInverseAdd(InternalEObject otherEnd, int
> > featureID, Class baseClass, NotificationChain msgs)
> > {
> > if (featureID >= 0)
> > {
> > switch (eDerivedStructuralFeatureID(featureID, baseClass))
> > {
> > case MyPackage.CONTAINER_CLASS__A_CLASSES :
> > return ((InternalEList) getAClasses()).basicAdd(otherEnd,
msgs);
> > default :
> > return eDynamicInverseAdd(otherEnd, featureID, baseClass,
msgs);
> > }
> > }
> > if (eContainer != null)
> > msgs = eBasicRemoveFromContainer(msgs);
> > return eBasicSetContainer(otherEnd, featureID, msgs);
> > }
Re: Problem 2: eInverseAdd() null pointer exceptions in 1.1 [message #377832 is a reply to message #377822] Tue, 10 June 2003 13:37 Go to previous messageGo to next message
Frank Budinsky is currently offline Frank BudinskyFriend
Messages: 478
Registered: July 2009
Senior Member
Henrietta,

Is this still a problem. If so, could you please provide all the applicable classes
once again and explain exactly what isn't working.

Thanks,
Frank.


Henrietta wrote:

> I beg your pardon, Frank, that\'s just my manual find and replace gone
> awry. I did do a complete rebuild (removed all model and autogen\'d files
> and created a new model) in 1.1. It looks like a codegen problem to me
> and I should have written:
>
> /**
> * @model
> */
> public interface AClass extends EObject {
> /**
> * @model opposite=\"aClasses\"
> */
> ContainerClass getContainerClass();
> }
>
> /**
> * @model
> */
> public interface BClass extends EObject {
> /**
> * @model opposite=\"bClasses\"
> */
> ContainerClass getContainerClass();
> }
>
> Frank Budinsky wrote:
>
> > Henrietta,
>
> > The call to eDynamicInverseAdd() indicates a codegen problem. Did you regen
> you\'re
> > model in 1.1?
>
> > The three model classes you show don\'t match. If they\'re supposed to work
> together
> > then ContainerClass would need to be named LillyModel and the opposite tags
> on
> > getAClasses() and getBClasses() would need to say opposite=\"lillyModel\".
>
> > Frank.
>
> > Henrietta wrote:
>
> > > I\'ve just upgraded to the latest EMF 1.1, recreated my models and run
> > > straight into null pointer exceptions. It happens in the call to
> > > eDynamicInverseAdd() after its failed to get its settings (sorry I\'ve lost
> > > the stack trace for the moment).
> > >
> > > I\'ve gone back to 1.02 for now where I\'m working quite happily; do you
> > > think this is likely to be a bug in 1.1?
> > >
> > > Thanks,
> > > Henrietta
> > >
> > > P.S. Any idea why AClass gets a basicAdd() and BClass gets
> > > eDynamicInverseAdd()? That looks wrong to me. I\'ve boiled this example
> > > out of a lot of code but I\'m certain the classes and relationships are
> > > defined in the same way.
> > >
> > > /**
> > > * @model
> > > */
> > > public interface ContainerClass extends EObject {
> > > /**
> > > * @model type=\"AClass\" opposite=\"containerClass\"
> > > */
> > > EList getAClasses();
> > >
> > > /**
> > > * @model type=\"BClass\" opposite=\"containerClass\"
> > > */
> > > EList getBClasses();
> > > }
> > >
> > > /**
> > > * @model
> > > */
> > > public interface AClass extends EObject {
> > > /**
> > > * @model opposite=\"aClasses\"
> > > */
> > > LillyModel getLillyModel();
> > > }
> > >
> > > /**
> > > * @model
> > > */
> > > public interface BClass extends EObject {
> > > /**
> > > * @model opposite=\"bClasses\"
> > > */
> > > LillyModel getLillyModel();
> > > }
> > >
> > > --------< Gen\'d ContainerClass implementation >----------
> > >
> > > /**
> > > * <!-- begin-user-doc -->
> > > * <!-- end-user-doc -->
> > > * @generated
> > > */
> > > public NotificationChain eInverseAdd(InternalEObject otherEnd, int
> > > featureID, Class baseClass, NotificationChain msgs)
> > > {
> > > if (featureID >= 0)
> > > {
> > > switch (eDerivedStructuralFeatureID(featureID, baseClass))
> > > {
> > > case MyPackage.CONTAINER_CLASS__A_CLASSES :
> > > return ((InternalEList) getAClasses()).basicAdd(otherEnd,
> msgs);
> > > default :
> > > return eDynamicInverseAdd(otherEnd, featureID, baseClass,
> msgs);
> > > }
> > > }
> > > if (eContainer != null)
> > > msgs = eBasicRemoveFromContainer(msgs);
> > > return eBasicSetContainer(otherEnd, featureID, msgs);
> > > }
Re: Problem 2: eInverseAdd() null pointer exceptions in 1.1 [message #377836 is a reply to message #377832] Tue, 10 June 2003 15:37 Go to previous messageGo to next message
Henrietta Slack is currently offline Henrietta SlackFriend
Messages: 63
Registered: July 2009
Member
I tried incorporating the change required for my first problem and
upgraded to 1.1 again with no success. The problem _seems_ to be in the
eInverseAdd() generated in ContainerClassImpl.java. It _looks as though_
a case statement is missing for CONTAINER_CLASS_B_CLASSES and it blows up
in the eDynamicInverseAdd() with a NullPointerException. (Shouldn't it be
doing a basicAdd() on the BClass list?). I've flipped backwards and
forwards between 1.02 and 1.1 three times now using the same code base and
regenerated the models from scratch and it's always consistent - 1.02
works, 1.1 falls over. Here's the code:

/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public NotificationChain eInverseAdd(InternalEObject otherEnd, int
featureID, Class baseClass, NotificationChain msgs)
{
if (featureID >= 0)
{
switch (eDerivedStructuralFeatureID(featureID, baseClass))
{
case ModelPackage.CONTAINER_CLASS_A_CLASSES :
return ((InternalEList) getAClasses()).basicAdd(otherEnd, msgs);
default :
return eDynamicInverseAdd(otherEnd, featureID, baseClass, msgs);
}
}
if (eContainer != null)
msgs = eBasicRemoveFromContainer(msgs);
return eBasicSetContainer(otherEnd, featureID, msgs);
}



Although it looks wrong (to me) it is exactly the same code that 1.0.2
generates and that works (well, it doesn't give me a
NullPointerException). This goes on to call eDynamicInverseAdd() in
EObjectImpl.java which picks up the null from eSettings():

public NotificationChain eDynamicInverseAdd(InternalEObject otherEnd, int
featureID, Class inverseClass, NotificationChain msgs)
{
EStructuralFeature.Internal feature =
(EStructuralFeature.Internal)eClass().getEAllStructuralFeatu res().get(featureID);
return
feature.getSettingDelegate().dynamicInverseAdd
(this, eSettings(), featureID - eStaticFeatureCount(), otherEnd,
msgs);
}



And then on to dynamicInverseAdd() in InternalSettingDelegateMany (an
inner class of EStructuralFeatureImpl):

public NotificationChain dynamicInverseAdd
(InternalEObject owner, EStructuralFeature.Internal.DynamicValueHolder
settings, int index, InternalEObject otherEnd, NotificationChain
notifications)
{
// -------- So we fail with settings as null here ------------
Object setting = settings.dynamicGet(index);
if (setting == null)
{
settings.dynamicSet(index, setting = createDynamicSetting(owner));
}
return ((InternalEList)setting).basicAdd(otherEnd, notifications);
}




To reiterate, here's what the three interfaces involved look like:


/**
* @model
*/
public interface ContainerClass extends EObject {
/**
* @model type="AClass" opposite="containerClass"
*/
EList getAClasses();

/**
* @model type="BClass" opposite="containerClass"
*/
EList getBClasses();
}

/**
* @model
*/
public interface AClass extends EObject {
/**
* @model opposite="aClasses"
*/
ContainerClass getContainerClass();
}

/**
* @model
*/
public interface BClass extends EObject {
/**
* @model opposite="bClasses"
*/
ContainerClass getContainerClass();
}

Let me know if you need anything more.
Thanks,
Henrietta

Frank Budinsky wrote:

> Henrietta,

> Is this still a problem. If so, could you please provide all the applicable
classes
> once again and explain exactly what isn't working.

> Thanks,
> Frank.


> Henrietta wrote:

> > I beg your pardon, Frank, that\'s just my manual find and replace gone
> > awry. I did do a complete rebuild (removed all model and autogen\'d files
> > and created a new model) in 1.1. It looks like a codegen problem to me
> > and I should have written:
> >
> > /**
> > * @model
> > */
> > public interface AClass extends EObject {
> > /**
> > * @model opposite=\"aClasses\"
> > */
> > ContainerClass getContainerClass();
> > }
> >
> > /**
> > * @model
> > */
> > public interface BClass extends EObject {
> > /**
> > * @model opposite=\"bClasses\"
> > */
> > ContainerClass getContainerClass();
> > }
> >
> > Frank Budinsky wrote:
> >
> > > Henrietta,
> >
> > > The call to eDynamicInverseAdd() indicates a codegen problem. Did you
regen
> > you\'re
> > > model in 1.1?
> >
> > > The three model classes you show don\'t match. If they\'re supposed to
work
> > together
> > > then ContainerClass would need to be named LillyModel and the opposite
tags
> > on
> > > getAClasses() and getBClasses() would need to say
opposite=\"lillyModel\".
> >
> > > Frank.
> >
> > > Henrietta wrote:
> >
> > > > I\'ve just upgraded to the latest EMF 1.1, recreated my models and run
> > > > straight into null pointer exceptions. It happens in the call to
> > > > eDynamicInverseAdd() after its failed to get its settings (sorry I\'ve
lost
> > > > the stack trace for the moment).
> > > >
> > > > I\'ve gone back to 1.02 for now where I\'m working quite happily; do
you
> > > > think this is likely to be a bug in 1.1?
> > > >
> > > > Thanks,
> > > > Henrietta
> > > >
> > > > P.S. Any idea why AClass gets a basicAdd() and BClass gets
> > > > eDynamicInverseAdd()? That looks wrong to me. I\'ve boiled this
example
> > > > out of a lot of code but I\'m certain the classes and relationships are
> > > > defined in the same way.
> > > >
> > > > /**
> > > > * @model
> > > > */
> > > > public interface ContainerClass extends EObject {
> > > > /**
> > > > * @model type=\"AClass\" opposite=\"containerClass\"
> > > > */
> > > > EList getAClasses();
> > > >
> > > > /**
> > > > * @model type=\"BClass\" opposite=\"containerClass\"
> > > > */
> > > > EList getBClasses();
> > > > }
> > > >
> > > > /**
> > > > * @model
> > > > */
> > > > public interface AClass extends EObject {
> > > > /**
> > > > * @model opposite=\"aClasses\"
> > > > */
> > > > LillyModel getLillyModel();
> > > > }
> > > >
> > > > /**
> > > > * @model
> > > > */
> > > > public interface BClass extends EObject {
> > > > /**
> > > > * @model opposite=\"bClasses\"
> > > > */
> > > > LillyModel getLillyModel();
> > > > }
> > > >
> > > > --------< Gen\'d ContainerClass implementation >----------
> > > >
> > > > /**
> > > > * <!-- begin-user-doc -->
> > > > * <!-- end-user-doc -->
> > > > * @generated
> > > > */
> > > > public NotificationChain eInverseAdd(InternalEObject otherEnd, int
> > > > featureID, Class baseClass, NotificationChain msgs)
> > > > {
> > > > if (featureID >= 0)
> > > > {
> > > > switch (eDerivedStructuralFeatureID(featureID, baseClass))
> > > > {
> > > > case MyPackage.CONTAINER_CLASS__A_CLASSES :
> > > > return ((InternalEList)
getAClasses()).basicAdd(otherEnd,
> > msgs);
> > > > default :
> > > > return eDynamicInverseAdd(otherEnd, featureID,
baseClass,
> > msgs);
> > > > }
> > > > }
> > > > if (eContainer != null)
> > > > msgs = eBasicRemoveFromContainer(msgs);
> > > > return eBasicSetContainer(otherEnd, featureID, msgs);
> > > > }
Re: Problem 2: eInverseAdd() null pointer exceptions in 1.1 [message #377838 is a reply to message #377832] Tue, 10 June 2003 16:19 Go to previous messageGo to next message
Henrietta Slack is currently offline Henrietta SlackFriend
Messages: 63
Registered: July 2009
Member
The generated method eInverseRemove() gets it right and does a
basicRemove() on the BClass list. Surely this should be symmetric with
eInverseAdd() and it's the missing case statement that's causing my
problem? I thought so, and when I add the case statement manually ...

case ModelPackage.CONTAINER_CLASS__B_CLASSES :
return ((InternalEList) getBClasses()).basicAdd(otherEnd, msgs);

... to my eInverseAdd() it fixes the problem (until I regenerate). So at
least I have a work around for the short term. Now why did it _appear_ to
work in 1.02 ...


/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public NotificationChain eInverseRemove(InternalEObject otherEnd, int
featureID, Class baseClass, NotificationChain msgs)
{
if (featureID >= 0)
{
switch (eDerivedStructuralFeatureID(featureID, baseClass))
{
case ModelPackage.CONTAINER_CLASS__A_CLASSES:
return ((InternalEList)getAClasses()).basicRemove(otherEnd, msgs);
case ModelPackage.CONTAINER_CLASS__B_CLASSES:
return ((InternalEList)getBClasses()).basicRemove(otherEnd, msgs);
default:
return eDynamicInverseRemove(otherEnd, featureID, baseClass, msgs);
}
}
return eBasicSetContainer(null, featureID, msgs);
}
Re: Problem 2: eInverseAdd() null pointer exceptions in 1.1 [message #377839 is a reply to message #377836] Tue, 10 June 2003 16:28 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33137
Registered: July 2009
Senior Member
--------------A7868DDD177D694C355E129F
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Henrietta,

When I generate from your examples below I get this implemention with a case that handles bClasses:

public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, Class
baseClass, NotificationChain msgs) {
if (featureID >= 0) {
switch (eDerivedStructuralFeatureID(featureID, baseClass)) {
case Sample1Package.CONTAINER_CLASS__ACLASSES:
return ((InternalEList)getAClasses()).basicAdd(otherEnd, msgs);
case Sample1Package.CONTAINER_CLASS__BCLASSES:
return ((InternalEList)getBClasses()).basicAdd(otherEnd, msgs);
default:
return eDynamicInverseAdd(otherEnd, featureID, baseClass, msgs);
}
}
if (eContainer != null)
msgs = eBasicRemoveFromContainer(msgs);
return eBasicSetContainer(otherEnd, featureID, msgs);
}

I'm quite confused about why you would see something different that this. There must be something
that you are doing that we aren't, or vice versa, but I haven't a clue. Perhaps you should attach
the exact input files you are using...


Henrietta wrote:

> I tried incorporating the change required for my first problem and
> upgraded to 1.1 again with no success. The problem _seems_ to be in the
> eInverseAdd() generated in ContainerClassImpl.java. It _looks as though_
> a case statement is missing for CONTAINER_CLASS_B_CLASSES and it blows up
> in the eDynamicInverseAdd() with a NullPointerException. (Shouldn't it be
> doing a basicAdd() on the BClass list?). I've flipped backwards and
> forwards between 1.02 and 1.1 three times now using the same code base and
> regenerated the models from scratch and it's always consistent - 1.02
> works, 1.1 falls over. Here's the code:
>
> /**
> * <!-- begin-user-doc -->
> * <!-- end-user-doc -->
> * @generated
> */
> public NotificationChain eInverseAdd(InternalEObject otherEnd, int
> featureID, Class baseClass, NotificationChain msgs)
> {
> if (featureID >= 0)
> {
> switch (eDerivedStructuralFeatureID(featureID, baseClass))
> {
> case ModelPackage.CONTAINER_CLASS_A_CLASSES :
> return ((InternalEList) getAClasses()).basicAdd(otherEnd, msgs);
> default :
> return eDynamicInverseAdd(otherEnd, featureID, baseClass, msgs);
> }
> }
> if (eContainer != null)
> msgs = eBasicRemoveFromContainer(msgs);
> return eBasicSetContainer(otherEnd, featureID, msgs);
> }
>
> Although it looks wrong (to me) it is exactly the same code that 1.0.2
> generates and that works (well, it doesn't give me a
> NullPointerException). This goes on to call eDynamicInverseAdd() in
> EObjectImpl.java which picks up the null from eSettings():
>
> public NotificationChain eDynamicInverseAdd(InternalEObject otherEnd, int
> featureID, Class inverseClass, NotificationChain msgs)
> {
> EStructuralFeature.Internal feature =
> (EStructuralFeature.Internal)eClass().getEAllStructuralFeatu res().get(featureID);
> return
> feature.getSettingDelegate().dynamicInverseAdd
> (this, eSettings(), featureID - eStaticFeatureCount(), otherEnd,
> msgs);
> }
>
> And then on to dynamicInverseAdd() in InternalSettingDelegateMany (an
> inner class of EStructuralFeatureImpl):
>
> public NotificationChain dynamicInverseAdd
> (InternalEObject owner, EStructuralFeature.Internal.DynamicValueHolder
> settings, int index, InternalEObject otherEnd, NotificationChain
> notifications)
> {
> // -------- So we fail with settings as null here ------------
> Object setting = settings.dynamicGet(index);
> if (setting == null)
> {
> settings.dynamicSet(index, setting = createDynamicSetting(owner));
> }
> return ((InternalEList)setting).basicAdd(otherEnd, notifications);
> }
>
> To reiterate, here's what the three interfaces involved look like:
>
> /**
> * @model
> */
> public interface ContainerClass extends EObject {
> /**
> * @model type="AClass" opposite="containerClass"
> */
> EList getAClasses();
>
> /**
> * @model type="BClass" opposite="containerClass"
> */
> EList getBClasses();
> }
>
> /**
> * @model
> */
> public interface AClass extends EObject {
> /**
> * @model opposite="aClasses"
> */
> ContainerClass getContainerClass();
> }
>
> /**
> * @model
> */
> public interface BClass extends EObject {
> /**
> * @model opposite="bClasses"
> */
> ContainerClass getContainerClass();
> }
>
> Let me know if you need anything more.
> Thanks,
> Henrietta
>
> Frank Budinsky wrote:
>
> > Henrietta,
>
> > Is this still a problem. If so, could you please provide all the applicable
> classes
> > once again and explain exactly what isn't working.
>
> > Thanks,
> > Frank.
>
> > Henrietta wrote:
>
> > > I beg your pardon, Frank, that\'s just my manual find and replace gone
> > > awry. I did do a complete rebuild (removed all model and autogen\'d files
> > > and created a new model) in 1.1. It looks like a codegen problem to me
> > > and I should have written:
> > >
> > > /**
> > > * @model
> > > */
> > > public interface AClass extends EObject {
> > > /**
> > > * @model opposite=\"aClasses\"
> > > */
> > > ContainerClass getContainerClass();
> > > }
> > >
> > > /**
> > > * @model
> > > */
> > > public interface BClass extends EObject {
> > > /**
> > > * @model opposite=\"bClasses\"
> > > */
> > > ContainerClass getContainerClass();
> > > }
> > >
> > > Frank Budinsky wrote:
> > >
> > > > Henrietta,
> > >
> > > > The call to eDynamicInverseAdd() indicates a codegen problem. Did you
> regen
> > > you\'re
> > > > model in 1.1?
> > >
> > > > The three model classes you show don\'t match. If they\'re supposed to
> work
> > > together
> > > > then ContainerClass would need to be named LillyModel and the opposite
> tags
> > > on
> > > > getAClasses() and getBClasses() would need to say
> opposite=\"lillyModel\".
> > >
> > > > Frank.
> > >
> > > > Henrietta wrote:
> > >
> > > > > I\'ve just upgraded to the latest EMF 1.1, recreated my models and run
> > > > > straight into null pointer exceptions. It happens in the call to
> > > > > eDynamicInverseAdd() after its failed to get its settings (sorry I\'ve
> lost
> > > > > the stack trace for the moment).
> > > > >
> > > > > I\'ve gone back to 1.02 for now where I\'m working quite happily; do
> you
> > > > > think this is likely to be a bug in 1.1?
> > > > >
> > > > > Thanks,
> > > > > Henrietta
> > > > >
> > > > > P.S. Any idea why AClass gets a basicAdd() and BClass gets
> > > > > eDynamicInverseAdd()? That looks wrong to me. I\'ve boiled this
> example
> > > > > out of a lot of code but I\'m certain the classes and relationships are
> > > > > defined in the same way.
> > > > >
> > > > > /**
> > > > > * @model
> > > > > */
> > > > > public interface ContainerClass extends EObject {
> > > > > /**
> > > > > * @model type=\"AClass\" opposite=\"containerClass\"
> > > > > */
> > > > > EList getAClasses();
> > > > >
> > > > > /**
> > > > > * @model type=\"BClass\" opposite=\"containerClass\"
> > > > > */
> > > > > EList getBClasses();
> > > > > }
> > > > >
> > > > > /**
> > > > > * @model
> > > > > */
> > > > > public interface AClass extends EObject {
> > > > > /**
> > > > > * @model opposite=\"aClasses\"
> > > > > */
> > > > > LillyModel getLillyModel();
> > > > > }
> > > > >
> > > > > /**
> > > > > * @model
> > > > > */
> > > > > public interface BClass extends EObject {
> > > > > /**
> > > > > * @model opposite=\"bClasses\"
> > > > > */
> > > > > LillyModel getLillyModel();
> > > > > }
> > > > >
> > > > > --------< Gen\'d ContainerClass implementation >----------
> > > > >
> > > > > /**
> > > > > * <!-- begin-user-doc -->
> > > > > * <!-- end-user-doc -->
> > > > > * @generated
> > > > > */
> > > > > public NotificationChain eInverseAdd(InternalEObject otherEnd, int
> > > > > featureID, Class baseClass, NotificationChain msgs)
> > > > > {
> > > > > if (featureID >= 0)
> > > > > {
> > > > > switch (eDerivedStructuralFeatureID(featureID, baseClass))
> > > > > {
> > > > > case MyPackage.CONTAINER_CLASS__A_CLASSES :
> > > > > return ((InternalEList)
> getAClasses()).basicAdd(otherEnd,
> > > msgs);
> > > > > default :
> > > > > return eDynamicInverseAdd(otherEnd, featureID,
> baseClass,
> > > msgs);
> > > > > }
> > > > > }
> > > > > if (eContainer != null)
> > > > > msgs = eBasicRemoveFromContainer(msgs);
> > > > > return eBasicSetContainer(otherEnd, featureID, msgs);
> > > > > }

--------------A7868DDD177D694C355E129F
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit

<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
Henrietta,
<p>When I generate from your examples below I get this implemention with
a case that handles bClasses:
<blockquote><tt>&nbsp;public NotificationChain eInverseAdd(InternalEObject
otherEnd, int featureID, Class baseClass, NotificationChain msgs) {</tt>
<br><tt>&nbsp; if (featureID >= 0) {</tt>
<br><tt>&nbsp;&nbsp; switch (eDerivedStructuralFeatureID(featureID, baseClass))
{</tt>
<br><tt>&nbsp;&nbsp;&nbsp; case Sample1Package.CONTAINER_CLASS__ACLASSES:</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp; return ((InternalEList)getAClasses()).basicAdd(otherEnd,
msgs);</tt>
<br><b><tt>&nbsp;&nbsp;&nbsp; case Sample1Package.CONTAINER_CLASS__BCLASSES:</tt></b>
<br><b><tt>&nbsp;&nbsp;&nbsp;&nbsp; return ((InternalEList)getBClasses()).basicAdd(otherEnd,
msgs);</tt></b>
<br><tt>&nbsp;&nbsp;&nbsp; default:</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp; return eDynamicInverseAdd(otherEnd, featureID,
baseClass, msgs);</tt>
<br><tt>&nbsp;&nbsp; }</tt>
<br><tt>&nbsp; }</tt>
<br><tt>&nbsp; if (eContainer != null)</tt>
<br><tt>&nbsp;&nbsp; msgs = eBasicRemoveFromContainer(msgs);</tt>
<br><tt>&nbsp; return eBasicSetContainer(otherEnd, featureID, msgs);</tt>
<br><tt>&nbsp;}</tt></blockquote>
I'm quite confused about why you would see something different that this.&nbsp;
There must be something that you are doing that we aren't, or vice versa,
but I haven't a clue.&nbsp; Perhaps you should attach the exact input files
you are using...
<br>&nbsp;
<p>Henrietta wrote:
<blockquote TYPE=CITE>I tried incorporating the change required for my
first problem and
<br>upgraded to 1.1 again with no success.&nbsp; The problem _seems_ to
be in the
<br>eInverseAdd() generated in ContainerClassImpl.java.&nbsp; It _looks
as though_
<br>a case statement is missing for CONTAINER_CLASS_B_CLASSES and it blows
up
<br>in the eDynamicInverseAdd() with a NullPointerException.&nbsp; (Shouldn't
it be
<br>doing a basicAdd() on the BClass list?).&nbsp; I've flipped backwards
and
<br>forwards between 1.02 and 1.1 three times now using the same code base
and
<br>regenerated the models from scratch and it's always consistent - 1.02
<br>works, 1.1 falls over.&nbsp; Here's the code:
<p>/**
<br>&nbsp;* &lt;!-- begin-user-doc -->
<br>&nbsp;* &lt;!-- end-user-doc -->
<br>&nbsp;* @generated
<br>&nbsp;*/
<br>public NotificationChain eInverseAdd(InternalEObject otherEnd, int
<br>featureID, Class baseClass, NotificationChain msgs)
<br>{
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; if (featureID >= 0)
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; {
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
switch (eDerivedStructuralFeatureID(featureID, baseClass))
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
{
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
case ModelPackage.CONTAINER_CLASS_A_CLASSES :
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;
return ((InternalEList) getAClasses()).basicAdd(otherEnd, msgs);
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
default :
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;
return eDynamicInverseAdd(otherEnd, featureID, baseClass, msgs);
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
}
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
}
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; if (eContainer != null)
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
msgs = eBasicRemoveFromContainer(msgs);
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; return eBasicSetContainer(otherEnd,
featureID, msgs);
<br>}
<p>Although it looks wrong (to me) it is exactly the same code that 1.0.2
<br>generates and that works (well, it doesn't give me a
<br>NullPointerException).&nbsp; This goes on to call eDynamicInverseAdd()
in
<br>EObjectImpl.java which picks up the null from eSettings():
<p>public NotificationChain eDynamicInverseAdd(InternalEObject otherEnd,
int
<br>featureID, Class inverseClass, NotificationChain msgs)
<br>{
<br>&nbsp; EStructuralFeature.Internal feature =
<br> (EStructuralFeature.Internal)eClass().getEAllStructuralFeatu res().get(featureID);
<br>&nbsp; return
<br>&nbsp;&nbsp;&nbsp; feature.getSettingDelegate().dynamicInverseAdd
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (this, eSettings(), featureID - eStaticFeatureCount(),
otherEnd,
<br>msgs);
<br>}
<p>And then on to dynamicInverseAdd() in InternalSettingDelegateMany (an
<br>inner class of EStructuralFeatureImpl):
<p>public NotificationChain dynamicInverseAdd
<br>&nbsp; (InternalEObject owner, EStructuralFeature.Internal.DynamicValueHolder
<br>settings, int index, InternalEObject otherEnd, NotificationChain
<br>notifications)
<br>{
<br>&nbsp; // -------- So we fail with settings as null here ------------
<br>&nbsp; Object setting = settings.dynamicGet(index);
<br>&nbsp; if (setting == null)
<br>&nbsp; {
<br>&nbsp;&nbsp;&nbsp; settings.dynamicSet(index, setting = createDynamicSetting(owner));
<br>&nbsp; }
<br>&nbsp; return ((InternalEList)setting).basicAdd(otherEnd, notifications);
<br>}
<p>To reiterate, here's what the three interfaces involved look like:
<p>/**
<br>&nbsp;* @model
<br>&nbsp;*/
<br>public interface ContainerClass extends EObject {
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; /**
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; * @model type="AClass"
opposite="containerClass"
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; */
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; EList getAClasses();
<p> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; /**
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; * @model type="BClass"
opposite="containerClass"
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; */
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; EList getBClasses();
<br>}
<p>/**
<br>&nbsp;* @model
<br>&nbsp;*/
<br>public interface AClass extends EObject {
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; /**
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; * @model opposite="aClasses"
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; */
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; ContainerClass getContainerClass();
<br>}
<p>/**
<br>&nbsp;* @model
<br>&nbsp;*/
<br>public interface BClass extends EObject {
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; /**
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; * @model opposite="bClasses"
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; */
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; ContainerClass getContainerClass();
<br>}
<p>Let me know if you need anything more.
<br>Thanks,
<br>Henrietta
<p>Frank Budinsky wrote:
<p>> Henrietta,
<p>> Is this still a problem. If so, could you please provide all the applicable
<br>classes
<br>> once again and explain exactly what isn't working.
<p>> Thanks,
<br>> Frank.
<p>> Henrietta wrote:
<p>> > I beg your pardon, Frank, that\'s just my manual find and replace
gone
<br>> > awry.&nbsp; I did do a complete rebuild (removed all model and
autogen\'d files
<br>> > and created a new model) in 1.1.&nbsp; It looks like a codegen
problem to me
<br>> > and I should have written:
<br>> >
<br>> > /**
<br>> >&nbsp; * @model
<br>> >&nbsp; */
<br>> > public interface AClass extends EObject {
<br>> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; /**
<br>> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; * @model
opposite=\"aClasses\"
<br>> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; */
<br>> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ContainerClass
getContainerClass();
<br>> > }
<br>> >
<br>> > /**
<br>> >&nbsp; * @model
<br>> >&nbsp; */
<br>> > public interface BClass extends EObject {
<br>> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; /**
<br>> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; * @model
opposite=\"bClasses\"
<br>> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; */
<br>> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; ContainerClass
getContainerClass();
<br>> > }
<br>> >
<br>> > Frank Budinsky wrote:
<br>> >
<br>> > > Henrietta,
<br>> >
<br>> > > The call to eDynamicInverseAdd() indicates a codegen problem.
Did you
<br>regen
<br>> > you\'re
<br>> > > model in 1.1?
<br>> >
<br>> > > The three model classes you show don\'t match. If they\'re supposed
to
<br>work
<br>> > together
<br>> > > then&nbsp; ContainerClass would need to be named LillyModel and
the opposite
<br>tags
<br>> > on
<br>> > > getAClasses() and getBClasses() would need to say
<br>opposite=\"lillyModel\".
<br>> >
<br>> > > Frank.
<br>> >
<br>> > > Henrietta wrote:
<br>> >
<br>> > > > I\'ve just upgraded to the latest EMF 1.1, recreated my models
and run
<br>> > > > straight into null pointer exceptions.&nbsp; It happens in
the call to
<br>> > > > eDynamicInverseAdd() after its failed to get its settings (sorry
I\'ve
<br>lost
<br>> > > > the stack trace for the moment).
<br>> > > >
<br>> > > > I\'ve gone back to 1.02 for now where I\'m working quite happily;
do
<br>you
<br>> > > > think this is likely to be a bug in 1.1?
<br>> > > >
<br>> > > > Thanks,
<br>> > > > Henrietta
<br>> > > >
<br>> > > > P.S. Any idea why AClass gets a basicAdd() and BClass gets
<br>> > > > eDynamicInverseAdd()?&nbsp; That looks wrong to me.&nbsp; I\'ve
boiled this
<br>example
<br>> > > > out of a lot of code but I\'m certain the classes and relationships
are
<br>> > > > defined in the same way.
<br>> > > >
<br>> > > > /**
<br>> > > >&nbsp; * @model
<br>> > > >&nbsp; */
<br>> > > > public interface ContainerClass extends EObject {
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; /**
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; * @model
type=\"AClass\" opposite=\"containerClass\"
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; */
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; EList getAClasses();
<br>> > > >
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; /**
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; * @model
type=\"BClass\" opposite=\"containerClass\"
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; */
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; EList getBClasses();
<br>> > > > }
<br>> > > >
<br>> > > > /**
<br>> > > >&nbsp; * @model
<br>> > > >&nbsp; */
<br>> > > > public interface AClass extends EObject {
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; /**
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; * @model
opposite=\"aClasses\"
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; */
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; LillyModel
getLillyModel();
<br>> > > > }
<br>> > > >
<br>> > > > /**
<br>> > > >&nbsp; * @model
<br>> > > >&nbsp; */
<br>> > > > public interface BClass extends EObject {
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; /**
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; * @model
opposite=\"bClasses\"
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; */
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; LillyModel
getLillyModel();
<br>> > > > }
<br>> > > >
<br>> > > > --------&lt; Gen\'d ContainerClass&nbsp; implementation >----------
<br>> > > >
<br>> > > > /**
<br>> > > >&nbsp; * &lt;!-- begin-user-doc -->
<br>> > > >&nbsp; * &lt;!-- end-user-doc -->
<br>> > > >&nbsp; * @generated
<br>> > > >&nbsp; */
<br>> > > > public NotificationChain eInverseAdd(InternalEObject otherEnd,
int
<br>> > > > featureID, Class baseClass, NotificationChain msgs)
<br>> > > > {
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; if (featureID
>= 0)
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; {
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;
switch (eDerivedStructuralFeatureID(featureID, baseClass))
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;
{
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
case MyPackage.CONTAINER_CLASS__A_CLASSES :
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
return ((InternalEList)
<br>getAClasses()).basicAdd(otherEnd,
<br>> > msgs);
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
default :
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
return eDynamicInverseAdd(otherEnd, featureID,
<br>baseClass,
<br>> > msgs);
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;
}
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; }
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; if (eContainer
!= null)
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;
msgs = eBasicRemoveFromContainer(msgs);
<br>> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; return eBasicSetContainer(otherEnd,
featureID, msgs);
<br>> > > > }</blockquote>
</html>

--------------A7868DDD177D694C355E129F--


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: Problem 2: eInverseAdd() null pointer exceptions in 1.1 [message #377840 is a reply to message #377839] Tue, 10 June 2003 16:39 Go to previous messageGo to next message
Henrietta Slack is currently offline Henrietta SlackFriend
Messages: 63
Registered: July 2009
Member
Oh dear! I was afraid of as much; I've boiled my example out a lot of
code (too much and not in a good state to send). I could try and get a
small demo together (if indeed I can reproduce it in a small demo) but
that's going to take me some time. In the meantime, does the asymmetry
between the eInverseAdd() and the eInverseRemove() give you any clues?
Would any differences in the code that generates these methods be obvious
to you just by looking?

Ed Merks wrote:


> --------------A7868DDD177D694C355E129F
> Content-Type: text/plain; charset=us-ascii
> Content-Transfer-Encoding: 7bit

> Henrietta,

> When I generate from your examples below I get this implemention with a case
that handles bClasses:

> public NotificationChain eInverseAdd(InternalEObject otherEnd, int
featureID, Class
> baseClass, NotificationChain msgs) {
> if (featureID >= 0) {
> switch (eDerivedStructuralFeatureID(featureID, baseClass)) {
> case Sample1Package.CONTAINER_CLASS__ACLASSES:
> return ((InternalEList)getAClasses()).basicAdd(otherEnd, msgs);
> case Sample1Package.CONTAINER_CLASS__BCLASSES:
> return ((InternalEList)getBClasses()).basicAdd(otherEnd, msgs);
> default:
> return eDynamicInverseAdd(otherEnd, featureID, baseClass, msgs);
> }
> }
> if (eContainer != null)
> msgs = eBasicRemoveFromContainer(msgs);
> return eBasicSetContainer(otherEnd, featureID, msgs);
> }

> I'm quite confused about why you would see something different that this.
There must be something
> that you are doing that we aren't, or vice versa, but I haven't a clue.
Perhaps you should attach
> the exact input files you are using...


> Henrietta wrote:

> > I tried incorporating the change required for my first problem and
> > upgraded to 1.1 again with no success. The problem _seems_ to be in the
> > eInverseAdd() generated in ContainerClassImpl.java. It _looks as though_
> > a case statement is missing for CONTAINER_CLASS_B_CLASSES and it blows up
> > in the eDynamicInverseAdd() with a NullPointerException. (Shouldn't it be
> > doing a basicAdd() on the BClass list?). I've flipped backwards and
> > forwards between 1.02 and 1.1 three times now using the same code base and
> > regenerated the models from scratch and it's always consistent - 1.02
> > works, 1.1 falls over. Here's the code:
> >
> > /**
> > * <!-- begin-user-doc -->
> > * <!-- end-user-doc -->
> > * @generated
> > */
> > public NotificationChain eInverseAdd(InternalEObject otherEnd, int
> > featureID, Class baseClass, NotificationChain msgs)
> > {
> > if (featureID >= 0)
> > {
> > switch (eDerivedStructuralFeatureID(featureID, baseClass))
> > {
> > case ModelPackage.CONTAINER_CLASS_A_CLASSES :
> > return ((InternalEList)
getAClasses()).basicAdd(otherEnd, msgs);
> > default :
> > return eDynamicInverseAdd(otherEnd,
featureID, baseClass, msgs);
> > }
> > }
> > if (eContainer != null)
> > msgs = eBasicRemoveFromContainer(msgs);
> > return eBasicSetContainer(otherEnd, featureID, msgs);
> > }
> >
> > Although it looks wrong (to me) it is exactly the same code that 1.0.2
> > generates and that works (well, it doesn't give me a
> > NullPointerException). This goes on to call eDynamicInverseAdd() in
> > EObjectImpl.java which picks up the null from eSettings():
> >
> > public NotificationChain eDynamicInverseAdd(InternalEObject otherEnd, int
> > featureID, Class inverseClass, NotificationChain msgs)
> > {
> > EStructuralFeature.Internal feature =
> >
(EStructuralFeature.Internal)eClass().getEAllStructuralFeatu res().get(featureID);
> > return
> > feature.getSettingDelegate().dynamicInverseAdd
> > (this, eSettings(), featureID - eStaticFeatureCount(), otherEnd,
> > msgs);
> > }
> >
> > And then on to dynamicInverseAdd() in InternalSettingDelegateMany (an
> > inner class of EStructuralFeatureImpl):
> >
> > public NotificationChain dynamicInverseAdd
> > (InternalEObject owner, EStructuralFeature.Internal.DynamicValueHolder
> > settings, int index, InternalEObject otherEnd, NotificationChain
> > notifications)
> > {
> > // -------- So we fail with settings as null here ------------
> > Object setting = settings.dynamicGet(index);
> > if (setting == null)
> > {
> > settings.dynamicSet(index, setting = createDynamicSetting(owner));
> > }
> > return ((InternalEList)setting).basicAdd(otherEnd, notifications);
> > }
> >
> > To reiterate, here's what the three interfaces involved look like:
> >
> > /**
> > * @model
> > */
> > public interface ContainerClass extends EObject {
> > /**
> > * @model type="AClass" opposite="containerClass"
> > */
> > EList getAClasses();
> >
> > /**
> > * @model type="BClass" opposite="containerClass"
> > */
> > EList getBClasses();
> > }
> >
> > /**
> > * @model
> > */
> > public interface AClass extends EObject {
> > /**
> > * @model opposite="aClasses"
> > */
> > ContainerClass getContainerClass();
> > }
> >
> > /**
> > * @model
> > */
> > public interface BClass extends EObject {
> > /**
> > * @model opposite="bClasses"
> > */
> > ContainerClass getContainerClass();
> > }
> >
> > Let me know if you need anything more.
> > Thanks,
> > Henrietta
> >
> > Frank Budinsky wrote:
> >
> > > Henrietta,
> >
> > > Is this still a problem. If so, could you please provide all the
applicable
> > classes
> > > once again and explain exactly what isn't working.
> >
> > > Thanks,
> > > Frank.
> >
> > > Henrietta wrote:
> >
> > > > I beg your pardon, Frank, that\'s just my manual find and replace gone
> > > > awry. I did do a complete rebuild (removed all model and autogen\'d
files
> > > > and created a new model) in 1.1. It looks like a codegen problem to me
> > > > and I should have written:
> > > >
> > > > /**
> > > > * @model
> > > > */
> > > > public interface AClass extends EObject {
> > > > /**
> > > > * @model opposite=\"aClasses\"
> > > > */
> > > > ContainerClass getContainerClass();
> > > > }
> > > >
> > > > /**
> > > > * @model
> > > > */
> > > > public interface BClass extends EObject {
> > > > /**
> > > > * @model opposite=\"bClasses\"
> > > > */
> > > > ContainerClass getContainerClass();
> > > > }
> > > >
> > > > Frank Budinsky wrote:
> > > >
> > > > > Henrietta,
> > > >
> > > > > The call to eDynamicInverseAdd() indicates a codegen problem. Did you
> > regen
> > > > you\'re
> > > > > model in 1.1?
> > > >
> > > > > The three model classes you show don\'t match. If they\'re supposed
to
> > work
> > > > together
> > > > > then ContainerClass would need to be named LillyModel and the
opposite
> > tags
> > > > on
> > > > > getAClasses() and getBClasses() would need to say
> > opposite=\"lillyModel\".
> > > >
> > > > > Frank.
> > > >
> > > > > Henrietta wrote:
> > > >
> > > > > > I\'ve just upgraded to the latest EMF 1.1, recreated my models and
run
> > > > > > straight into null pointer exceptions. It happens in the call to
> > > > > > eDynamicInverseAdd() after its failed to get its settings (sorry
I\'ve
> > lost
> > > > > > the stack trace for the moment).
> > > > > >
> > > > > > I\'ve gone back to 1.02 for now where I\'m working quite happily;
do
> > you
> > > > > > think this is likely to be a bug in 1.1?
> > > > > >
> > > > > > Thanks,
> > > > > > Henrietta
> > > > > >
> > > > > > P.S. Any idea why AClass gets a basicAdd() and BClass gets
> > > > > > eDynamicInverseAdd()? That looks wrong to me. I\'ve boiled this
> > example
> > > > > > out of a lot of code but I\'m certain the classes and
relationships are
> > > > > > defined in the same way.
> > > > > >
> > > > > > /**
> > > > > > * @model
> > > > > > */
> > > > > > public interface ContainerClass extends EObject {
> > > > > > /**
> > > > > > * @model type=\"AClass\" opposite=\"containerClass\"
> > > > > > */
> > > > > > EList getAClasses();
> > > > > >
> > > > > > /**
> > > > > > * @model type=\"BClass\" opposite=\"containerClass\"
> > > > > > */
> > > > > > EList getBClasses();
> > > > > > }
> > > > > >
> > > > > > /**
> > > > > > * @model
> > > > > > */
> > > > > > public interface AClass extends EObject {
> > > > > > /**
> > > > > > * @model opposite=\"aClasses\"
> > > > > > */
> > > > > > LillyModel getLillyModel();
> > > > > > }
> > > > > >
> > > > > > /**
> > > > > > * @model
> > > > > > */
> > > > > > public interface BClass extends EObject {
> > > > > > /**
> > > > > > * @model opposite=\"bClasses\"
> > > > > > */
> > > > > > LillyModel getLillyModel();
> > > > > > }
> > > > > >
> > > > > > --------< Gen\'d ContainerClass implementation >----------
> > > > > >
> > > > > > /**
> > > > > > * <!-- begin-user-doc -->
> > > > > > * <!-- end-user-doc -->
> > > > > > * @generated
> > > > > > */
> > > > > > public NotificationChain eInverseAdd(InternalEObject otherEnd, int
> > > > > > featureID, Class baseClass, NotificationChain msgs)
> > > > > > {
> > > > > > if (featureID >= 0)
> > > > > > {
> > > > > > switch (eDerivedStructuralFeatureID(featureID,
baseClass))
> > > > > > {
> > > > > > case MyPackage.CONTAINER_CLASS__A_CLASSES :
> > > > > > return ((InternalEList)
> > getAClasses()).basicAdd(otherEnd,
> > > > msgs);
> > > > > > default :
> > > > > > return eDynamicInverseAdd(otherEnd, featureID,
> > baseClass,
> > > > msgs);
> > > > > > }
> > > > > > }
> > > > > > if (eContainer != null)
> > > > > > msgs = eBasicRemoveFromContainer(msgs);
> > > > > > return eBasicSetContainer(otherEnd, featureID, msgs);
> > > > > > }

> --------------A7868DDD177D694C355E129F
> Content-Type: text/html; charset=us-ascii
> Content-Transfer-Encoding: 7bit

> <!doctype html public "-//w3c//dtd html 4.0 transitional//en">
> <html>
> Henrietta,
> <p>When I generate from your examples below I get this implemention with
> a case that handles bClasses:
> <blockquote><tt> public NotificationChain eInverseAdd(InternalEObject
> otherEnd, int featureID, Class baseClass, NotificationChain msgs) {</tt>
> <br><tt>  if (featureID >= 0) {</tt>
> <br><tt>   switch (eDerivedStructuralFeatureID(featureID, baseClass))
> {</tt>
> <br><tt>    case Sample1Package.CONTAINER_CLASS__ACLASSES:</tt>
> <br><tt>     return ((InternalEList)getAClasses()).basicAdd(otherEnd,
> msgs);</tt>
> <br><b><tt>    case Sample1Package.CONTAINER_CLASS__BCLASSES:</tt></b>
> <br><b><tt>     return ((InternalEList)getBClasses()).basicAdd(otherEnd,
> msgs);</tt></b>
> <br><tt>    default:</tt>
> <br><tt>     return eDynamicInverseAdd(otherEnd, featureID,
> baseClass, msgs);</tt>
> <br><tt>   }</tt>
> <br><tt>  }</tt>
> <br><tt>  if (eContainer != null)</tt>
> <br><tt>   msgs = eBasicRemoveFromContainer(msgs);</tt>
> <br><tt>  return eBasicSetContainer(otherEnd, featureID, msgs);</tt>
> <br><tt> }</tt></blockquote>
> I'm quite confused about why you would see something different that this. 
> There must be something that you are doing that we aren't, or vice versa,
> but I haven't a clue.  Perhaps you should attach the exact input files
> you are using...
> <br> 
> <p>Henrietta wrote:
> <blockquote TYPE=CITE>I tried incorporating the change required for my
> first problem and
> <br>upgraded to 1.1 again with no success.  The problem _seems_ to
> be in the
> <br>eInverseAdd() generated in ContainerClassImpl.java.  It _looks
> as though_
> <br>a case statement is missing for CONTAINER_CLASS_B_CLASSES and it blows
> up
> <br>in the eDynamicInverseAdd() with a NullPointerException.  (Shouldn't
> it be
> <br>doing a basicAdd() on the BClass list?).  I've flipped backwards
> and
> <br>forwards between 1.02 and 1.1 three times now using the same code base
> and
> <br>regenerated the models from scratch and it's always consistent - 1.02
> <br>works, 1.1 falls over.  Here's the code:
> <p>/**
> <br> * <!-- begin-user-doc -->
> <br> * <!-- end-user-doc -->
> <br> * @generated
> <br> */
> <br>public NotificationChain eInverseAdd(InternalEObject otherEnd, int
> <br>featureID, Class baseClass, NotificationChain msgs)
> <br>{
> <br>        if (featureID >= 0)
> <br>        {
> <br>               
> switch (eDerivedStructuralFeatureID(featureID, baseClass))
> <br>               
> {
> <br>                       
> case ModelPackage.CONTAINER_CLASS_A_CLASSES :
> <br>                                 
> return ((InternalEList) getAClasses()).basicAdd(otherEnd, msgs);
> <br>                       
> default :
> <br>                                 
> return eDynamicInverseAdd(otherEnd, featureID, baseClass, msgs);
> <br>                       
> }
> <br>               
> }
> <br>        if (eContainer != null)
> <br>               
> msgs = eBasicRemoveFromContainer(msgs);
> <br>        return eBasicSetContainer(otherEnd,
> featureID, msgs);
> <br>}
> <p>Although it looks wrong (to me) it is exactly the same code that 1.0.2
> <br>generates and that works (well, it doesn't give me a
> <br>NullPointerException).  This goes on to call eDynamicInverseAdd()
> in
> <br>EObjectImpl.java which picks up the null from eSettings():
> <p>public NotificationChain eDynamicInverseAdd(InternalEObject otherEnd,
> int
> <br>featureID, Class inverseClass, NotificationChain msgs)
> <br>{
> <br>  EStructuralFeature.Internal feature =
>
<br> (EStructuralFeature.Internal)eClass().getEAllStructuralFeatu res().get(featureID);
> <br>  return
> <br>    feature.getSettingDelegate().dynamicInverseAdd
> <br>      (this, eSettings(), featureID - eStaticFeatureCount(),
> otherEnd,
> <br>msgs);
> <br>}
> <p>And then on to dynamicInverseAdd() in InternalSettingDelegateMany (an
> <br>inner class of EStructuralFeatureImpl):
> <p>public NotificationChain dynamicInverseAdd
> <br>  (InternalEObject owner, EStructuralFeature.Internal.DynamicValueHolder
> <br>settings, int index, InternalEObject otherEnd, NotificationChain
> <br>notifications)
> <br>{
> <br>  // -------- So we fail with settings as null here ------------
> <br>  Object setting = settings.dynamicGet(index);
> <br>  if (setting == null)
> <br>  {
> <br>    settings.dynamicSet(index, setting = createDynamicSetting(owner));
> <br>  }
> <br>  return ((InternalEList)setting).basicAdd(otherEnd, notifications);
> <br>}
> <p>To reiterate, here's what the three interfaces involved look like:
> <p>/**
> <br> * @model
> <br> */
> <br>public interface ContainerClass extends EObject {
> <br>        /**
> <br>         * @model type="AClass"
> opposite="containerClass"
> <br>         */
> <br>        EList getAClasses();
> <p>        /**
> <br>         * @model type="BClass"
> opposite="containerClass"
> <br>         */
> <br>        EList getBClasses();
> <br>}
> <p>/**
> <br> * @model
> <br> */
> <br>public interface AClass extends EObject {
> <br>        /**
> <br>         * @model opposite="aClasses"
> <br>         */
> <br>        ContainerClass getContainerClass();
> <br>}
> <p>/**
> <br> * @model
> <br> */
> <br>public interface BClass extends EObject {
> <br>        /**
> <br>         * @model opposite="bClasses"
> <br>         */
> <br>        ContainerClass getContainerClass();
> <br>}
> <p>Let me know if you need anything more.
> <br>Thanks,
> <br>Henrietta
> <p>Frank Budinsky wrote:
> <p>> Henrietta,
> <p>> Is this still a problem. If so, could you please provide all the
applicable
> <br>classes
> <br>> once again and explain exactly what isn't working.
> <p>> Thanks,
> <br>> Frank.
> <p>> Henrietta wrote:
> <p>> > I beg your pardon, Frank, that\'s just my manual find and replace
> gone
> <br>> > awry.  I did do a complete rebuild (removed all model and
> autogen\'d files
> <br>> > and created a new model) in 1.1.  It looks like a codegen
> problem to me
> <br>> > and I should have written:
> <br>> >
> <br>> > /**
> <br>> >  * @model
> <br>> >  */
> <br>> > public interface AClass extends EObject {
> <br>> >         /**
> <br>> >          * @model
> opposite=\"aClasses\"
> <br>> >          */
> <br>> >          ContainerClass
> getContainerClass();
> <br>> > }
> <br>> >
> <br>> > /**
> <br>> >  * @model
> <br>> >  */
> <br>> > public interface BClass extends EObject {
> <br>> >         /**
> <br>> >          * @model
> opposite=\"bClasses\"
> <br>> >          */
> <br>> >         ContainerClass
> getContainerClass();
> <br>> > }
> <br>> >
> <br>> > Frank Budinsky wrote:
> <br>> >
> <br>> > > Henrietta,
> <br>> >
> <br>> > > The call to eDynamicInverseAdd() indicates a codegen problem.
> Did you
> <br>regen
> <br>> > you\'re
> <br>> > > model in 1.1?
> <br>> >
> <br>> > > The three model classes you show don\'t match. If they\'re supposed
> to
> <br>work
> <br>> > together
> <br>> > > then  ContainerClass would need to be named LillyModel and
> the opposite
> <br>tags
> <br>> > on
> <br>> > > getAClasses() and getBClasses() would need to say
> <br>opposite=\"lillyModel\".
> <br>> >
> <br>> > > Frank.
> <br>> >
> <br>> > > Henrietta wrote:
> <br>> >
> <br>> > > > I\'ve just upgraded to the latest EMF 1.1, recreated my models
> and run
> <br>> > > > straight into null pointer exceptions.  It happens in
> the call to
> <br>> > > > eDynamicInverseAdd() after its failed to get its settings (sorry
> I\'ve
> <br>lost
> <br>> > > > the stack trace for the moment).
> <br>> > > >
> <br>> > > > I\'ve gone back to 1.02 for now where I\'m working quite happily;
> do
> <br>you
> <br>> > > > think this is likely to be a bug in 1.1?
> <br>> > > >
> <br>> > > > Thanks,
> <br>> > > > Henrietta
> <br>> > > >
> <br>> > > > P.S. Any idea why AClass gets a basicAdd() and BClass gets
> <br>> > > > eDynamicInverseAdd()?  That looks wrong to me.  I\'ve
> boiled this
> <br>example
> <br>> > > > out of a lot of code but I\'m certain the classes and
relationships
> are
> <br>> > > > defined in the same way.
> <br>> > > >
> <br>> > > > /**
> <br>> > > >  * @model
> <br>> > > >  */
> <br>> > > > public interface ContainerClass extends EObject {
> <br>> > > >         /**
> <br>> > > >          * @model
> type=\"AClass\" opposite=\"containerClass\"
> <br>> > > >          */
> <br>> > > >         EList getAClasses();
> <br>> > > >
> <br>> > > >         /**
> <br>> > > >          * @model
> type=\"BClass\" opposite=\"containerClass\"
> <br>> > > >          */
> <br>> > > >         EList getBClasses();
> <br>> > > > }
> <br>> > > >
> <br>> > > > /**
> <br>> > > >  * @model
> <br>> > > >  */
> <br>> > > > public interface AClass extends EObject {
> <br>> > > >         /**
> <br>> > > >          * @model
> opposite=\"aClasses\"
> <br>> > > >          */
> <br>> > > >         LillyModel
> getLillyModel();
> <br>> > > > }
> <br>> > > >
> <br>> > > > /**
> <br>> > > >  * @model
> <br>> > > >  */
> <br>> > > > public interface BClass extends EObject {
> <br>> > > >         /**
> <br>> > > >          * @model
> opposite=\"bClasses\"
> <br>> > > >          */
> <br>> > > >         LillyModel
> getLillyModel();
> <br>> > > > }
> <br>> > > >
> <br>> > > > --------< Gen\'d ContainerClass  implementation >----------
> <br>> > > >
> <br>> > > > /**
> <br>> > > >  * <!-- begin-user-doc -->
> <br>> > > >  * <!-- end-user-doc -->
> <br>> > > >  * @generated
> <br>> > > >  */
> <br>> > > > public NotificationChain eInverseAdd(InternalEObject otherEnd,
> int
> <br>> > > > featureID, Class baseClass, NotificationChain msgs)
> <br>> > > > {
> <br>> > > >         if (featureID
> >= 0)
> <br>> > > >         {
> <br>> > > >          
> switch (eDerivedStructuralFeatureID(featureID, baseClass))
> <br>> > > >          
> {
> <br>> > > >            
> case MyPackage.CONTAINER_CLASS__A_CLASSES :
> <br>> > > >               
> return ((InternalEList)
> <br>getAClasses()).basicAdd(otherEnd,
> <br>> > msgs);
> <br>> > > >            
> default :
> <br>> > > >               
> return eDynamicInverseAdd(otherEnd, featureID,
> <br>baseClass,
> <br>> > msgs);
> <br>> > > >          
> }
> <br>> > > >         }
> <br>> > > >         if (eContainer
> != null)
> <br>> > > >          
> msgs = eBasicRemoveFromContainer(msgs);
> <br>> > > >         return eBasicSetContainer(otherEnd,
> featureID, msgs);
> <br>> > > > }</blockquote>
> </html>

> --------------A7868DDD177D694C355E129F--
Re: Problem 2: eInverseAdd() null pointer exceptions in 1.1 [message #377841 is a reply to message #377838] Tue, 10 June 2003 17:10 Go to previous messageGo to next message
Frank Budinsky is currently offline Frank BudinskyFriend
Messages: 478
Registered: July 2009
Senior Member
Henrietta,

I created a project with the three interfaces in your note and it generated properly. I'm using the
latest 1.1 driver. Here's what eInverseAdd() generated:

/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, Class baseClass,
NotificationChain msgs) {
if (featureID >= 0) {
switch (eDerivedStructuralFeatureID(featureID, baseClass)) {
case TestPackage.CONTAINER_CLASS__ACLASSES:
return ((InternalEList)getAClasses()).basicAdd(otherEnd, msgs);
case TestPackage.CONTAINER_CLASS__BCLASSES:
return ((InternalEList)getBClasses()).basicAdd(otherEnd, msgs);
default:
return eDynamicInverseAdd(otherEnd, featureID, baseClass, msgs);
}
}
if (eContainer != null)
msgs = eBasicRemoveFromContainer(msgs);
return eBasicSetContainer(otherEnd, featureID, msgs);
}

There must be something else in your environment causing the problem. Why don't you try to create a new
Java project, import just the three interfaces from your note and generate.

Btw, you shouldn't ordinarly need to add the extends EObject to your interfaces. It is an implicit
model inheritance that the generator will add to the Java interfaces. If you add it yourself, it will
be explicit in the meta model.

Frank.


Henrietta wrote:

> The generated method eInverseRemove() gets it right and does a
> basicRemove() on the BClass list. Surely this should be symmetric with
> eInverseAdd() and it's the missing case statement that's causing my
> problem? I thought so, and when I add the case statement manually ...
>
> case ModelPackage.CONTAINER_CLASS__B_CLASSES :
> return ((InternalEList) getBClasses()).basicAdd(otherEnd, msgs);
>
> .. to my eInverseAdd() it fixes the problem (until I regenerate). So at
> least I have a work around for the short term. Now why did it _appear_ to
> work in 1.02 ...
>
> /**
> * <!-- begin-user-doc -->
> * <!-- end-user-doc -->
> * @generated
> */
> public NotificationChain eInverseRemove(InternalEObject otherEnd, int
> featureID, Class baseClass, NotificationChain msgs)
> {
> if (featureID >= 0)
> {
> switch (eDerivedStructuralFeatureID(featureID, baseClass))
> {
> case ModelPackage.CONTAINER_CLASS__A_CLASSES:
> return ((InternalEList)getAClasses()).basicRemove(otherEnd, msgs);
> case ModelPackage.CONTAINER_CLASS__B_CLASSES:
> return ((InternalEList)getBClasses()).basicRemove(otherEnd, msgs);
> default:
> return eDynamicInverseRemove(otherEnd, featureID, baseClass, msgs);
> }
> }
> return eBasicSetContainer(null, featureID, msgs);
> }
Re: Problem 2: eInverseAdd() null pointer exceptions in 1.1 [message #377842 is a reply to message #377841] Tue, 10 June 2003 17:38 Go to previous messageGo to next message
Henrietta Slack is currently offline Henrietta SlackFriend
Messages: 63
Registered: July 2009
Member
Yeah, I\'ve tried that experiment too and several variations and I
haven\'t yet reproduced the problem in anything but my full development
environment. I\'m going to keep trying. In the meantime...

Here\'s one asymmetry in the code generation framework between adds and
removes. This code is from GenClassImpl.java. Note that more removes can
be generated than adds because of the genFeature.isContains() condition on
the remove. Does this one make any sense? This _could_ result in what
I\'m seeing.


public List getEInverseAddGenFeatures()
{
return
collectGenFeatures
(getAllBaseGenClasses(),
getGenFeatures(),
new GenFeatureFilter()
{
public boolean accept(GenFeature genFeature)
{
return genFeature.isBidirectional() &&
!genFeature.isVolatile();
}
});
}

public List getEInverseRemoveGenFeatures()
{
return
collectGenFeatures
(getAllBaseGenClasses(),
getGenFeatures(),
new GenFeatureFilter()
{
public boolean accept(GenFeature genFeature)
{
return genFeature.isContains() ||
(genFeature.isBidirectional() &&
!genFeature.getReverse().isVolatile());
}
});
}




Frank Budinsky wrote:

> Henrietta,

> I created a project with the three interfaces in your note and it generated
properly. I\'m using the
> latest 1.1 driver. Here\'s what eInverseAdd() generated:

> /**
> * <!-- begin-user-doc -->
> * <!-- end-user-doc -->
> * @generated
> */
> public NotificationChain eInverseAdd(InternalEObject otherEnd, int
featureID, Class baseClass,
> NotificationChain msgs) {
> if (featureID >= 0) {
> switch (eDerivedStructuralFeatureID(featureID, baseClass)) {
> case TestPackage.CONTAINER_CLASS__ACLASSES:
> return ((InternalEList)getAClasses()).basicAdd(otherEnd, msgs);
> case TestPackage.CONTAINER_CLASS__BCLASSES:
> return ((InternalEList)getBClasses()).basicAdd(otherEnd, msgs);
> default:
> return eDynamicInverseAdd(otherEnd, featureID, baseClass, msgs);
> }
> }
> if (eContainer != null)
> msgs = eBasicRemoveFromContainer(msgs);
> return eBasicSetContainer(otherEnd, featureID, msgs);
> }

> There must be something else in your environment causing the problem. Why
don\'t you try to create a new
> Java project, import just the three interfaces from your note and generate.

> Btw, you shouldn\'t ordinarly need to add the extends EObject to your
interfaces. It is an implicit
> model inheritance that the generator will add to the Java interfaces. If you
add it yourself, it will
> be explicit in the meta model.

> Frank.


> Henrietta wrote:

> > The generated method eInverseRemove() gets it right and does a
> > basicRemove() on the BClass list. Surely this should be symmetric with
> > eInverseAdd() and it\'s the missing case statement that\'s causing my
> > problem? I thought so, and when I add the case statement manually ...
> >
> > case ModelPackage.CONTAINER_CLASS__B_CLASSES :
> > return ((InternalEList) getBClasses()).basicAdd(otherEnd, msgs);
> >
> > .. to my eInverseAdd() it fixes the problem (until I regenerate). So at
> > least I have a work around for the short term. Now why did it _appear_ to
> > work in 1.02 ...
> >
> > /**
> > * <!-- begin-user-doc -->
> > * <!-- end-user-doc -->
> > * @generated
> > */
> > public NotificationChain eInverseRemove(InternalEObject otherEnd, int
> > featureID, Class baseClass, NotificationChain msgs)
> > {
> > if (featureID >= 0)
> > {
> > switch (eDerivedStructuralFeatureID(featureID, baseClass))
> > {
> > case ModelPackage.CONTAINER_CLASS__A_CLASSES:
> > return
((InternalEList)getAClasses()).basicRemove(otherEnd, msgs);
> > case ModelPackage.CONTAINER_CLASS__B_CLASSES:
> > return
((InternalEList)getBClasses()).basicRemove(otherEnd, msgs);
> > default:
> > return eDynamicInverseRemove(otherEnd,
featureID, baseClass, msgs);
> > }
> > }
> > return eBasicSetContainer(null, featureID, msgs);
> > }
Re: Problem 2: eInverseAdd() null pointer exceptions in 1.1 [message #377843 is a reply to message #377841] Tue, 10 June 2003 18:06 Go to previous messageGo to next message
Henrietta Slack is currently offline Henrietta SlackFriend
Messages: 63
Registered: July 2009
Member
Sorry, I missed part of your note.

> There must be something else in your environment causing the problem.
> Why don\'t you try to create a new Java project, import just the
> three interfaces from your note and generate.

I don't believe it! It's the same environment I use for 1.0.2 and 1.1.
The problem seems more complicated. Although the three interfaces in
my example are EXACTLY SIMILAR (same relationships and annotation,
different names, other methods left out) they're not reproducing the
problem. I'll let you know as soon as i can reproduce it, but doesn't that
"genFeature.isContains()" condition mentioned above look suspicious?

> Btw, you shouldn\'t ordinarly need to add the extends EObject to your
> interfaces. It is an implicit model inheritance that the generator
> will add to the Java interfaces. If you add it yourself, it will
> be explicit in the meta model.

Thanks for the tip.
Re: Problem 2: eInverseAdd() null pointer exceptions in 1.1 [message #377848 is a reply to message #377841] Tue, 10 June 2003 21:01 Go to previous messageGo to next message
Henrietta Slack is currently offline Henrietta SlackFriend
Messages: 63
Registered: July 2009
Member
OK, it's easy to reproduce and easy to work around (once you know what it
is). After you've generated the example I gave you paste the lines below
into ContainerClassImpl.java just prior to the eInverseAdd() method call.

/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
*/
/*public void aMethodYouDontWant()
{
some code you've commented out;
}*/

You can then remove the BCLASSES case statement from the eInverseAdd() to
simulate what's been happening in my environment and then regenerate. It
doesn't generate the method again. Take the comment lines out,
regenerate, and everything works fine.

The interesting thing about this problem is that seems to affect
subsequent eInverseAdds as well, even in different packages.

Thanks for your help today,
Henrietta
Re: Problem 2: eInverseAdd() null pointer exceptions in 1.1 [message #377850 is a reply to message #377848] Tue, 10 June 2003 21:19 Go to previous message
Ed Merks is currently offline Ed MerksFriend
Messages: 33137
Registered: July 2009
Senior Member
--------------99EDF5ABEBB1180D296A67C5
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Henrietta,

Sorry you were bitten by this! We deliberately ignore comments with
multiple /* occurrences (in JPatternDictionary.match) so that if you did this

/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
/*public void aMethodYouDontWant()
{
some code you've commented out;
}*/

/**
* Some really important hand written code.
*/
public void aMethodYouReallyWant()
{
// Some code that you've just written.
}

the merger won't treat this as if the @generated applies to
aMethodYouReallyWant, which would result it in it being removed during
regeneration. Note that all the stuff in blue is considered by JDOM to be
the comment of aMethodYouReallyWant.


Henrietta wrote:

> OK, it's easy to reproduce and easy to work around (once you know what it
> is). After you've generated the example I gave you paste the lines below
> into ContainerClassImpl.java just prior to the eInverseAdd() method call.
>
> /**
> * <!-- begin-user-doc -->
> * <!-- end-user-doc -->
> */
> /*public void aMethodYouDontWant()
> {
> some code you've commented out;
> }*/
>
> You can then remove the BCLASSES case statement from the eInverseAdd() to
> simulate what's been happening in my environment and then regenerate. It
> doesn't generate the method again. Take the comment lines out,
> regenerate, and everything works fine.
>
> The interesting thing about this problem is that seems to affect
> subsequent eInverseAdds as well, even in different packages.
>
> Thanks for your help today,
> Henrietta

--------------99EDF5ABEBB1180D296A67C5
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit

<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
Henrietta,
<p>Sorry you were bitten by this!&nbsp;&nbsp; We deliberately ignore comments
with multiple /* occurrences (in JPatternDictionary.match) so that if you
did this
<p>&nbsp;<font color="#000099"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /**</font>
<br><font color="#000099"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;
* &lt;!-- begin-user-doc --></font>
<br><font color="#000099"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;
* &lt;!-- end-user-doc --></font>
<br><font color="#000099"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;
* @generated</font>
<br><font color="#000099"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;
*/</font>
<br><font color="#000099"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; /*public
void aMethodYouDontWant()</font>
<br><font color="#000099"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; {</font>
<br><font color="#000099"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
some code you've commented out;</font>
<br><font color="#000099"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; }*/</font><font color="#000099"></font>
<p><font color="#000099"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; /**</font>
<br><font color="#000099"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;
* Some really important hand written code.</font>
<br><font color="#000099"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;
*/</font>
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; public void aMethodYouReallyWant()
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; {
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// Some code that you've just written.
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; }
<p>the merger won't treat this as if the @generated applies to aMethodYouReallyWant,
which would result it in it being removed during regeneration.&nbsp; Note
that all the stuff in <font color="#000099">blue</font> is considered by
JDOM to be the comment of aMethodYouReallyWant.
<br>&nbsp;
<p>Henrietta wrote:
<blockquote TYPE=CITE>OK, it's easy to reproduce and easy to work around
(once you know what it
<br>is).&nbsp; After you've generated the example I gave you paste the
lines below
<br>into ContainerClassImpl.java just prior to the eInverseAdd() method
call.
<p> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; /**
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; * &lt;!-- begin-user-doc
-->
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; * &lt;!-- end-user-doc
-->
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; */
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; /*public void aMethodYouDontWant()
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; {
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
some code you've commented out;
<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; }*/
<p>You can then remove the BCLASSES case statement from the eInverseAdd()
to
<br>simulate what's been happening in my environment and then regenerate.&nbsp;
It
<br>doesn't generate the method again.&nbsp; Take the comment lines out,
<br>regenerate, and everything works fine.
<p>The interesting thing about this problem is that seems to affect
<br>subsequent eInverseAdds as well, even in different packages.
<p>Thanks for your help today,
<br>Henrietta</blockquote>
</html>

--------------99EDF5ABEBB1180D296A67C5--


Ed Merks
Professional Support: https://www.macromodeling.com/
Previous Topic:EMF and XML Schemas
Next Topic:getting started with JETEmitter
Goto Forum:
  


Current Time: Fri Apr 19 14:08:10 GMT 2024

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

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

Back to the top