testcontainers-java icon indicating copy to clipboard operation
testcontainers-java copied to clipboard

[Bug]: Unable to start container with mount as GraalVM native image

Open bedla opened this issue 7 months ago • 1 comments

Module

Core

Testcontainers version

1.20.6

Using the latest Testcontainers version?

Yes

Host OS

Windows/WLS

Host Arch

x86

Docker version

Client:
 Version:           28.0.4
 API version:       1.48
 Go version:        go1.23.7
 Git commit:        b8034c0
 Built:             Tue Mar 25 15:06:08 2025
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Desktop 4.0.0 ()
 Engine:
  Version:          28.0.4
  API version:      1.48 (minimum version 1.24)
  Go version:       go1.23.7
  Git commit:       6430e49
  Built:            Tue Mar 25 15:07:22 2025
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.7.26
  GitCommit:        753481ec61c7c8955a23d6ff7bc8e4daed455734
 runc:
  Version:          1.2.5
  GitCommit:        v1.2.5-0-g59923ef
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

What happened?

Hi, please take a look at repo to reproduce at https://github.com/bedla/reproduce-graalvm-native-springboot-testcontainers You can see that when running GraalVM native image, check for mount is failing. It looks like that it is becase of prefix resource:. Seems that there is missing pefix removal at org.testcontainers.utility.MountableFile#unencodeResourceURIToFilePath method? Thank you Ivos

Relevant log output

2025-04-22T13:50:55.790Z DEBUG 1 --- [demo] [           main] org.testcontainers.DockerClientFactory   : Failure while checking for mountable file support

com.github.dockerjava.api.exception.InternalServerErrorException: Status 500: mount denied:
the source path "resource:/org/testcontainers/utility/ResourceReaper.class:/dummy:ro"
too many colons

        at org.testcontainers.shaded.com.github.dockerjava.core.DefaultInvocationBuilder.execute(DefaultInvocationBuilder.java:247) ~[na:na]
        at org.testcontainers.shaded.com.github.dockerjava.core.DefaultInvocationBuilder.post(DefaultInvocationBuilder.java:124) ~[na:na]
        at org.testcontainers.shaded.com.github.dockerjava.core.exec.CreateContainerCmdExec.execute(CreateContainerCmdExec.java:37) ~[na:na]
        at org.testcontainers.shaded.com.github.dockerjava.core.exec.CreateContainerCmdExec.execute(CreateContainerCmdExec.java:13) ~[na:na]
        at org.testcontainers.shaded.com.github.dockerjava.core.exec.AbstrSyncDockerCmdExec.exec(AbstrSyncDockerCmdExec.java:21) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:1.20.6]
        at org.testcontainers.shaded.com.github.dockerjava.core.command.AbstrDockerCmd.exec(AbstrDockerCmd.java:33) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:1.20.6]
        at org.testcontainers.shaded.com.github.dockerjava.core.command.CreateContainerCmdImpl.exec(CreateContainerCmdImpl.java:608) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:1.20.6]
        at org.testcontainers.DockerClientFactory.runInsideDocker(DockerClientFactory.java:364) ~[na:na]
        at org.testcontainers.DockerClientFactory.runInsideDocker(DockerClientFactory.java:351) ~[na:na]
        at org.testcontainers.DockerClientFactory.checkMountableFile(DockerClientFactory.java:293) ~[na:na]
        at org.testcontainers.DockerClientFactory.isFileMountingSupported(DockerClientFactory.java:99) ~[na:na]
        at org.testcontainers.containers.ContainerDef.applyTo(ContainerDef.java:117) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:1.20.6]
        at org.testcontainers.containers.GenericContainer.applyConfiguration(GenericContainer.java:783) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:1.20.6]
        at org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:381) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:1.20.6]
        at org.testcontainers.containers.GenericContainer.lambda$doStart$0(GenericContainer.java:346) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:1.20.6]
        at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:81) ~[na:na]
        at org.testcontainers.containers.GenericContainer.doStart(GenericContainer.java:336) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:1.20.6]
        at org.testcontainers.containers.GenericContainer.start(GenericContainer.java:322) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:1.20.6]
        at cz.publicstaticvoidmain.reproduce.demo.MyCommandLineRunner.run(DemoApplication.kt:54) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:na]
        at org.springframework.boot.SpringApplication.lambda$callRunner$5(SpringApplication.java:788) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:3.4.4]
        at org.springframework.util.function.ThrowingConsumer$1.acceptWithException(ThrowingConsumer.java:82) ~[na:na]
        at org.springframework.util.function.ThrowingConsumer.accept(ThrowingConsumer.java:60) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:6.2.5]
        at org.springframework.util.function.ThrowingConsumer$1.accept(ThrowingConsumer.java:86) ~[na:na]
        at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:796) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:3.4.4]
        at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:787) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:3.4.4]
        at org.springframework.boot.SpringApplication.lambda$callRunners$3(SpringApplication.java:772) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:3.4.4]
        at [email protected]/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184) ~[na:na]
        at [email protected]/java.util.stream.SortedOps$SizedRefSortingSink.end(SortedOps.java:357) ~[na:na]
        at [email protected]/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:510) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:na]
        at [email protected]/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:na]
        at [email protected]/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:na]
        at [email protected]/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174) ~[na:na]
        at [email protected]/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:na]
        at [email protected]/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:na]
        at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:772) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:3.4.4]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:325) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:3.4.4]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:3.4.4]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:3.4.4]
        at cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt.main(DemoApplication.kt:109) ~[cz.publicstaticvoidmain.reproduce.demo.DemoApplicationKt:na]
        at [email protected]/java.lang.invoke.LambdaForm$DMH/sa346b79c.invokeStaticInit(LambdaForm$DMH) ~[na:na]

2025-04-22T13:50:55.790Z  WARN 1 --- [demo] [           main] o.t.containers.ContainerDef              : Unable to mount a file from test host into a running container. This may be a misconfiguration or limitation of your Docker environment. Some features might not work.

Additional Information

No response

bedla avatar Apr 22 '25 13:04 bedla

related URLs to this topic

  • https://github.com/testcontainers/testcontainers-java/issues/7954
  • https://github.com/oracle/graal/issues/7682
  • https://github.com/Kehrlann/native-image-resource-fs/blob/main/src/test/java/wf/garnier/nativeimage/FilesystemTests.java

Seems that file (or dir tree) embedded into GraalVM native-image has to be extracted to temp-dir and mounted, like currently org.testcontainers.utility.MountableFile#extractClassPathResourceToTempLocation is doing the same with files inside .jar.

bedla avatar May 02 '25 08:05 bedla