alibaba/arthas · error · NullPointerException
model class is null
Error message
model class is null
What it means
GrpcResultViewResolver.registerView(GrpcResultView view) throws NullPointerException when getModelClass(view) returns null — i.e. the view's model class could not be determined via reflection of its draw method signature. The resolver keys views by their associated ResultModel subclass; without it registration is impossible.
Source
Thrown at labs/arthas-grpc-web-proxy/src/main/java/com/taobao/arthas/grpcweb/grpc/view/GrpcResultViewResolver.java:102
} catch (Throwable e) {
logger.error("register result view failed", e);
}
}
public GrpcResultView getResultView(ResultModel model) {
return resultViewMap.get(model.getClass());
}
public GrpcResultViewResolver registerView(Class modelClass, GrpcResultView view) {
//TODO 检查model的type是否重复,避免复制代码带来的bug
this.resultViewMap.put(modelClass, view);
return this;
}
public GrpcResultViewResolver registerView(GrpcResultView view) {
Class modelClass = getModelClass(view);
if (modelClass == null) {
throw new NullPointerException("model class is null");
}
return this.registerView(modelClass, view);
}
public void registerView(Class<? extends GrpcResultView> viewClass) {
GrpcResultView view = null;
try {
view = viewClass.newInstance();
} catch (Throwable e) {
throw new RuntimeException("create view instance failure, viewClass:" + viewClass, e);
}
this.registerView(view);
}
/**
* Get model class of result view
*
* @returnView on GitHub (pinned to 21cf2e9ba5)
Solutions
- Ensure the view's draw method declares a concrete ResultModel subclass as its model parameter (not Object or a raw type).
- Use the two-argument overload registerView(modelClass, view) to specify the class explicitly when reflection cannot infer it.
- If using a lambda/anonymous view, replace it with a named class that retains generic type info.
Example fix
// before: model type erased, getModelClass returns null resolver.registerView(myLambdaView); // throws 'model class is null' // after: specify explicitly resolver.registerView(MyResultModel.class, myLambdaView);
Defensive patterns
Strategy: validation
Validate before calling
Class modelClass = GrpcResultViewResolver.getModelClass(view);
if (modelClass == null) {
// use explicit overload to avoid the NPE
resolver.registerView(knownModelClass, view);
} else {
resolver.registerView(view);
} Try / catch
try {
resolver.registerView(view);
} catch (NullPointerException e) {
if (e.getMessage().contains("model class is null")) {
resolver.registerView(MyResultModel.class, view); // explicit
} else { throw e; }
} Prevention
- Use the explicit registerView(modelClass, view) overload when the model type may not be reflectively inferable.
- Ensure custom views declare a concrete ResultModel subclass in their draw signature.
When it happens
Trigger: Registering a GrpcResultView whose draw method's second parameter is not a concrete ResultModel subclass, or whose generic type information is erased/unavailable at runtime, so reflection cannot extract the model class.
Common situations: A custom view class uses a raw type or Object as the model parameter instead of a concrete ResultModel subclass; the view is a lambda or anonymous class with erased generics; the draw method signature doesn't match the expected pattern getModelClass() inspects.
Related errors
- create view instance failure, viewClass:{}
- Couldn't find rpcmethod: {}
- Source is not an array: {}
- AllServerStart must be initialized before!
- Cannot write to standard output when {}
AI-assisted analysis of alibaba/arthas@21cf2e9ba5 (2026-08-14).
Data as JSON: /api/errors/835b99c78515822f.
Report an issue: GitHub.