micronaut-projects / micronaut-core

Micronaut Application Framework
http://micronaut.io
Apache License 2.0
6.03k stars 1.05k forks source link

JacksonConfiguration.constructType throws ArrayIndexOutOfBoundsException for an Argument created from ParenthesizedType like Map<String,String> #10491

Open edward3h opened 6 months ago

edward3h commented 6 months ago

Expected Behavior

Given an Argument<Map<String, String>>, JacksonConfiguration.constructType(...) should return a valid result, regardless of how the Argument was constructed.

Actual Behaviour

In the circumstance I encountered, an ArrayIndexOutOfBoundsException was thrown.

Note that in my real application, I'm not calling JacksonConfiguration.constructType(...) directly - it's a consequence of using HttpClient.

Steps To Reproduce

Please see my test cases ConversionTests.java. The first test fails, the others pass.

The failing test is:

    @Test
    public void testMapStringString() {
        var generic = new GenericType<Map<String,String>>() {};
        var derived = Argument.of(generic.getType());
        var jacksonType = JacksonConfiguration.constructType(derived, objectMapper.getTypeFactory());
        Assertions.assertTrue(jacksonType.isMapLikeType());
    }

The constructType call throws ArrayIndexOutOfBoundsException

Environment Information

OS: Mac OS 14.2.1 JDK: corretto-17.0.6.10.1 or temurin-17.0.7+7

Example Application

https://github.com/edward3h/generictype_to_argument

Version

4.3.5

edward3h commented 6 months ago

My workaround is to use GenericTypeUtils as shown in my second test case.

    @Test
    public void testMapStringStringWithUtils() {
        var generic = new GenericType<Map<String,String>>() {};
        var derived = Argument.of(generic.getRawType(), GenericTypeUtils.resolveTypeArguments(generic.getType()));
        var jacksonType = JacksonConfiguration.constructType(derived, objectMapper.getTypeFactory());
        Assertions.assertTrue(jacksonType.isMapLikeType());
    }