Uploaded image for project: 'Isis'
  1. Isis
  2. ISIS-1435

Infitinite recursion in updating() callback if it modifies the object

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 1.12.2
    • Fix Version/s: 1.13.0
    • Component/s: Archetype: SimpleApp, Core
    • Labels:
      None

      Description

      I'm observing infinite recursion / stack overflow if a domain object has an updating() reserved method that updates the domain object. This is related, if not identical, to ISIS-1004.

      Steps to reproduce:

      1.
      Checkout the SimpleApp as described on https://isis.apache.org/guides/ugfun.html#_generating_the_app -

      mvn archetype:generate  \
          -D archetypeGroupId=org.apache.isis.archetype \
          -D archetypeArtifactId=simpleapp-archetype \
          -D archetypeVersion=1.12.2 \
          -D groupId=com.mycompany \
          -D artifactId=myapp \
          -D version=1.0-SNAPSHOT \
          -B
      

      2.
      Open the class:

      domainapp.dom.simple.SimpleObject

      and add the following code to the bottom:

      public void updating() {
          	System.out.println("updating()");
          	// this.name += "-updating"; // modification directly to field
          	this.setName(this.getName() + "-updating"); // modification via setter
          }
      

      3.
      Build as described on https://isis.apache.org/guides/ugfun.html#_building_the_app -

      cd myapp
      mvn clean install
      

      Result:
      Stack overflow in

      domainapp.integtests.tests.modules.simple.SimpleObjectIntegTest$UpdateName

        Activity

        Hide
        jira-bot ASF subversion and git services added a comment -

        Commit e7d7ab5f3a578f7c5434e2694c2fad8f2f97a2e0 in isis's branch refs/heads/master from Dan Haywood
        [ https://git-wip-us.apache.org/repos/asf?p=isis.git;h=e7d7ab5 ]

        ISIS-1435: fixes infinite recursion for updating()

        ... as demonstrated by public void updating()

        { setName(getName() + " - updating"; }

        We now only call the updating() callback, and also the domain event lifecycle callback, if it hasn't previously been called. We figure that out by looking asking the ChangedObjectsService (new API) as to whether the object was previously changed or not (if so, then don't fire the callbacks).

        Show
        jira-bot ASF subversion and git services added a comment - Commit e7d7ab5f3a578f7c5434e2694c2fad8f2f97a2e0 in isis's branch refs/heads/master from Dan Haywood [ https://git-wip-us.apache.org/repos/asf?p=isis.git;h=e7d7ab5 ] ISIS-1435 : fixes infinite recursion for updating() ... as demonstrated by public void updating() { setName(getName() + " - updating"; } We now only call the updating() callback, and also the domain event lifecycle callback, if it hasn't previously been called. We figure that out by looking asking the ChangedObjectsService (new API) as to whether the object was previously changed or not (if so, then don't fire the callbacks).
        Hide
        danhaywood Dan Haywood added a comment -

        Thanks for providing this detailed example of how to reproduce.

        I've fixed this by ensuring that updating() callback is only ever called once.

        It's possible that there are other cases, with other lifecycle events, that might trigger similar infinite loops. eg, what might happen if an inserted() triggered a deleting() which then called an updating() that then did another inserted() etc. But I'd rather fix this particular use case in a relatively simple fashion, than try to consider every other possible use case which may or may not arise.

        Show
        danhaywood Dan Haywood added a comment - Thanks for providing this detailed example of how to reproduce. I've fixed this by ensuring that updating() callback is only ever called once. It's possible that there are other cases, with other lifecycle events, that might trigger similar infinite loops. eg, what might happen if an inserted() triggered a deleting() which then called an updating() that then did another inserted() etc. But I'd rather fix this particular use case in a relatively simple fashion, than try to consider every other possible use case which may or may not arise.

          People

          • Assignee:
            danhaywood Dan Haywood
            Reporter:
            dukeyin Duke Yin
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development