pinpoint-apm/pinpoint · error · ConfigurationException
<fieldName> access error
Error message
<fieldName> access error
What it means
After successfully parsing the value, injectField() uses field.set(target, parsedValue) to write it into the @Value-annotated field. If this reflective operation fails (IllegalAccessException, or an exception due to final/static constraints), a ConfigurationException named 'ClassName.fieldName access error' is thrown with the original exception as cause. Note parse() never returns null, so this wrapper only fires on reflection failures.
Source
Thrown at commons-config/src/main/java/com/navercorp/pinpoint/common/config/util/ValueAnnotationProcessor.java:190
private char parseChar(String value) {
if (value.length() != 1) {
throw new IllegalArgumentException("Invalid value:" + value);
}
return value.charAt(0);
}
private void injectField(Field field, Object target, String value) {
final Class<?> fieldType = field.getType();
try {
final Object parsedValue = parse(fieldType, value);
if (parsedValue != null) {
try {
setAccessible(field);
field.set(target, parsedValue);
} catch (ReflectiveOperationException e) {
throw new ConfigurationException(getFieldName(target, field) + " access error", e);
}
}
} catch (Exception ex) {
throw new RuntimeException("injectField error field:" + field + " value:" + value, ex);
}
}
private String getFieldName(Object instance, Member field) {
return instance.getClass().getSimpleName() + "." + field.getName();
}
}
View on GitHub (pinned to 744c3d3075)
Solutions
- Remove the final/static modifiers from the @Value-annotated field
- Ensure the config class package is under com.navercorp.pinpoint and opened to the processor (add opens directives if using modules / --add-opens on the JVM)
- Convert the field to a package-private non-final field with a matching setter so handleMethods can inject via method.invoke instead
Example fix
// before
@Value("${log.level}")
private static final String logLevel;
// after
@Value("${log.level}")
private String logLevel; Defensive patterns
Strategy: type-guard
Validate before calling
int mods = field.getModifiers();
if (java.lang.reflect.Modifier.isStatic(mods) || java.lang.reflect.Modifier.isFinal(mods)) {
throw new IllegalStateException("@Value field must not be static/final: " + field);
} Try / catch
try {
processor.process(configInstance, resolver);
} catch (ConfigurationException e) {
log.error("Reflection access failed for {}: cause={}", e.getMessage(), e.getCause(), e);
throw e;
} Prevention
- Never declare @Value-annotated fields static or final
- Keep config classes in com.navercorp.pinpoint packages (process() rejects others)
- On JDK 9+, add the required --add-opens / opens directives if packages are encapsulated
- Prefer annotated setters over fields to avoid setAccessible issues
When it happens
Trigger: field.set() fails for the annotated field — typically because the field is static final, lives under a package that blocks setAccessible under the module system / SecurityManager, or is otherwise inaccessible even after setAccessible(true).
Common situations: Running on JDK 9+ strong encapsulation where the config class package is not open to the processor's module; annotating a static final field expecting injection; security policies denying reflectAccess.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- bootstrapClassLoader access fail Caused by:
- unsupported data type :<fieldName>
- Unsupported type:<typeName>
- injectField error field:<field> value:<value>
- initialize fail Caused by:
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/fff008510e5d225b.
Report an issue: GitHub.