javamicronautsuppress-warningsmicronaut-serde

Deserializing with generics using Micronaut Serialization without using @SuppressWarnings("unchecked")


I try to deserialize a generic Object W<T> from JSON with Micronaut Serialization , it works, but the compiler produces an "unchecked assignment" warning.

I would like to achieve the same result without the warning or using @SuppressWarnings("unchecked").

The following is a reduced version of the code I use. It works, but there is a @SuppressWarnings("unchecked") annotation.

1st note: The ObjectMapper is not the Jackson ObjectMapper, but the io.micronaut.serde.ObjectMapper
2nd note: I removed common java and slf4j imports for brevity

import io.micronaut.context.annotation.Prototype;
import io.micronaut.core.type.Argument;
import io.micronaut.serde.ObjectMapper;
import jakarta.inject.Inject;

@Prototype
public class Scratch {
    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
    private final ObjectMapper objectMapper;

    @Inject
    public Scratch(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @SuppressWarnings("unchecked")
    private Optional<CommonResponse<JobResponse>> getCommonResponse(final String entry) {
        try {
            return Optional.of(objectMapper.readValue(entry, Argument.of(CommonResponse.class, JobResponse.class)));
        } catch (IOException e) {
            LOG.warn("Could not deserialize, skipping entry: '{}'", entry, e);
        }
        return Optional.empty();
    }
}

Solution

  • There is no way to achieve this with Argument.of, but there is GenericArgument which is exactly what is needed.

    Full example:

    import io.micronaut.context.annotation.Prototype;
    import io.micronaut.core.type.GenericArgument;
    import io.micronaut.serde.ObjectMapper;
    import jakarta.inject.Inject;
    
    @Prototype
    public class Scratch {
        private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
        private final ObjectMapper objectMapper;
    
        @Inject
        public Scratch(ObjectMapper objectMapper) {
            this.objectMapper = objectMapper;
        }
    
        private Optional<CommonResponse<JobResponse>> getCommonResponse(final String entry) {
            try {
                return Optional.of(objectMapper.readValue(entry, new GenericArgument<>() {}));
            } catch (IOException e) {
               LOG.warn("Could not deserialize, skipping entry: '{}'", entry, e);
            }
            return Optional.empty();
        }
    }
    

    See https://github.com/micronaut-projects/micronaut-core/issues/2204