-
Notifications
You must be signed in to change notification settings - Fork 41.6k
Description
Environment
- Spring Boot: 4.0.0-RC1
- Jackson: 3.0.1
- Container runtime: Podman 5.6.2 with all Docker compatibility features enabled
- Spring Modulith: 2.0-RC1
- macOS 26.1
Description
When using the spring-boot-docker-compose dependency with Podman instead of Docker, the startup fails because of the change in Jackson 3.0 to set FAIL_ON_NULL_FOR_PRIMITIVES to true.
This would not be an issue, if it was possible to set this back to false using either application.properties or JsonMapperBuilderCustomizer, but this does not seem to be possible because of the timing during application startup and the early initialization of the Docker Compose feature. Neither setting is picked up and therefore the deserialization in DockerJson and the static configuration cannot be changed.
The root cause for the issue is the different response Podman gives to the docker context ls command. This does not conform with the Docker response as it does not include a current field, which is in turn a primitive boolean in DockerCliContextResponse. This causes the issue with the new Jackson 3.0 defaults.
Podman response to docker context ls:
{"Name":"podman-machine-default","URI":"ssh://core@127.0.0.1:55599/run/user/501/podman/podman.sock","Identity":"/Users/user/.local/share/containers/podman/machine/machine","IsMachine":true,"Default":false,"ReadWrite":true}
{"Name":"podman-machine-default-root","URI":"ssh://root@127.0.0.1:55599/run/podman/podman.sock","Identity":"/Users/user/.local/share/containers/podman/machine/machine","IsMachine":true,"Default":true,"ReadWrite":true}Full stacktrace of the issue:
tools.jackson.databind.exc.MismatchedInputException: Cannot map `null` into type `boolean` (set DeserializationConfig.DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES to 'false' to allow)
at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); byte offset: #UNKNOWN] (through reference chain: org.springframework.boot.docker.compose.core.DockerCliContextResponse["current"])
at tools.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:67) ~[jackson-databind-3.0.1.jar:3.0.1]
at tools.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1802) ~[jackson-databind-3.0.1.jar:3.0.1]
at tools.jackson.databind.deser.jdk.NumberDeserializers$PrimitiveOrWrapperDeserializer.getNullValue(NumberDeserializers.java:167) ~[jackson-databind-3.0.1.jar:3.0.1]
at tools.jackson.databind.ValueDeserializer.getAbsentValue(ValueDeserializer.java:384) ~[jackson-databind-3.0.1.jar:3.0.1]
at tools.jackson.databind.deser.bean.PropertyValueBuffer._findMissing(PropertyValueBuffer.java:279) ~[jackson-databind-3.0.1.jar:3.0.1]
at tools.jackson.databind.deser.bean.PropertyValueBuffer.getParameters(PropertyValueBuffer.java:208) ~[jackson-databind-3.0.1.jar:3.0.1]
at tools.jackson.databind.deser.ValueInstantiator.createFromObjectWith(ValueInstantiator.java:270) ~[jackson-databind-3.0.1.jar:3.0.1]
at tools.jackson.databind.deser.bean.PropertyBasedCreator.build(PropertyBasedCreator.java:252) ~[jackson-databind-3.0.1.jar:3.0.1]
at tools.jackson.databind.deser.bean.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:697) ~[jackson-databind-3.0.1.jar:3.0.1]
at tools.jackson.databind.deser.bean.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1417) ~[jackson-databind-3.0.1.jar:3.0.1]
at tools.jackson.databind.deser.bean.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:480) ~[jackson-databind-3.0.1.jar:3.0.1]
at tools.jackson.databind.deser.bean.BeanDeserializer.deserialize(BeanDeserializer.java:200) ~[jackson-databind-3.0.1.jar:3.0.1]
at tools.jackson.databind.deser.DeserializationContextExt.readRootValue(DeserializationContextExt.java:265) ~[jackson-databind-3.0.1.jar:3.0.1]
at tools.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2610) ~[jackson-databind-3.0.1.jar:3.0.1]
at tools.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:1564) ~[jackson-databind-3.0.1.jar:3.0.1]
at org.springframework.boot.docker.compose.core.DockerJson.deserialize(DockerJson.java:73) ~[spring-boot-docker-compose-4.0.0-RC1.jar:4.0.0-RC1]
at org.springframework.boot.docker.compose.core.DockerJson.deserialize(DockerJson.java:69) ~[spring-boot-docker-compose-4.0.0-RC1.jar:4.0.0-RC1]
at org.springframework.boot.docker.compose.core.DockerJson.lambda$deserializeToList$0(DockerJson.java:58) ~[spring-boot-docker-compose-4.0.0-RC1.jar:4.0.0-RC1]
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) ~[na:na]
at java.base/java.lang.StringLatin1$LinesSpliterator.forEachRemaining(StringLatin1.java:688) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:575) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:616) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:622) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.toList(ReferencePipeline.java:627) ~[na:na]
at org.springframework.boot.docker.compose.core.DockerJson.deserializeToList(DockerJson.java:58) ~[spring-boot-docker-compose-4.0.0-RC1.jar:4.0.0-RC1]
at org.springframework.boot.docker.compose.core.DockerCliCommand.deserialize(DockerCliCommand.java:85) ~[spring-boot-docker-compose-4.0.0-RC1.jar:4.0.0-RC1]
at org.springframework.boot.docker.compose.core.DockerCli.run(DockerCli.java:83) ~[spring-boot-docker-compose-4.0.0-RC1.jar:4.0.0-RC1]
at org.springframework.boot.docker.compose.core.DefaultDockerCompose.lambda$new$0(DefaultDockerCompose.java:48) ~[spring-boot-docker-compose-4.0.0-RC1.jar:4.0.0-RC1]
at org.springframework.boot.docker.compose.core.DockerHost.fromCurrentContext(DockerHost.java:104) ~[spring-boot-docker-compose-4.0.0-RC1.jar:4.0.0-RC1]
at org.springframework.boot.docker.compose.core.DockerHost.get(DockerHost.java:90) ~[spring-boot-docker-compose-4.0.0-RC1.jar:4.0.0-RC1]
at org.springframework.boot.docker.compose.core.DockerHost.get(DockerHost.java:75) ~[spring-boot-docker-compose-4.0.0-RC1.jar:4.0.0-RC1]
at org.springframework.boot.docker.compose.core.DefaultDockerCompose.<init>(DefaultDockerCompose.java:48) ~[spring-boot-docker-compose-4.0.0-RC1.jar:4.0.0-RC1]
at org.springframework.boot.docker.compose.core.DockerCompose.get(DockerCompose.java:148) ~[spring-boot-docker-compose-4.0.0-RC1.jar:4.0.0-RC1]
at org.springframework.boot.docker.compose.lifecycle.DockerComposeLifecycleManager.getDockerCompose(DockerComposeLifecycleManager.java:166) ~[spring-boot-docker-compose-4.0.0-RC1.jar:4.0.0-RC1]
at org.springframework.boot.docker.compose.lifecycle.DockerComposeLifecycleManager.start(DockerComposeLifecycleManager.java:114) ~[spring-boot-docker-compose-4.0.0-RC1.jar:4.0.0-RC1]
at org.springframework.boot.docker.compose.lifecycle.DockerComposeListener.onApplicationEvent(DockerComposeListener.java:53) ~[spring-boot-docker-compose-4.0.0-RC1.jar:4.0.0-RC1]
at org.springframework.boot.docker.compose.lifecycle.DockerComposeListener.onApplicationEvent(DockerComposeListener.java:35) ~[spring-boot-docker-compose-4.0.0-RC1.jar:4.0.0-RC1]
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:180) ~[spring-context-7.0.0-RC2.jar:7.0.0-RC2]
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:173) ~[spring-context-7.0.0-RC2.jar:7.0.0-RC2]
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:151) ~[spring-context-7.0.0-RC2.jar:7.0.0-RC2]
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:133) ~[spring-context-7.0.0-RC2.jar:7.0.0-RC2]
at org.springframework.boot.context.event.EventPublishingRunListener.multicastInitialEvent(EventPublishingRunListener.java:137) ~[spring-boot-4.0.0-RC1.jar:4.0.0-RC1]
at org.springframework.boot.context.event.EventPublishingRunListener.contextLoaded(EventPublishingRunListener.java:99) ~[spring-boot-4.0.0-RC1.jar:4.0.0-RC1]
at org.springframework.boot.SpringApplicationRunListeners.lambda$contextLoaded$0(SpringApplicationRunListeners.java:74) ~[spring-boot-4.0.0-RC1.jar:4.0.0-RC1]
at java.base/java.lang.Iterable.forEach(Iterable.java:75) ~[na:na]
at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:123) ~[spring-boot-4.0.0-RC1.jar:4.0.0-RC1]
at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:117) ~[spring-boot-4.0.0-RC1.jar:4.0.0-RC1]
at org.springframework.boot.SpringApplicationRunListeners.contextLoaded(SpringApplicationRunListeners.java:74) ~[spring-boot-4.0.0-RC1.jar:4.0.0-RC1]
at org.springframework.boot.SpringApplication.prepareContext(SpringApplication.java:418) ~[spring-boot-4.0.0-RC1.jar:4.0.0-RC1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320) ~[spring-boot-4.0.0-RC1.jar:4.0.0-RC1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1374) ~[spring-boot-4.0.0-RC1.jar:4.0.0-RC1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363) ~[spring-boot-4.0.0-RC1.jar:4.0.0-RC1]
at com.example.demo.DemoApplication.main(DemoApplication.java:14) ~[main/:na]
I found no way to make the Docker Compose feature work with Podman in Spring Boot 4.0.0-RC1 because of this issue. I know there is some discussion about adding full Podman support in the future, but until then it would be great if the Docker Compose feature would work as it did in Spring Boot 3.5.