testcontainers-java: com.github.docker-java is not shaded and conflicts with the project's version

Adding com.github.docker-java:docker-java to a project that uses testcontainers creates dependency conflicts. In a way this issue is related to this one but that one is closed.

This example with the below dependencies demonstrate the problem

import org.junit.Test;
import org.testcontainers.containers.MySQLContainer;

public class DockerJavaTest {
    @Test
    public void dockerJavaTest() {
        MySQLContainer mySQLContainer = new MySQLContainer();
        mySQLContainer.start();
        mySQLContainer.stop();
    }
}
plugins {
    id 'java'
}

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    testCompile 'com.github.docker-java:docker-java:3.0.6'
    testCompile "org.testcontainers:testcontainers:1.10.4"
    testCompile "org.testcontainers:mysql:1.10.4"
    testCompile "ch.qos.logback:logback-classic:1.2.2"
    testCompile group: 'junit', name: 'junit', version: '4.12'
}
org.testcontainers.shaded.com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "ID" (class com.github.dockerjava.api.model.Info), not marked as ignorable (48 known properties: "systemStatus", "ipv4Forwarding", "httpsProxy", "discoveryBackend", "httpProxy", "clusterStore", "cpuCfsPeriod", "dockerRootDir", "containersRunning", "operatingSystem", "containers", "architecture", "initPath", "cpuSet", "containersStopped", "systemTime", "oomKillDisable", "registryConfig", "containersPaused", "oomScoreAdj", "experimentalBuild", "loggingDriver", "driver", "nfd", "noProxy", "memTotal", "cpuCfsQuota", "bridgeNfIp6tables", "initSha1", "images", "memoryLimit", "cpuShares", "osType", "indexServerAddress", "name", "bridgeNfIptables", "debug", "serverVersion", "id", "plugins", "driverStatuses", "ncpu", "labels", "executionDriver", "kernelVersion", "sockets", "swapLimit", "clusterAdvertise"])
 at [Source: buffer(org.testcontainers.shaded.okhttp3.internal.http1.Http1Codec$ChunkedSource@4f209819).inputStream(); line: 1, column: 8] (through reference chain: com.github.dockerjava.api.model.Info["ID"])

	at org.testcontainers.shaded.com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:51)
	at org.testcontainers.shaded.com.fasterxml.jackson.databind.DeserializationContext.reportUnknownProperty(DeserializationContext.java:839)
	at org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1045)
	at org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1352)
	at org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1330)
	at org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:264)
	at org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:125)
	at org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3736)
	at org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2803)
	at org.testcontainers.dockerclient.transport.okhttp.OkHttpInvocationBuilder.get(OkHttpInvocationBuilder.java:101)
	at com.github.dockerjava.core.exec.InfoCmdExec.exec(InfoCmdExec.java:24)
	at com.github.dockerjava.core.exec.InfoCmdExec.exec(InfoCmdExec.java:14)
	at com.github.dockerjava.core.command.AbstrDockerCmd.exec(AbstrDockerCmd.java:35)
	at org.testcontainers.DockerClientFactory.client(DockerClientFactory.java:112)
	at org.testcontainers.containers.GenericContainer.<init>(GenericContainer.java:162)
	at org.testcontainers.containers.JdbcDatabaseContainer.<init>(JdbcDatabaseContainer.java:40)
	at org.testcontainers.containers.MySQLContainer.<init>(MySQLContainer.java:24)
	at DockerJavaTest.dockerJavaTest(DockerJavaTest.java:8)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 6
  • Comments: 20 (6 by maintainers)

Most upvoted comments

@dagguh I reopened it, we’re working with docker-java team on splitting it into modules, so that we can depend on docker-java-api directly. docker-java’s upcoming 3.2.0 release will make it possible

@dagguh yes (I am the author of it 😅).

We will do a release of Testcontainers with docker-java 3.2.0 and a few deprecations to let everyone update their usages and the next one most probably will finally stop shading docker-java-api.

@nasis oh, I think I know what happens. Darn!

Your InfoCmdExec#exec (from original docker-java) calls .get with TypeReference of non-shaded Jackson.

We will try to fix it. Meanwhile, you can try removing docker-java dependency from your classpath and use the one shipped with Testcontainers. It is the same docker-java, but with OkHttp transport and fewer dependencies. Sorry 😞

Thanks for the fast response @bsideup but that still doesn’t solve the issue entirely. Moving to the release notes version of docker-java:3.1.0-rc-4 has a different conflict

java.lang.AbstractMethodError: org.testcontainers.dockerclient.transport.okhttp.OkHttpInvocationBuilder.get(Lcom/fasterxml/jackson/core/type/TypeReference;)Ljava/lang/Object;

	at com.github.dockerjava.core.exec.InfoCmdExec.exec(InfoCmdExec.java:24)
	at com.github.dockerjava.core.exec.InfoCmdExec.exec(InfoCmdExec.java:14)
	at com.github.dockerjava.core.command.AbstrDockerCmd.exec(AbstrDockerCmd.java:35)
	at org.testcontainers.DockerClientFactory.client(DockerClientFactory.java:112)
	at org.testcontainers.containers.GenericContainer.<init>(GenericContainer.java:162)
	at org.testcontainers.containers.JdbcDatabaseContainer.<init>(JdbcDatabaseContainer.java:40)
	at org.testcontainers.containers.MySQLContainer.<init>(MySQLContainer.java:24)
	at DockerJavaTest.dockerJavaTest(DockerJavaTest.java:8)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
dependencies {
    testCompile 'com.github.docker-java:docker-java:3.1.0-rc-4'
    testCompile "org.testcontainers:testcontainers:1.10.4"
    testCompile "org.testcontainers:mysql:1.10.4"
    testCompile "ch.qos.logback:logback-classic:1.2.2"
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

This is quite a vicious cycle. I couldn’t find a pair of testcontainers and docker-java that can pass this test successfully.

Hi @nasis!

We plan to remove “embedded” docker-java as soon as they ship a modularised version of it so that we can opt out of Netty code (we use OkHttp now).

Sorry, the problem is known, but unfortunately, there is not much we can do. However, we continuously update docker-java to the latest version ASAP, in case you can afford using the latest code from docker-java.