pinpoint-apm/pinpoint · error · ConfigurationException
unsupported data type :<fieldName>
Error message
unsupported data type :<fieldName>
What it means
ValueAnnotationProcessor injects @Value-annotated properties into setter methods via reflection. After parsing the string value, parse() returns null only if the setter's single parameter type is not one of the supported types (String, primitives/wrappers, enum). The processor then throws ConfigurationException naming the target class.field so the developer knows which config property could not be injected.
Source
Thrown at commons-config/src/main/java/com/navercorp/pinpoint/common/config/util/ValueAnnotationProcessor.java:141
private void setAccessible(AccessibleObject accessibleObject) {
if (!accessibleObject.isAccessible()) {
accessibleObject.setAccessible(true);
}
}
private void injectMethod(Method method, Object target, String value) {
final Class<?> parameterType = method.getParameterTypes()[0];
final Object parsedValue = parse(parameterType, value);
if (parsedValue != null) {
try {
setAccessible(method);
method.invoke(target, parsedValue);
} catch (ReflectiveOperationException e) {
throw new ConfigurationException(getFieldName(target, method) + " access error", e);
}
} else {
throw new ConfigurationException("unsupported data type :" + getFieldName(target, method));
}
}
@SuppressWarnings({"unchecked", "rawtypes"})
private Object parse(Class<?> type, String value) {
if (type.isEnum()) {
return Enum.valueOf((Class<Enum>) type, value);
}
if (type == String.class) {
return value;
} else if (type == int.class || type == Integer.class) {
return Integer.parseInt(value);
} else if (type == long.class || type == Long.class) {
return Long.parseLong(value);
} else if (type == boolean.class || type == Boolean.class) {
return Boolean.parseBoolean(value);
} else if (type == double.class || type == Double.class) {View on GitHub (pinned to 744c3d3075)
Solutions
- Change the setter's parameter type to String, a primitive/wrapper, or an enum type supported by parse()
- Parse the complex value inside the setter body from a String parameter
- Remove the @Value annotation from the unsupported setter and initialize it manually in the constructor
Example fix
// before
@Value("${collector.list}")
public void setListeners(List<String> listeners) { ... }
// after
@Value("${collector.list}")
public void setListeners(String listenersCsv) { this.listeners = Arrays.asList(listenersCsv.split(",")); } Defensive patterns
Strategy: validation
Validate before calling
Class<?> p = setter.getParameterTypes()[0];
boolean ok = p == String.class || p.isEnum()
|| p == int.class || p == Integer.class || p == long.class || p == Long.class
|| p == boolean.class || p == Boolean.class || p == double.class || p == Double.class
|| p == float.class || p == Float.class || p == short.class || p == Short.class
|| p == byte.class || p == Byte.class || p == char.class || p == Character.class;
if (!ok) throw new IllegalStateException("Unsupported @Value setter type: " + p.getName()); Try / catch
try {
processor.process(configInstance, resolver);
} catch (ConfigurationException e) {
log.error("Config injection failed: {}", e.getMessage(), e);
throw new IllegalArgumentException("Unsupported config property type", e);
} Prevention
- Restrict @Value-annotated setters to String, primitives/wrappers, char, and enum types
- Parse complex types (List/Map/POJOs) inside the setter from a String
- Write a unit test that runs process() on every config class at build time
When it happens
Trigger: Calling ValueAnnotationProcessor.process(instance, resolver) (directly or via a config loader) where a @Value-annotated public/package setX(...) method with exactly one parameter takes an unsupported type such as java.util.List, java.util.Map, java.net.URL, or a custom POJO.
Common situations: Adding a new setter to a Pinpoint config class with a complex type (List/Map/array) instead of a String; refactoring a setter parameter from String to a typed object; copying Spring-style @Value usage assuming rich type conversion that this simple processor does not provide.
Related errors
- Unsupported type:<typeName>
- <fieldName> access error
- injectField error field:<field> value:<value>
- initialize fail Caused by:
- invoke fail Caused by:
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/449e24d9bca0421e.
Report an issue: GitHub.