I've found a problem when trying to migrate to new Domain Events.


I wrap all setter invocations and that originates Domain Events to be 
constantly generated without generating any problems, but the following one.

In DomainEventHelper.postEventForProperty, the method will reuse the previously 
available event on the ThreadLocal (being one of my custom defined type 
"AssetPropertyWithRelationshipEvent", despite trying to post an event of type 
"org.apache.isis.applib.services.eventbus.PropertyDomainEvent$Default".

As it reuses that, when published the EventBus publishes it to all subscribed 
Event Handlers (ie, my custom defined ones) with wrong params causing 
unexpected behaviors.

So basically, when entering DomainEventHelper.postEventForProperty we have on 
the debugger:
- eventType:            class 
org.apache.isis.applib.services.eventbus.PropertyDomainEvent$Default
- existingEvent:        instance of AssetPropertyWithRelationshipEvent

Referring to different "domain actions" (identifiers):
- Identified (method param):            PROPERTY Peer 
[identifier="com.xms.framework.architecture.domain.model.Relationship#enterpriseArchitectureModel()",type=com.xms.framework.architecture.domain.model.EnterpriseArchitectureModel
 ]
- On "existingEvent.identifier":                
com.xms.framework.architecture.domain.model.technology.extensions.systemsoftware.SoftwareInstance#host()


As the only check is:

            final PropertyDomainEvent<?, ?> event;
            if ((existingEvent != null) && phase.isValidatingOrLater()) {
                event = existingEvent;
                setEventOldValue(event, oldValue);
                setEventNewValue(event, newValue);


It will reuse the Event despite not been referred to the same action 
invocation, property or collection update, etc.


So basically I would try to not reuse the Event but always create it (as 
searching for "equivalency" of the existingEvent and the one to be published 
could lead to a comparison chain for "nearly" all values other that the Phase - 
, refactoring the method to this implementation:


public class DomainEventHelper {
    ...

    public PropertyDomainEvent<?, ?> postEventForProperty(
            final Class eventType,
            final PropertyDomainEvent<?, ?> existingEvent,
            final AbstractDomainEvent.Phase phase,
            final IdentifiedHolder identified,
            final ObjectAdapter targetAdapter,
            final Object oldValue,
            final Object newValue) {
        if (!this.hasEventBusService()) {
            return null;
        }
        try {
            final PropertyDomainEvent<?, ?> event;
            final Object source = ObjectAdapter.Util.unwrap(targetAdapter);
            final Identifier identifier = identified.getIdentifier();
            event = newPropertyDomainEvent(eventType, identifier, source, 
oldValue, newValue);
            event.setEventPhase(phase);
            event.setPhase(AbstractInteractionEvent.Phase.from(phase));

            // Old and New Values are populated only on the VALIDATION Phase and
            // afterwards.
            if ((existingEvent != null) && phase.isValidatingOrLater()) {
                setEventOldValue(event, oldValue);
                setEventNewValue(event, newValue);
            }
            this.getEventBusService().post(event);
            return event;
        } catch (final Exception e) {
            throw new FatalException(e);
        }
    }

    ...

}

FYI, this case was also happening on previous implementation for the EXECUTED 
phase, as I found a comment in my code telling that I was receiving "bad" 
values on the subscribed Event properties on the EXECUTED phase (but it was 
correct on the EXECUTING phase).


Problem is that when I implement that change, there are tests not passing:



PropertyAnnotationFacetFactoryTest.withDeprecatedPostsPropertyChangedEvent_andGetterFacet_andSetterFacet()


Invocation.withPostsActionInvokedEvent()

Failing on:

Assert.assertTrue(domainEventFacet instanceof ActionDomainEventFacetDefault);

As domainEventFacet is an instanceof 
ActionDomainEventFacetForPostsActionInvokedEventAnnotation


But I think that must be the correct behavior, so tests might be refactored to 
expect those deprecated classes.



HTH,

Oscar




> El 6/2/2015, a las 19:39, QUALITEC - Óscar Bou <[email protected]> escribió:
> 
> Hi, Dan.
> 
> I sent previous message before reading your response.
> 
> 
> Yes, I think it should be feasible.
> 
> Let me try it.
> 
> Thanks again,
> 
> Oscar
> 
> 
> 
>> El 6/2/2015, a las 19:37, QUALITEC - Óscar Bou <[email protected]> escribió:
>> 
>> Sorry. Params number is correct, but it’s curious what’s happening.
>> 
>> On DomainEventHelper.newCollectionDomainEvent(), line 264 requires the 
>> constructor to have 4 params (source, identifier, type, value), instead of 
>> the 3 previously required (source, identifier, value).
>> 
>> In fact, in line 289 3 params are required, for the EXECUTED phase.
>> 
>> 
>> HTH, 
>> 
>> Oscar
>> 
>> 
>>> El 6/2/2015, a las 19:03, QUALITEC - Óscar Bou <[email protected] 
>>> <mailto:[email protected]>> escribió:
>>> 
>>> 
>>> Hi Dan.
>>> 
>>> Since today our Jenkins fails with the following message.
>>> 
>>> Perhaps is it due to the refactoring / deprecation work you’re doing?
>>> 
>>> We’re working against latest SNAPSHOT.
>>> 
>>> In fact, when throwing:
>>> 
>>> Caused by: java.lang.NoSuchMethodException: 
>>> com.xms.framework.architecture.domain.model.events.AssetCollectionWithRelationshipAddedToEvent.<init>(?
>>>  super com.xms.framework.architecture.domain.model.business.Product, 
>>> org.apache.isis.applib.Identifier, java.lang.Object)
>>> 
>>> 
>>> It’s true because I have a 3 params constructor:
>>> 
>>> public class AssetCollectionWithRelationshipAddedToEvent extends 
>>> CollectionAddedToEvent<Asset, Asset> {
>>> 
>>>    /**
>>>     * 
>>>     */
>>>    private static final long serialVersionUID = 1L;
>>> 
>>>    public AssetCollectionWithRelationshipAddedToEvent(final Asset source, 
>>> final Identifier identifier, final Asset value) {
>>>        super(source, identifier, value);
>>>    }
>>> 
>>> }
>>> 
>>> 
>>> 
>>> Thanks,
>>> 
>>> Oscar
>>> 
>>> Mensaje de error
>>> 
>>> com.xms.framework.architecture.domain.model.events.AssetCollectionWithRelationshipAddedToEvent.<init>(?
>>>  super com.xms.framework.architecture.domain.model.business.Product, 
>>> org.apache.isis.applib.Identifier, java.lang.Object)
>>> Traza
>>> 
>>> org.apache.isis.applib.FatalException: 
>>> com.xms.framework.architecture.domain.model.events.AssetCollectionWithRelationshipAddedToEvent.<init>(?
>>>  super com.xms.framework.architecture.domain.model.business.Product, 
>>> org.apache.isis.applib.Identifier, java.lang.Object)
>>>     at 
>>> org.apache.isis.core.metamodel.facets.DomainEventHelper.postEventForCollection(DomainEventHelper.java:240)
>>>     at 
>>> org.apache.isis.core.metamodel.facets.collections.collection.modify.CollectionDomainEventFacetAbstract.hides(CollectionDomainEventFacetAbstract.java:61)
>>>     at 
>>> org.apache.isis.core.metamodel.interactions.InteractionUtils.isVisibleResult(InteractionUtils.java:40)
>>>     at 
>>> org.apache.isis.core.metamodel.specloader.specimpl.ObjectMemberAbstract.isVisibleResult(ObjectMemberAbstract.java:232)
>>>     at 
>>> org.apache.isis.core.metamodel.specloader.specimpl.ObjectMemberAbstract.isVisible(ObjectMemberAbstract.java:227)
>>>     at 
>>> org.apache.isis.core.wrapper.handlers.DomainObjectInvocationHandler.checkVisibility(DomainObjectInvocationHandler.java:592)
>>>     at 
>>> org.apache.isis.core.wrapper.handlers.DomainObjectInvocationHandler.handleCollectionAddToMethod(DomainObjectInvocationHandler.java:470)
>>>     at 
>>> org.apache.isis.core.wrapper.handlers.DomainObjectInvocationHandler.invoke(DomainObjectInvocationHandler.java:215)
>>>     at 
>>> org.apache.isis.core.wrapper.proxy.ProxyInstantiatorForJavassist$1.invoke(ProxyInstantiatorForJavassist.java:52)
>>>     at 
>>> com.xms.framework.architecture.domain.model.business.Product_$$_jvstd87_40.addToAggregatedServices(Product_$$_jvstd87_40.java)
>>>     at 
>>> com.xms.framework.architecture.domain.model.business.Product.addService(Product.java:115)
>>>     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>>     at 
>>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>>>     at 
>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>>     at java.lang.reflect.Method.invoke(Method.java:606)
>>>     at 
>>> org.apache.isis.core.metamodel.facets.actions.action.invocation.ActionInvocationFacetForDomainEventAbstract.internalInvoke(ActionInvocationFacetForDomainEventAbstract.java:337)
>>>     at 
>>> org.apache.isis.core.metamodel.facets.actions.action.invocation.ActionInvocationFacetForDomainEventAbstract.invoke(ActionInvocationFacetForDomainEventAbstract.java:191)
>>>     at 
>>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction$1.execute(ActionInvocationFacetWrapTransaction.java:57)
>>>     at 
>>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction$1.execute(ActionInvocationFacetWrapTransaction.java:54)
>>>     at 
>>> org.apache.isis.core.runtime.system.transaction.IsisTransactionManager.executeWithinTransaction(IsisTransactionManager.java:205)
>>>     at 
>>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction.invoke(ActionInvocationFacetWrapTransaction.java:54)
>>>     at 
>>> org.apache.isis.core.metamodel.specloader.specimpl.ObjectActionImpl.execute(ObjectActionImpl.java:367)
>>>     at 
>>> org.apache.isis.core.wrapper.handlers.DomainObjectInvocationHandler.handleActionMethod(DomainObjectInvocationHandler.java:563)
>>>     at 
>>> org.apache.isis.core.wrapper.handlers.DomainObjectInvocationHandler.invoke(DomainObjectInvocationHandler.java:229)
>>>     at 
>>> org.apache.isis.core.wrapper.proxy.ProxyInstantiatorForJavassist$1.invoke(ProxyInstantiatorForJavassist.java:52)
>>>     at 
>>> com.xms.framework.architecture.domain.model.business.Product_$$_jvstd87_40.addService(Product_$$_jvstd87_40.java)
>>>     at 
>>> com.xms.framework.architecture.integration.glue.business.old.ProductGlue.product_aggregates_the_business_service(ProductGlue.java:34)
>>>     at ✽.When the "EAM-ASS-VAL-INH-010 - product" product aggregates the 
>>> "EAM-ASS-VAL-INH-010 - business service" business 
>>> service(com/xms/framework/architecture/integration/specs/base/EAM-ASS-VAL - 
>>> Enterprise Architecture Model - Assets - Valuation.feature:93)
>>> Caused by: java.lang.NoSuchMethodException: 
>>> com.xms.framework.architecture.domain.model.events.AssetCollectionWithRelationshipAddedToEvent.<init>(?
>>>  super com.xms.framework.architecture.domain.model.business.Product, 
>>> org.apache.isis.applib.Identifier, java.lang.Object)
>>>     at 
>>> org.apache.isis.core.metamodel.facets.DomainEventHelper.newCollectionDomainEvent(DomainEventHelper.java:327)
>>>     at 
>>> org.apache.isis.core.metamodel.facets.DomainEventHelper.postEventForCollection(DomainEventHelper.java:233)
>>>     at 
>>> org.apache.isis.core.metamodel.facets.collections.collection.modify.CollectionDomainEventFacetAbstract.hides(CollectionDomainEventFacetAbstract.java:61)
>>>     at 
>>> org.apache.isis.core.metamodel.interactions.InteractionUtils.isVisibleResult(InteractionUtils.java:40)
>>>     at 
>>> org.apache.isis.core.metamodel.specloader.specimpl.ObjectMemberAbstract.isVisibleResult(ObjectMemberAbstract.java:232)
>>>     at 
>>> org.apache.isis.core.metamodel.specloader.specimpl.ObjectMemberAbstract.isVisible(ObjectMemberAbstract.java:227)
>>>     at 
>>> org.apache.isis.core.wrapper.handlers.DomainObjectInvocationHandler.checkVisibility(DomainObjectInvocationHandler.java:592)
>>>     at 
>>> org.apache.isis.core.wrapper.handlers.DomainObjectInvocationHandler.handleCollectionAddToMethod(DomainObjectInvocationHandler.java:470)
>>>     at 
>>> org.apache.isis.core.wrapper.handlers.DomainObjectInvocationHandler.invoke(DomainObjectInvocationHandler.java:215)
>>>     at 
>>> org.apache.isis.core.wrapper.proxy.ProxyInstantiatorForJavassist$1.invoke(ProxyInstantiatorForJavassist.java:52)
>>>     at 
>>> com.xms.framework.architecture.domain.model.business.Product_$$_jvstd87_40.addToAggregatedServices(Product_$$_jvstd87_40.java)
>>>     at 
>>> com.xms.framework.architecture.domain.model.business.Product.addService(Product.java:115)
>>>     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>>     at 
>>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>>>     at 
>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>>     at java.lang.reflect.Method.invoke(Method.java:606)
>>>     at 
>>> org.apache.isis.core.metamodel.facets.actions.action.invocation.ActionInvocationFacetForDomainEventAbstract.internalInvoke(ActionInvocationFacetForDomainEventAbstract.java:337)
>>>     at 
>>> org.apache.isis.core.metamodel.facets.actions.action.invocation.ActionInvocationFacetForDomainEventAbstract.invoke(ActionInvocationFacetForDomainEventAbstract.java:191)
>>>     at 
>>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction$1.execute(ActionInvocationFacetWrapTransaction.java:57)
>>>     at 
>>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction$1.execute(ActionInvocationFacetWrapTransaction.java:54)
>>>     at 
>>> org.apache.isis.core.runtime.system.transaction.IsisTransactionManager.executeWithinTransaction(IsisTransactionManager.java:205)
>>>     at 
>>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction.invoke(ActionInvocationFacetWrapTransaction.java:54)
>>>     at 
>>> org.apache.isis.core.metamodel.specloader.specimpl.ObjectActionImpl.execute(ObjectActionImpl.java:367)
>>>     at 
>>> org.apache.isis.core.wrapper.handlers.DomainObjectInvocationHandler.handleActionMethod(DomainObjectInvocationHandler.java:563)
>>>     at 
>>> org.apache.isis.core.wrapper.handlers.DomainObjectInvocationHandler.invoke(DomainObjectInvocationHandler.java:229)
>>>     at 
>>> org.apache.isis.core.wrapper.proxy.ProxyInstantiatorForJavassist$1.invoke(ProxyInstantiatorForJavassist.java:52)
>>>     at 
>>> com.xms.framework.architecture.domain.model.business.Product_$$_jvstd87_40.addService(Product_$$_jvstd87_40.java)
>>>     at 
>>> com.xms.framework.architecture.integration.glue.business.old.ProductGlue.product_aggregates_the_business_service(ProductGlue.java:34)
>>>     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>>     at 
>>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>>>     at 
>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>>     at java.lang.reflect.Method.invoke(Method.java:606)
>>>     at cucumber.runtime.Utils$1.call(Utils.java:35)
>>>     at cucumber.runtime.Timeout.timeout(Timeout.java:12)
>>>     at cucumber.runtime.Utils.invoke(Utils.java:31)
>>>     at 
>>> cucumber.runtime.java.JavaStepDefinition.execute(JavaStepDefinition.java:35)
>>>     at 
>>> cucumber.runtime.StepDefinitionMatch.runStep(StepDefinitionMatch.java:38)
>>>     at cucumber.runtime.Runtime.runStep(Runtime.java:289)
>>>     at cucumber.runtime.model.StepContainer.runStep(StepContainer.java:44)
>>>     at cucumber.runtime.model.StepContainer.runSteps(StepContainer.java:39)
>>>     at cucumber.runtime.model.CucumberScenario.run(CucumberScenario.java:40)
>>>     at 
>>> cucumber.runtime.junit.ExecutionUnitRunner.run(ExecutionUnitRunner.java:83)
>>>     at cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:63)
>>>     at cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:18)
>>>     at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
>>>     at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
>>>     at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
>>>     at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
>>>     at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
>>>     at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
>>>     at cucumber.runtime.junit.FeatureRunner.run(FeatureRunner.java:70)
>>>     at cucumber.api.junit.Cucumber.runChild(Cucumber.java:82)
>>>     at cucumber.api.junit.Cucumber.runChild(Cucumber.java:41)
>>>     at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
>>>     at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
>>>     at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
>>>     at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
>>>     at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
>>>     at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
>>>     at cucumber.api.junit.Cucumber.run(Cucumber.java:87)
>>>     at 
>>> org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:264)
>>>     at 
>>> org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153)
>>>     at 
>>> org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:124)
>>>     at 
>>> org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:200)
>>>     at 
>>> org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:153)
>>>     at 
>>> org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
>>> 
>> 
> 

Reply via email to