Приложение Spring Boot 3 работает на встроенном Tomcat, но не на внешнем

Я обновляю наше приложение с Spring Boot 2.7.10 до 3.0.5.

Я также запускаю его из IDE на встроенном Tomcat и внешнем Tomcat (версия 9 для Spring Boot 2.7.x). Сейчас я использую Tomcat 10.1.7 и Jackson 2.14.2.

Он по-прежнему работает на встроенном Tomcat, но не на внешнем Tomcat 10. Я получаю:

Failed to bind properties under 'my-configuration.object-mapper.serializer-provider.generator.write-capabilities' to com.fasterxml.jackson.core.util.JacksonFeatureSet<com.fasterxml.jackson.core.StreamWriteCapability>:

    Reason: org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'my-configuration.object-mapper.serializer-provider.generator.write-capabilities' to com.fasterxml.jackson.core.util.JacksonFeatureSet<com.fasterxml.jackson.core.StreamWriteCapability>

С использованием

@ConfigurationProperties(prefix = "my-configuration")
@Getter
@Setter
public class MyConfiguration {
    private ObjectMapper objectMapper;
}

Я могу подавить ошибку, указав ignoreInvalidFields, но убедиться, что это правильное решение.

@ConfigurationProperties(prefix = "my-configuration", ignoreInvalidFields = true)

Несомненно, мне нужно реорганизовать наши классы конфигурации, но все же я хотел бы понять, что происходит и почему происходит сбой после Spring Boot 3 и только внешнего Tomcat.

Трассировки стека

    Caused by: org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'my-configuration.object-mapper.serializer-provider.generator.write-capabilities' to com.fasterxml.jackson.core.util.JacksonFeatureSet<com.fasterxml.jackson.core.StreamWriteCapability>
        at org.springframework.boot.context.properties.bind.Binder.handleBindError(Binder.java:387)
        at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:347)
        at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$4(Binder.java:472)
        at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:98)
        at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:86)
        at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:62)
        at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$5(Binder.java:476)
        at org.springframework.boot.context.properties.bind.Binder$Context.withIncreasedDepth(Binder.java:590)
        at org.springframework.boot.context.properties.bind.Binder$Context.withDataObject(Binder.java:576)
        at org.springframework.boot.context.properties.bind.Binder.bindDataObject(Binder.java:474)
        at org.springframework.boot.context.properties.bind.Binder.bindObject(Binder.java:414)
        at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:343)
        at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$4(Binder.java:472)
        at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:98)
        at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:86)
        at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:62)
        at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$5(Binder.java:476)
        at org.springframework.boot.context.properties.bind.Binder$Context.withIncreasedDepth(Binder.java:590)
        at org.springframework.boot.context.properties.bind.Binder$Context.withDataObject(Binder.java:576)
        at org.springframework.boot.context.properties.bind.Binder.bindDataObject(Binder.java:474)
        at org.springframework.boot.context.properties.bind.Binder.bindObject(Binder.java:414)
        at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:343)
        at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$4(Binder.java:472)
        at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:98)
        at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:86)
        at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:62)
        at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$5(Binder.java:476)
        at org.springframework.boot.context.properties.bind.Binder$Context.withIncreasedDepth(Binder.java:590)
        at org.springframework.boot.context.properties.bind.Binder$Context.withDataObject(Binder.java:576)
        at org.springframework.boot.context.properties.bind.Binder.bindDataObject(Binder.java:474)
        at org.springframework.boot.context.properties.bind.Binder.bindObject(Binder.java:414)
        at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:343)
        at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$4(Binder.java:472)
        at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:98)
        at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:86)
        at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:62)
        at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$5(Binder.java:476)
        at org.springframework.boot.context.properties.bind.Binder$Context.withIncreasedDepth(Binder.java:590)
        at org.springframework.boot.context.properties.bind.Binder$Context.withDataObject(Binder.java:576)
        at org.springframework.boot.context.properties.bind.Binder.bindDataObject(Binder.java:474)
        at org.springframework.boot.context.properties.bind.Binder.bindObject(Binder.java:414)
        at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:343)
        at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$4(Binder.java:472)
        at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:98)
        at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:86)
        at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:62)
        at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$5(Binder.java:476)
        at org.springframework.boot.context.properties.bind.Binder$Context.withIncreasedDepth(Binder.java:590)
        at org.springframework.boot.context.properties.bind.Binder$Context.withDataObject(Binder.java:576)
        at org.springframework.boot.context.properties.bind.Binder.bindDataObject(Binder.java:474)
        at org.springframework.boot.context.properties.bind.Binder.bindObject(Binder.java:414)
        at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:343)
        at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:332)
        at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:262)
        at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:249)
        at org.springframework.boot.context.properties.ConfigurationPropertiesBinder.bind(ConfigurationPropertiesBinder.java:93)
        at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.bind(ConfigurationPropertiesBindingPostProcessor.java:96)
        ... 121 more
    Caused by: java.lang.IllegalStateException: Unable to get value for property write-capabilities
        at org.springframework.boot.context.properties.bind.JavaBeanBinder$BeanProperty.lambda$getValue$0(JavaBeanBinder.java:360)
        at org.springframework.boot.context.properties.bind.DefaultBindConstructorProvider.getBindConstructor(DefaultBindConstructorProvider.java:46)
        at org.springframework.boot.context.properties.bind.ValueObjectBinder$ValueObject.get(ValueObjectBinder.java:190)
        at org.springframework.boot.context.properties.bind.ValueObjectBinder.bind(ValueObjectBinder.java:67)
        at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$5(Binder.java:476)
        at org.springframework.boot.context.properties.bind.Binder$Context.withIncreasedDepth(Binder.java:590)
        at org.springframework.boot.context.properties.bind.Binder$Context.withDataObject(Binder.java:576)
        at org.springframework.boot.context.properties.bind.Binder.bindDataObject(Binder.java:474)
        at org.springframework.boot.context.properties.bind.Binder.bindObject(Binder.java:414)
        at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:343)
        ... 176 more
    Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.fasterxml.jackson.core.JsonGenerator]: Is it an abstract class?
        at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:215)
        at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:153)
        at org.springframework.boot.context.properties.bind.JavaBeanBinder$Bean.lambda$getSupplier$0(JavaBeanBinder.java:217)
        at org.springframework.boot.context.properties.bind.JavaBeanBinder$BeanSupplier.get(JavaBeanBinder.java:279)
        at org.springframework.boot.context.properties.bind.JavaBeanBinder$BeanProperty.lambda$getValue$0(JavaBeanBinder.java:357)
        ... 185 more
    Caused by: java.lang.InstantiationException
        at java.base/jdk.internal.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:48)
        at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
        at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:198)
        ... 189 more

Что вы пытаетесь сделать? Почему бы вам просто не использовать свойства spring.jackson для настройки привязки?

M. Deinum 18.04.2023 15:03

Устаревшая конфигурация остальных клиентов. В любом случае, главный вопрос в том, почему встроенный кот ведет себя не так, как внешний?

banterCZ 18.04.2023 15:06

Если вы не создадите свой собственный ObjectMapper, это повлияет на глобальный. Почему он другой, сказать сложно, это та же версия, что и встроенная? Пожалуйста, включите полную трассировку стека вместо фрагмента.

M. Deinum 18.04.2023 15:09

Добавлена ​​трассировка стека. Несомненно, мне нужно реорганизовать наши классы конфигурации, но все же я хотел бы понять, что происходит и почему происходит сбой после Spring Boot 3 и только внешнего Tomcat.

banterCZ 19.04.2023 07:16

Существуют ли какие-либо дополнительные библиотеки, входящие в состав установки yur tomcat, которые мешают добавленным зависимостям Spring?

M. Deinum 19.04.2023 08:37

Это свежий новый Tomcat. Интересно, отличается ли загрузка классов. Я собирался сообщить об этом команде Spring, но когда я попробовал базовый проект, я не смог его воспроизвести. Я должен копнуть глубже, какая зависимость вызывает такое столкновение.

banterCZ 20.04.2023 10:11

Может быть проблема с зависимостями, что при построении войны конфликтующая зависимость имеет приоритет над другой при запуске в командной строке. Может быть разница в ОС (Windows, Linux и Mac иногда имеют разные порядки разрешения для пути к классу).

M. Deinum 20.04.2023 10:16

Наконец, у меня есть минимальный проект для воспроизведения. Я открыл вопрос github.com/spring-projects/spring-boot/issues/35091

banterCZ 20.04.2023 10:37
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
8
127
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как объясняется в выпуске https://github.com/spring-projects/spring-boot/issues/35091#issuecomment-1516051146 основная причина в том, что на внешнем Tomcat включен JNDI.

Это влияет на привязку свойства. JNDI не позволяет перечислять все свойства, которые он содержит, поэтому вместо того, чтобы находить все свойства и привязывать их к целям, Spring вместо этого должен запрашивать все цели, какие свойства у них есть, а затем пытаться их связать. Это когда ObjectMapper вызывает проблему.

Другие вопросы по теме