pinpoint-apm/pinpoint · error · IllegalArgumentException
Cannot add setter to final field. setterMethod: ${setterName
Error message
Cannot add setter to final field. setterMethod: ${setterName}, fieldName: ${fieldName} What it means
ASMClass.addSetter() refuses to add a setter to a field declared final, because writing it would violate the class's declared invariants. The caller may pass removeFinal=true to have the engine strip the ACC_FINAL flag before weaving; otherwise the transform is rejected with this IllegalArgumentException naming the setter method and field.
Source
Thrown at agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/ASMClass.java:349
final ASMFieldNodeAdapter fieldNode = this.classNode.getField(fieldName, null);
if (fieldNode == null) {
throw new IllegalArgumentException("Not found field. name=" + fieldName);
}
final Type fieldType = setterDetails.getFieldType();
if (!fieldNode.getJavaType().equals(fieldType)) {
throw new IllegalArgumentException("Argument type of the setter is different with the field type. setterMethod: " + fieldType + ", fieldType: " + fieldNode.getJavaType());
}
if (fieldNode.isStatic()) {
throw new IllegalArgumentException("Cannot add setter to static fields. setterMethod: " + setterDetails.getSetter().getName() + ", fieldName: " + fieldName);
}
final int original = fieldNode.getAccess();
boolean finalRemoved = false;
if (fieldNode.isFinal()) {
if (!removeFinal) {
throw new IllegalArgumentException("Cannot add setter to final field. setterMethod: " + setterDetails.getSetter().getName() + ", fieldName: " + fieldName);
} else {
final int removed = original & ~Opcodes.ACC_FINAL;
fieldNode.setAccess(removed);
finalRemoved = true;
}
}
try {
boolean modified = finalRemoved;
modified |= this.classNode.addSetterMethod(setterDetails.getSetter().getName(), fieldNode);
modified |= this.classNode.addInterface(setterClass.getName());
if (modified) {
setModified(true);
} else if (logger.isDebugEnabled()) {
logger.debug("Skip addSetter, setter already declared. class={}, setter={}", getName(), setterClass.getName());
}
} catch (Exception e) {
if (finalRemoved) {View on GitHub (pinned to 744c3d3075)
Solutions
- Pass removeFinal=true to addSetter if mutating the final field is intentional
- Choose a non-final field, or drop the setter approach and use an interceptor on accessing methods
- Verify with javap whether the field is final in the exact target library version
Example fix
// before clazz.addSetter(setterClass, "url"); // url is final // after clazz.addSetter(setterClass, "url", true); // removeFinal = true
Defensive patterns
Strategy: validation
Validate before calling
Field f = targetClass.getDeclaredField(fieldName);
if (Modifier.isFinal(f.getModifiers())) {
// decide: pass removeFinal=true or pick another field
} Type guard
boolean isMutableField(Class<?> c, String name) {
try { int m = c.getDeclaredField(name).getModifiers(); return !Modifier.isFinal(m) && !Modifier.isStatic(m); } catch (NoSuchFieldException e) { return false; }
} Prevention
- Avoid targeting final fields in plugins
- Only enable removeFinal when mutation is truly required and safe
- Re-check field modifiers on every library upgrade
When it happens
Trigger: Calling the addSetter API against a final field while removeFinal is false (default). fieldNode.isFinal() is true in the target class bytecode.
Common situations: Targeting immutable/value fields or constants accidentally; library versions where a field was made final; plugin authors unaware that removeFinal must be explicitly enabled.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Cannot add setter to static fields. setterMethod: ${setterNa
- Failed to add setter: ${setterClassName}
- %s load fail Caused by:%s
- J9BootLoader create fail Caused by:
- initialize fail Caused by:
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/223d483f939341a1.
Report an issue: GitHub.