Skip to content

Using @ServiceConnection on a Container @Bean method does not work with AOT-processed tests #42851

Open
@wyhasany

Description

@wyhasany

Spring Boot application fails to run the nativeTest task with Testcontainers.

I generated a simple project using start.spring.io:

image

On the first run, it fails due to a reflection issue:

...
o.t.d.DockerClientProviderStrategy       : Could not find a valid Docker environment. Please check configuration. Attempted configurations were:
	UnixSocketClientProviderStrategy: failed with exception RuntimeException (org.testcontainers.shaded.com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.github.dockerjava.api.model.RuntimeInfo: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)
 at [Source: N/A; line: -1, column: -1] (through reference chain: com.github.dockerjava.api.model.Info["Runtimes"]->java.util.LinkedHashMap["io.containerd.runc.v2"])). Root cause JsonMappingException (Can not construct instance of com.github.dockerjava.api.model.RuntimeInfo: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)
 at [Source: N/A; line: -1, column: -1] (through reference chain: com.github.dockerjava.api.model.Info["Runtimes"]->java.util.LinkedHashMap["io.containerd.runc.v2"]))
	DockerDesktopClientProviderStrategy: failed with exception RuntimeException (org.testcontainers.shaded.com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.github.dockerjava.api.model.RuntimeInfo: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)
 at [Source: N/A; line: -1, column: -1] (through reference chain: com.github.dockerjava.api.model.Info["Runtimes"]->java.util.LinkedHashMap["io.containerd.runc.v2"])). Root cause JsonMappingException (Can not construct instance of com.github.dockerjava.api.model.RuntimeInfo: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)
 at [Source: N/A; line: -1, column: -1] (through reference chain: com.github.dockerjava.api.model.Info["Runtimes"]->java.util.LinkedHashMap["io.containerd.runc.v2"]))As no valid configuration was found, execution cannot continue.
See https://java.testcontainers.org/on_failure.html for more details.
...

I solved this issue by adding a reflect.json file in src/test/resources/META-INF/native-image/ with the following content::

[
  {
    "name":"com.github.dockerjava.api.model.RuntimeInfo",
    "allDeclaredFields":true,
    "queryAllDeclaredMethods":true,
    "queryAllDeclaredConstructors":true,
    "methods":[{"name":"<init>","parameterTypes":[] }, {"name":"setPath","parameterTypes":["java.lang.String"] }]
  },
  {
    "name":"com.github.dockerjava.api.model.Info",
    "allDeclaredFields":true,
    "queryAllDeclaredMethods":true,
    "queryAllDeclaredConstructors":true,
    "methods":[{"name":"<init>","parameterTypes":[] }]
  }
]

However, I'm confused because Testcontainers seems to be supported by GraalVM as indicated here: https://www.graalvm.org/native-image/libraries-and-frameworks/

With that configuration, I encountered another issue that I'm unsure how to resolve:

> Task :nativeTest
JUnit Platform on Native Image - report
----------------------------------------

12:37:58.794 [main] INFO org.springframework.test.context.support.AnnotationConfigContextLoaderUtils -- Could not detect default configuration classes for test class [com.example.demo.DemoApplicationTests]: DemoApplicationTests does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
12:37:58.797 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper -- Found @SpringBootConfiguration com.example.demo.DemoApplication for test class com.example.demo.DemoApplicationTests

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::                (v3.3.4)

2024-10-23T12:37:58.813+02:00  INFO 9667 --- [demo] [           main] com.example.demo.DemoApplicationTests    : Starting AOT-processed DemoApplicationTests using Java 21.0.4 with PID 9667 (started by rowickim in /private/tmp/demo)
2024-10-23T12:37:58.813+02:00  INFO 9667 --- [demo] [           main] com.example.demo.DemoApplicationTests    : No active profile set, falling back to 1 default profile: "default"
2024-10-23T12:37:58.816+02:00  INFO 9667 --- [demo] [           main] org.testcontainers.images.PullPolicy     : Image pull policy will be performed by: DefaultPullPolicy()
2024-10-23T12:37:58.816+02:00  INFO 9667 --- [demo] [           main] o.t.utility.ImageNameSubstitutor         : Image name substitution will be performed by: DefaultImageNameSubstitutor (composite of 'ConfigurationFileImageNameSubstitutor' and 'PrefixingImageNameSubstitutor')
2024-10-23T12:37:58.825+02:00  INFO 9667 --- [demo] [           main] o.t.d.DockerClientProviderStrategy       : Loaded org.testcontainers.dockerclient.UnixSocketClientProviderStrategy from ~/.testcontainers.properties, will try it first
2024-10-23T12:37:58.846+02:00  INFO 9667 --- [demo] [           main] o.t.d.DockerClientProviderStrategy       : Found Docker environment with local Unix socket (unix:///var/run/docker.sock)
2024-10-23T12:37:58.847+02:00  INFO 9667 --- [demo] [           main] org.testcontainers.DockerClientFactory   : Docker host IP address is localhost
2024-10-23T12:37:58.852+02:00  INFO 9667 --- [demo] [           main] org.testcontainers.DockerClientFactory   : Connected to docker:
  Server Version: 27.2.0
  API Version: 1.47
  Operating System: Docker Desktop
  Total Memory: 7838 MB
2024-10-23T12:37:58.852+02:00  WARN 9667 --- [demo] [           main] o.testcontainers.utility.ResourceReaper  :
********************************************************************************
Ryuk has been disabled. This can cause unexpected behavior in your environment.
********************************************************************************
2024-10-23T12:37:58.852+02:00  INFO 9667 --- [demo] [           main] org.testcontainers.DockerClientFactory   : Checking the system...
2024-10-23T12:37:58.852+02:00  INFO 9667 --- [demo] [           main] org.testcontainers.DockerClientFactory   : ✔︎ Docker server version should be at least 1.6.0
2024-10-23T12:37:58.859+02:00  INFO 9667 --- [demo] [           main] tc.mongo:latest                          : Creating container for image: mongo:latest
2024-10-23T12:37:59.004+02:00  INFO 9667 --- [demo] [           main] tc.mongo:latest                          : Container mongo:latest is starting: cb2dd662645f26c2cb8ffdf5dd73d4332628b60c2a5e6487fcfe101c4480456e
2024-10-23T12:37:59.877+02:00  INFO 9667 --- [demo] [           main] tc.mongo:latest                          : Container mongo:latest started in PT1.018256S
2024-10-23T12:38:00.339+02:00  WARN 9667 --- [demo] [           main] o.s.c.support.GenericApplicationContext  : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'standardMongoSettingsCustomizer': Unsatisfied dependency expressed through method 'standardMongoSettingsCustomizer' parameter 1: No qualifying bean of type 'org.springframework.boot.autoconfigure.mongo.MongoConnectionDetails' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

It looks like the task aotTestClasses doesn't add any MongoConnectionDetails to the application context.

Here is the zipped project for reference: demo.zip

Environment Details

I'm using the following version of GraalVM:

❯ java -version
java version "21.0.4" 2024-07-16 LTS
Java(TM) SE Runtime Environment Oracle GraalVM 21.0.4+8.1 (build 21.0.4+8-LTS-jvmci-23.1-b41)
Java HotSpot(TM) 64-Bit Server VM Oracle GraalVM 21.0.4+8.1 (build 21.0.4+8-LTS-jvmci-23.1-b41, mixed mode, sharing)

Metadata

Metadata

Assignees

No one assigned

    Labels

    theme: aotAn issue related to Ahead-of-time processingtype: bugA general bug

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions