zalando / problem

A Java library that implements application/problem+json
https://zalando.github.io/problem
MIT License
891 stars 83 forks source link

Unable to deserialize Problem with Jackson #356

Closed tinolazreg closed 1 year ago

tinolazreg commented 2 years ago

Description

We are using Java modules system, and our trying to use both problem and jackson-datatype-problem to be able to serialize and deserialize problems.

Example code:

var outOfStockProblem = Problem.builder()
        .withType(URI.create("https://example.org/out-of-stock"))
        .withTitle("Out of Stock")
        .withStatus(Status.BAD_REQUEST)
        .withDetail("Item B00027Y5QG is no longer available")
        .build();
ObjectMapper mapper = new ObjectMapper()
        .registerModule(new ProblemModule());
var serializedProblem = mapper.writeValueAsString(outOfStockProblem.toString());
var deserializedProblem = mapper.readValue(serializedProblem, Problem.class);

mapper.readValue(serializedProblem, Problem.class); throws an exception in this case with stack trace:

Failed to call `setAccess()` on Constructor 'org.zalando.problem.DefaultProblem' due to `java.lang.reflect.InaccessibleObjectException`, problem: Unable to make org.zalando.problem.DefaultProblem(java.net.URI,java.lang.String,org.zalando.problem.StatusType,java.lang.String,java.net.URI,org.zalando.problem.ThrowableProblem) accessible: module org.zalando.problem does not "opens org.zalando.problem" to module com.fasterxml.jackson.databind

Expected Behavior

Serialization and deserialization should work.

Actual Behavior

Exception is thrown.

Possible Fix

Seems like there are still more issues with how the Java modules are set-up.

Steps to Reproduce

See 'Description'

Context

Your Environment

ffroliva commented 2 years ago

any update on this?

anirudh708 commented 1 year ago

Should mapper.writeValueAsString(outOfStockProblem.toString()); be mapper.writeValueAsString(outOfStockProblem); in initial code snippet?

ffroliva commented 1 year ago

Add this to you code and it should solve the problem. It solved for me.

@RequiredArgsConstructor
@Configuration
@EnableWebMvc
public class WebConfiguration implements WebMvcConfigurer {

    @Autowired
    private final ObjectMapper objectMapper;

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(new MappingJackson2HttpMessageConverter(objectMapper));
    }

    @Bean
    public ObjectMapper objectMapper() {
        return new ObjectMapper()
                .registerModule(new Jdk8Module())
                .registerModule(new JavaTimeModule())
                .registerModule(new ProblemModule())
                .registerModule(new ConstraintViolationProblemModule());
    }
}