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

H2ConsoleAutoConfiguration causes early initialization of DataSource beans #43337

Closed
AlbertoCortina opened this issue Dec 1, 2024 · 7 comments
Assignees
Labels
type: bug A general bug
Milestone

Comments

@AlbertoCortina
Copy link

AlbertoCortina commented Dec 1, 2024

Context

I have an application (recently upgraded to Spring Boot 3.4.0) with two configured data sources, following a setup similar to the one described in this Baeldung article.

Currently, I am using Testcontainers for integration tests, based on the approach outlined in Spring Boot's documentation. These tests mock the second data source, and everything is working perfectly.

After a great initial experience using Testcontainers for testing, I decided to try it for local development. However, this is where I encountered some challenges.

Problem

I followed the steps described in Baeldung's article on Testcontainers support for local development and Spring's blog post on improved Testcontainers support in Spring Boot 3.1.

Below are the classes involved:

public interface OracleContainerConfiguration {

  @Container
  OracleContainer oracleContainer =
      new OracleContainer("gvenzl/oracle-free:slim-faststart")
          .withReuse(true);

  @DynamicPropertySource
  private static void configureProperties(DynamicPropertyRegistry registry) {
    registry.add("my-custom.datasource.url", oracleContainer::getJdbcUrl);
    registry.add("my-custom.datasource.username", oracleContainer::getUsername);
    registry.add("my-custom.datasource.password", oracleContainer::getPassword);
  }
}
@TestConfiguration(proxyBeanMethods = false)
@ImportTestcontainers(OracleContainerConfiguration.class)
public class LocalDevelopmentContainersConfiguration {}
public class MyApplicationWithContainer {

  public static void main(String[] args) {
    SpringApplication.from(MyApplication::main)
        .withAdditionalProfiles("integration-test-oracle")
        .with(LocalDevelopmentContainersConfiguration.class)
        .run(args);
  }
}

When running the application, I noticed that the data source configuration is executed before the @DynamicPropertySource, which results in the application picking up the properties defined in my application.yml.

In contrast, during an integration test, the behavior is reversed: the values from the @DynamicPropertySource are processed first, and only then is the data source configured.

Is this the expected behavior, or could it be a bug when using Testcontainers for local development?

Please let me know if anything is unclear.

Thank you very much!

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

It's hard to say for sure what's happening as there are some parts of your app that you haven't shared. For example, we can't see how the my-custom.datasource.* properties are consumed. If you would like us to spend some more time investigating, please spend some time providing 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 2, 2024
@AlbertoCortina
Copy link
Author

Hello @wilkinsona, thank you for looking into the issue.

While creating a minimal example to reproduce the error, I discovered that the cause of the problem was having the dependency implementation("org.springframework.boot:spring-boot-devtools") in my build.gradle.kts. After removing it, everything worked as expected.

I'm not sure if this behavior is intentional or not. If you'd like, I have a small project where the issue can be reproduced.

@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 2, 2024
@wilkinsona
Copy link
Member

Yes please, @AlbertoCortina.

@AlbertoCortina
Copy link
Author

Here is the repository -> https://github.com/AlbertoCortina/demo-bug-testcontainers-dynamicpropertysource

To reproduce the error just try to run the application in the test folder, you will see that it goes first to the data source configuration classes and the to the @DynamicPropertySource.

Please let me know if you don't manage to reproduce the error

@philwebb
Copy link
Member

philwebb commented Dec 3, 2024

Thanks for the sample, this appears to be because the H2ConsoleAutoConfiguration is triggering DataSource bean initialization from a ServletRegistrationBean. As a work around you can add the following to your application.yml:

spring:
  h2:
    console:
      enabled: false

@philwebb philwebb changed the title @DynamicPropertySource executed after DataSource initialization while using Testcontainers for local development H2ConsoleAutoConfiguration causes early initialization of DataSource beans Dec 3, 2024
@philwebb philwebb added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged status: feedback-provided Feedback has been provided labels Dec 3, 2024
@philwebb philwebb added this to the 3.3.x milestone Dec 3, 2024
@quaff

This comment was marked as resolved.

@philwebb philwebb self-assigned this Dec 3, 2024
@philwebb

This comment was marked as resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
Development

No branches or pull requests

5 participants