Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Child context created with SpringApplicationBuilder runs parents runners #38647

Closed
fgsfb opened this issue Dec 4, 2023 · 3 comments
Closed
Assignees
Labels
type: regression A regression from a previous release
Milestone

Comments

@fgsfb
Copy link

fgsfb commented Dec 4, 2023

After #37905 fix, child context created with SpringApplicationBuilder runs parents runners.
Child context creation code:

        SpringApplication springApplication = new SpringApplicationBuilder(childMainClass)
                .parent((ConfigurableApplicationContext) applicationContext)
                .bannerMode(Banner.Mode.OFF)
                .build();
        ConfigurableApplicationContext context = springApplication.run();

Code above is executed from parents CommandLineRunner and leads to infinite context recursion. Parents runner creates child context, which invokes parents runner and so on.

Looks like problem is in using context.getBeanProvider(Runner.class) instead of context.getBeansOfType(ApplicationRunner.class) in SpringApplication::callRunners

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Dec 4, 2023
@wilkinsona
Copy link
Member

wilkinsona commented Dec 4, 2023

Thanks for the report. Unfortunately, I'm not sure that I've understood the arrangement that you have described. Are you using the SpringApplicationBuilder API in a CommandLineRunner implementation? To clarify, please provide a complete yet minimal sample that reproduces the problem. You can share it with us by pushing it to a separate repository on GitHub or by zipping it up and attaching it to this issue.

@wilkinsona wilkinsona added the status: waiting-for-feedback We need additional information before we can continue label Dec 4, 2023
@fgsfb
Copy link
Author

fgsfb commented Dec 4, 2023

Yes, I'm trying to create child context in parents runner implementation. And it worked well on previous versions.
reproduce.zip

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Dec 4, 2023
@wilkinsona
Copy link
Member

wilkinsona commented Dec 4, 2023

Thanks very much. I understand things now.

You can work around the problem by only allowing the parent runner to run once:

package com.reproduce.parent;

import java.util.concurrent.atomic.AtomicBoolean;

import org.springframework.beans.BeansException;
import org.springframework.boot.Banner;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Component;

import com.reproduce.child.ChildMainClass;

@Component
public class ParentRunner implements CommandLineRunner, ApplicationContextAware {
	
    private final AtomicBoolean run = new AtomicBoolean();
	
    private ApplicationContext applicationContext;

    @Override
    public void run(String... args) throws Exception {
    	if (run.compareAndSet(false, true)) {
	        System.out.println("Parent runner");
	        new SpringApplicationBuilder(ChildMainClass.class)
	                .parent((ConfigurableApplicationContext) applicationContext)
	                .bannerMode(Banner.Mode.OFF)
	                .run();
    	}
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

}

@philwebb philwebb added type: regression A regression from a previous release and removed status: waiting-for-triage An issue we've not yet triaged status: feedback-provided Feedback has been provided labels Dec 4, 2023
@philwebb philwebb added this to the 3.2.x milestone Dec 4, 2023
@philwebb philwebb modified the milestones: 3.2.x, 3.1.x Dec 15, 2023
@philwebb philwebb self-assigned this Dec 15, 2023
@philwebb philwebb modified the milestones: 3.1.x, 3.1.7 Dec 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: regression A regression from a previous release
Projects
None yet
Development

No branches or pull requests

4 participants