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

Null key for a Map not allowed in JSON (use a converting NullKeySerializer?) on withCreateContainerCmdModifier and withNetwork

Open cheatmenot opened this issue 3 years ago • 9 comments

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!

cheatmenot avatar Mar 25 '22 12:03 cheatmenot

Hi , did you resolve this issue?

mansinigam-maersk avatar Apr 26 '22 13:04 mansinigam-maersk

I have stumbled upon the same issue...however for me when I remove the network option the container still does not start.

amihaescu-8x8 avatar Apr 29 '22 16:04 amihaescu-8x8

I used setPortBinding instead of HostConfig and it worked for me

container.getPortBindings().add("4444:4444");
container.getPortBindings().add("6900:5900");

rudreshtrivedi avatar Aug 05 '22 09:08 rudreshtrivedi

@cheatmenot Thanks for the issue. I've been able to reproduce it on my end. Will investigate tomorrow.

aidando73 avatar Sep 02 '22 07:09 aidando73

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?

aidando73 avatar Sep 03 '22 04:09 aidando73

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.

aidando73 avatar Sep 03 '22 06:09 aidando73

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.

aidando73 avatar Sep 08 '22 08:09 aidando73

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.

eddumelendez avatar Sep 09 '22 22:09 eddumelendez

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

aidando73 avatar Sep 13 '22 12:09 aidando73