Skip to content

Inconsistent handling of dependent lifecycle beans in DefaultLifecycleProcessor [SPR-16901] #21440

@spring-projects-issues

Description

@spring-projects-issues

Markus Heiden opened SPR-16901 and commented

DefaultLifecycleProcessor.LifecycleGroup#stop() fails to wait for all members, if there are dependencies between the members.

IMO the problem lies in this loop of LifecycleGroup#stop():

for (LifecycleGroupMember member : this.members) {
  if (this.lifecycleBeans.containsKey(member.name)) {
    doStop(this.lifecycleBeans, member.name, latch, countDownBeanNames);
  }
  else if (member.bean instanceof SmartLifecycle) {
    // already removed, must have been a dependent
    latch.countDown();
  }
}

The loop iterates all members. doStop() removes the current member and its dependent members from this.lifecycleBeans and passes a callback to all of them which counts the latch down. This way the latch gets counted down for the current member and its dependent members.

Later on when the iteration reaches one of the dependent members from above, the else block gets executed, because the dependent member has already been removed from this.lifecycleBeans. This counts the latch down again for the dependent member.

This way the latch reaches 0 before all beans called their stop callback and the application context gets destroyed even though some of the members are still running.

I don't understand why the else block is needed at all. IMO it should be simply removed.


Affects: 5.0.6

Issue Links:

Referenced from: commits 6f41d4e, b3ca2d5, b71795b, 6cf1978

0 votes, 5 watchers

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)type: bugA general bug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions