programing

스프링 부트 2.5.0 및 잘못된 정의예외: Java 8 날짜/시간 유형 'java.time.Instant'는 기본적으로 지원되지 않습니다.

megabox 2023. 7. 23. 14:10
반응형

스프링 부트 2.5.0 및 잘못된 정의예외: Java 8 날짜/시간 유형 'java.time.Instant'는 기본적으로 지원되지 않습니다.

Spring Boot 2.4.5에서 Spring 2.5.0으로 업데이트한 후 애플리케이션 로그에서 다음과 같은 예외를 발견했습니다.

Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.Instant` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: org.telegram.telegrambots.meta.api.objects.Update["my_chat_member"]->org.telegram.telegrambots.meta.api.objects.ChatMemberUpdated["new_chat_member"]->org.telegram.telegrambots.meta.api.objects.ChatMember["untilDateAsInstant"])
    at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77) ~[jackson-databind-2.12.3.jar!/:2.12.3]
    at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1276) ~[jackson-databind-2.12.3.jar!/:2.12.3]
    at com.fasterxml.jackson.databind.ser.impl.UnsupportedTypeSerializer.serialize(UnsupportedTypeSerializer.java:35) ~[jackson-databind-2.12.3.jar!/:2.12.3]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728) ~[jackson-databind-2.12.3.jar!/:2.12.3]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:770) ~[jackson-databind-2.12.3.jar!/:2.12.3]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[jackson-databind-2.12.3.jar!/:2.12.3]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728) ~[jackson-databind-2.12.3.jar!/:2.12.3]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:770) ~[jackson-databind-2.12.3.jar!/:2.12.3]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[jackson-databind-2.12.3.jar!/:2.12.3]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728) ~[jackson-databind-2.12.3.jar!/:2.12.3]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:770) ~[jackson-databind-2.12.3.jar!/:2.12.3]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[jackson-databind-2.12.3.jar!/:2.12.3]
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480) ~[jackson-databind-2.12.3.jar!/:2.12.3]
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319) ~[jackson-databind-2.12.3.jar!/:2.12.3]
    at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1514) ~[jackson-databind-2.12.3.jar!/:2.12.3]
    at com.fasterxml.jackson.databind.ObjectWriter._writeValueAndClose(ObjectWriter.java:1215) ~[jackson-databind-2.12.3.jar!/:2.12.3]
    at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:1059) ~[jackson-databind-2.12.3.jar!/:2.12.3]
    at org.springframework.jms.support.converter.MappingJackson2MessageConverter.mapToTextMessage(MappingJackson2MessageConverter.java:279) ~[spring-jms-5.3.7.jar!/:5.3.7]
    at org.springframework.jms.support.converter.MappingJackson2MessageConverter.toMessage(MappingJackson2MessageConverter.java:184) ~[spring-jms-5.3.7.jar!/:5.3.7]
    ... 37 common frames omitted

이것은 나의 pom.xml입니다.

    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr310</artifactId>
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
    </dependency>

Spring Boot 2.4.5로 되돌렸는데 모든 것이 정상적으로 작동하는 것은 아닙니다.Spring Boot 2.5.0의 문제점은 무엇입니까?

업데이트됨

해당 GitHub https://github.com/spring-projects/spring-boot/issues/26859

저는 제 시험 수업 중 하나에서 문제를 발견했습니다.문제는 JavaTimeModule을 추가하지 않는 새 ObjectMapper 인스턴스를 만드는 것이었습니다.

다음은 봄 2.4.5에서 작동하지만 2.5.0/2.5.1에서 com.fasterxml.jackson.databind.exc에서 실패하는 테스트 예제입니다.잘못된 정의예외: Java 8 날짜/시간 유형java.time.ZonedDateTime기본적으로 지원되지 않음

Jackson-datatype-jsr310 버전의 업그레이드 때문일 수 있습니다.

package net.jpmchase.gti.gtfabric;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;

import java.time.ZonedDateTime;

public class ObjectMapperTest {

    @Test
    public void objectMapperTest() throws Exception{

        ZonedDateTime time = ZonedDateTime.now();
        ObjectMapper o = new ObjectMapper();
        o.writeValueAsString(time);
    }
}

이 특정 테스트 사례를 수정하려면 명시적으로

ObjectMapper o = new ObjectMapper();
o.registerModule(new JavaTimeModule()); 

스프링에서 제공하는 코드 객체 맵퍼에서 사용하지 않는 것일 수 있습니다.

잘못된 방법:

ObjectMapper o = new ObjectMapper();

올바른 방법:

@Autowired
Jackson2ObjectMapperBuilder mapperBuilder;

...

ObjectMapper mapper = mapperBuilder.build();

Spring Data Couchbase를 사용하는 경우 문제가 발생할 수 있습니다. https://github.com/spring-projects/spring-data-couchbase/blame/4.2.x/src/main/java/org/springframework/data/couchbase/config/AbstractCouchbaseConfiguration.java#L309

버그 보고서는 다음과 같습니다. https://github.com/spring-projects/spring-data-couchbase/issues/1209

이 문제는 Spring-Data-Couchbase 4.3에서 수정되었습니다.

미래의 나를 위한 적절한 답변을 게시하는 것 (잊어버리는):

@Configuration
public class JacksonConfig {

@Bean
public BatchConfigurer batchConfigurer(DataSource dataSource, PlatformTransactionManager transactionManager) {
    return new DefaultBatchConfigurer(dataSource) {
        @Override
        protected JobRepository createJobRepository() throws Exception {
            Jackson2ExecutionContextStringSerializer serializer = new Jackson2ExecutionContextStringSerializer();
            ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule()).findAndRegisterModules();
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);
            serializer.setObjectMapper(objectMapper);

            JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
            factory.setDataSource(dataSource);
            factory.setTransactionManager(transactionManager);
            factory.setSerializer(serializer);
            return factory.getObject();
        }
    };
}

}

출처: https://docs.spring.io/spring-batch/docs/current/reference/html/job.html

사이푸딘 머천트와 다위드 지비토-마니아코프스키는 도서관을 만들기 위해 서로 다르지만 동등하게 작동하는 방법을 제공했습니다.


<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.15.2</version>
</dependency>

실제로 작동합니다, 제 제안은 당신의 것에서 그것을 제거하는 것입니다.pom.xml완전하게 자신만의 직렬화기를 작성합니다( 예에서는 내부 정적 클래스로).

public static class CustomDateSerializer extends com.fasterxml.jackson.databind.ser.std.StdSerializer<LocalDateTime> {
        private static final long serialVersionUID = 4365897561L;
        public CustomDateSerializer() { 
            this(null); 
        } 
        public CustomDateSerializer(Class<LocalDateTime> t) {
            super(t); 
        }
        @Override
        public void serialize(
                LocalDateTime value, JsonGenerator gen, SerializerProvider arg2) 
          throws IOException, JsonProcessingException {
            gen.writeString(value.format(DateTimeFormatter.ofPattern("dd-MM-yyyy hh:mm:ss")));
        }
    }

그런 다음 JSON으로 직렬화할 개체의 시간 필드에 주석을 달습니다.

@JsonSerialize(using = CustomDateSerializer.class)
private LocalDateTime time = LocalDateTime.now();

코드가 많지 않죠?pom.xml종속성은 코드 자체의 5줄입니다.하지만 자동 배선은Jackson2ObjectMapperBuilder두 줄입니다. 또는 등록하기로 결정한 경우new JavaTimeModule()이은 부적절한 직렬화 제공하기 더 이 될 입니다. 의 포맷터를 이 "JavaTimeModule" (JavaTimeModule)에 해야 할 것입니다. 그래서 당신은 이것에 당신 자신의 포맷터를 연결해야 할 것입니다.JavaTimeModule어떻게든...아마도 당신이 원하는 것이 아닐 것입니다.

지정 하십시오. 사용자 지정 직렬화 장치에 합니다. 이 장치는 다음에 적합합니다.<LocalDateTime>여기요. 필요에 맞게 수정하세요.

언급URL : https://stackoverflow.com/questions/67874510/spring-boot-2-5-0-and-invaliddefinitionexception-java-8-date-time-type-java-ti

반응형