Netflix / archaius

Library for configuration management API
Apache License 2.0
2.47k stars 485 forks source link

Avoid class cast exceptions in array and enum converters #703

Closed kilink closed 8 months ago

kilink commented 8 months ago

If a ParameterizedType was passed to ArrayTypeConverterFactory or EnumTypeConverterFactory, a ClassCastException would be thrown when it attempted to unconditionally cast it to Class; update the factories to handle this more gracefully by just returning Optional.empty().

Additionally, update ArrayTypeConverterFactory to handle arrays of primitives, and add unit tests for Enums, arrays, and collections.

rgallardo-netflix commented 8 months ago

As a curiosity, does the existing code not handle primitive arrays at all, or does it handle them inefficiently, with boxing convertions?

kilink commented 8 months ago

As a curiosity, does the existing code not handle primitive arrays at all, or does it handle them inefficiently, with boxing convertions?

It didn't handle them at all, which I found out when I started adding some unit tests to cover some missing conversions. We could also decide to not support primitive arrays if you think it's not needed. I guess it's not really used at all if no one ever complained, or maybe they hit it and switch to the boxed type?

Here's the exception you would hit if you're curious:

DefaultDecoder.INSTANCE.decode(int[].class, "1,2,3,4");
com.netflix.archaius.exceptions.ParseException: Error decoding type `int[]`
    at com.netflix.archaius.AbstractRegistryDecoder.decode(AbstractRegistryDecoder.java:51)
    at com.netflix.archaius.DefaultDecoder.decode(DefaultDecoder.java:29)
    at com.netflix.archaius.AbstractRegistryDecoder.decode(AbstractRegistryDecoder.java:35)
    at com.netflix.archaius.DefaultDecoder.decode(DefaultDecoder.java:29)
       ...
Caused by: java.lang.ClassCastException: [I cannot be cast to [Ljava.lang.Object;
    at com.netflix.archaius.converters.ArrayTypeConverterFactory.lambda$create$1(ArrayTypeConverterFactory.java:33)
    at com.netflix.archaius.AbstractRegistryDecoder.decode(AbstractRegistryDecoder.java:49)
rgallardo-netflix commented 8 months ago

I'll merge this with the primitives support. The question was more about how to word the release notes :-)