pinpoint-apm/pinpoint · error · NullPointerException
handler
Error message
handler
What it means
UnsafeDelegatorJava8.register installs the global LambdaBytecodeHandler used to instrument lambda invocations on Java 8+. It refuses null with NullPointerException("handler") and only accepts the first registration; subsequent registrations fail (return false) because the field is already set.
Source
Thrown at agent-module/bootstraps/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/lambda/UnsafeDelegatorJava8.java:31
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.navercorp.pinpoint.bootstrap.lambda;
import com.navercorp.pinpoint.bootstrap.instrument.lambda.LambdaBytecodeHandler;
import sun.misc.Unsafe;
/**
* @author Woonduk Kang(emeroad)
*/
public class UnsafeDelegatorJava8 {
private static final Unsafe UNSAFE = Unsafe.getUnsafe();
private static LambdaBytecodeHandler handler;
public static boolean register(LambdaBytecodeHandler handler) {
if (handler == null) {
throw new NullPointerException("handler");
}
final LambdaBytecodeHandler localCopy = UnsafeDelegatorJava8.handler;
if (localCopy == null) {
UnsafeDelegatorJava8.handler = handler;
return true;
} else {
System.err.println("LambdaBytecodeHandler already registered");
return false;
}
}
public static Class<?> defineAnonymousClass(Class<?> hostClass, byte[] data, Object[] cpPatches) {
if (hostClass == null || data == null) {
throw new NullPointerException();
}
if (hostClass.isArray() || hostClass.isPrimitive()) {
throw new IllegalArgumentException();
}View on GitHub (pinned to 744c3d3075)
Solutions
- Ensure register is called exactly once with a non-null handler, guarded by the boolean return value
- Check the return value of register(): false means another handler already owns the slot
- In tests, isolate registration to a single setup or use a fresh JVM/classloader
Example fix
// before
UnsafeDelegatorJava8.register(null); // NPE
// after
if (handler != null && !UnsafeDelegatorJava8.register(handler)) {
logger.warn("lambda handler already registered");
} Defensive patterns
Strategy: type-guard
Validate before calling
if (handler == null) throw new IllegalArgumentException("handler must not be null"); Type guard
boolean registerSafe(LambdaBytecodeHandler h) { return h != null && UnsafeDelegatorJava8.register(h); } Try / catch
try {
boolean installed = UnsafeDelegatorJava8.register(handler);
if (!installed) logger.warn("lambda handler already registered; ignoring");
} catch (NullPointerException e) {
if ("handler".equals(e.getMessage())) {
logger.error("register(null) is not allowed", e);
} else { throw e; }
} Prevention
- Register the lambda handler once during agent bootstrap, before any lambdas are instrumented
- Check register()'s boolean return rather than assuming success
- Make the handler reference final and initialize it before registration
When it happens
Trigger: Calling UnsafeDelegatorJava8.register(null); or attempting to register a second handler when one was already installed earlier in the JVM lifetime.
Common situations: Bootstrap ordering bugs where registration code runs twice; two agent components competing to install the lambda handler; unit tests leaking a previously registered handler in the same JVM.
Related errors
- null parameterType not supported
- Invalid AgentClass:
- boot create failed. Error:
- not found
- unexpected class ${className}
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/7d1669c247bfa23d.
Report an issue: GitHub.