testcontainers-java
testcontainers-java copied to clipboard
Null key for a Map not allowed in JSON (use a converting NullKeySerializer?) on withCreateContainerCmdModifier and withNetwork
I was using GenericContainer below and encounter issue
Caused by: org.testcontainers.shaded.com.fasterxml.jackson.databind.JsonMappingException: Null key for a Map not allowed in JSON (use a converting NullKeySerializer?) (through reference chain: org.testcontainers.shaded.com.github.dockerjava.core.command.CreateContainerCmdImpl["NetworkingConfig"]->org.testcontainers.shaded.com.github.dockerjava.core.command.CreateContainerCmdImpl$NetworkingConfig["EndpointsConfig"])
GenericContainer<?> xContainer = new GenericContainer<>("x:latest")
.withExposedPorts(8080)
.withCreateContainerCmdModifier(cmd -> cmd.withHostConfig(
new HostConfig().withPortBindings(new PortBinding(Ports.Binding.bindPort(8080), new ExposedPort(8081)))
))
.withNetwork(network);
further investigation shows that the error exists only when withCreateContainerCmdModifier and withNetwork are used at the same time. If they are used without the other it works. But I need both of them one for mapping to a new port and the other one for networking capabilities. Please advice. Thanks!
Hi , did you resolve this issue?
I have stumbled upon the same issue...however for me when I remove the network option the container still does not start.
I used setPortBinding instead of HostConfig and it worked for me
container.getPortBindings().add("4444:4444");
container.getPortBindings().add("6900:5900");
@cheatmenot Thanks for the issue. I've been able to reproduce it on my end. Will investigate tomorrow.
Still looking into the root cause of this issue. But I've found that using the previous host config doesn't throw the exception:
GenericContainer<?> xContainer = new GenericContainer<>("x:latest")
.withExposedPorts(8080)
.withCreateContainerCmdModifier(cmd -> {
cmd.getHostConfig().withPortBindings(new PortBinding(Ports.Binding.bindPort(8080), new ExposedPort(8081));
}))
.withNetwork(network);
@cheatmenot does this or what @rudreshtrivedi suggested work as a workaround?
As for the technical details, GenericContainer internally generates it's own HostConfig and applies certain settings (See GenericContainer$applyConfiguration). When you create a new host config in GenericContainer$withCreateContainerCmdModifier, you overwrite the one generated by GenericContainer. This can cause undefined behavior - thus it's recommended to modify the existing host config instead of creating a new one.
How to make this a bit more clear for users I'm not sure atm.
And as for why it's throwing this weird exception, still drilling down to the root cause.
I think this is a bug from docker-java. I've submitted an issue for it above. Not sure if we can do anything on Testcontainer's side until there's a fix for it.
thanks for the discovery @REslim30 ! from testcontainers' point of view, it is right what you said HostConfig is already created by GenericContainer. So, doing something like it was initially proposed will override some configuration. It is also mentioned in the docs
Any customizations you make using withCreateContainerCmdModifier will be applied on top of the container definition that Testcontainers creates, but before it is created.
Potentially, we could add in a note there saying to opt for modifying nested objects like authConfig, healthCheck, hostConfig, networkingConfig volumes, instead of creating new ones as test containers might have configured its own version. We can add in an example of what to avoid and what to do instead. I can submit a PR for this