Hello,
I've updated my application from Spring-Boot 3.2.0-M3 to 3.2.0-RC1 and since then the used postgresql testcontainer doesnt't start before the application and the following error occurs:
[javax.sql.DataSource]: Factory method 'dataSource' threw exception with message: Mapped port can only be obtained after the container is started
See example: https://github.com/mosesonline/container-bug When starting the class TestContainerBugApplication it fails, but stepping back to M3 the application starts and terminates fine. I couldn't find anysting in the change log so it might be an regression.
It can be connected with #37989 but there is no @RestartScope.
Thanks
Comment From: rajadilipkolli
it is happening only for web-mvc project where spring-data-jpa is present, whereas for web-flux project and a web-mvc project without spring-data-jpa. It is working as expected.
Comment From: mhalbritter
When JPA is on the classpath, org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization looks for LoadTimeWeaverAware beans. The EntityManagerFactory is such a bean, and then Framework calls getBean on it, which then wants to get the datasource, and the container is not started at that point. I think we need to tweak the if statement in org.springframework.boot.testcontainers.lifecycle.TestcontainersLifecycleBeanPostProcessor#postProcessAfterInitialization so that the containers are started earlier.
Comment From: Wzy19930507
Hi, @mhalbritter may i pick it up, this issue looks good for beginners
Comment From: mhalbritter
Hey @Wzy19930507, thanks for the offer, but I don't think this issue is suitable for beginners. It relies on bean initialization logic and bean post processors, which require a delicate understanding of Spring Framework internals.
Comment From: Wzy19930507
Hi, @mhalbritter, If possible, I'll write a plan and discuss it with you.
Comment From: Wzy19930507
Hi, @mhalbritter , prototype code is https://gist.github.com/Wzy19930507/057446d5249b501f6a4e91e7ead83ad9 change in L67, L77-L82, L101-L103
Comment From: scottfrederick
@Wzy19930507 Thanks for the suggestion. The changes that introduced this problem were done to support starting containers in parallel. If I'm reading your changes correctly, all containers would be started sequentially regardless of the value of the spring.testcontainers.beans.startup that was introduced in that change. This isn't the way we would want to fix the problem. We are discussing as a team whether we want to resolve this by further refining the code or by reverting the parallel container startup changes.
Comment From: Wzy19930507
Hi, @scottfrederick Thank you for the response. Learn a lot
if (!this.beanFactory.isConfigurationFrozen()) {
if (bean instanceof Startable) {
startup.start(bean)
}
}
Use !this.beanFactory.isConfigurationFrozen() to earlier create jpa container because of LoadTimeWeaverAware,
else container can create at parallel mode?
Comment From: philwebb
I think that this issue has the same underlying cause as #37989 so I'm going to close it as a duplicate.
@mosesonline Thanks very much for the sample, it was very helpful.