{"record":{"id":"835b99c78515822f","repo":"alibaba/arthas","slug":"model-class-is-null","errorCode":null,"errorMessage":"model class is null","messagePattern":"model class is null","errorType":"exception","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"labs/arthas-grpc-web-proxy/src/main/java/com/taobao/arthas/grpcweb/grpc/view/GrpcResultViewResolver.java","lineNumber":102,"sourceCode":"        } catch (Throwable e) {\n            logger.error(\"register result view failed\", e);\n        }\n    }\n\n    public GrpcResultView getResultView(ResultModel model) {\n        return resultViewMap.get(model.getClass());\n    }\n\n    public GrpcResultViewResolver registerView(Class modelClass, GrpcResultView view) {\n        //TODO 检查model的type是否重复，避免复制代码带来的bug\n        this.resultViewMap.put(modelClass, view);\n        return this;\n    }\n\n    public GrpcResultViewResolver registerView(GrpcResultView view) {\n        Class modelClass = getModelClass(view);\n        if (modelClass == null) {\n            throw new NullPointerException(\"model class is null\");\n        }\n        return this.registerView(modelClass, view);\n    }\n\n    public void registerView(Class<? extends GrpcResultView> viewClass) {\n        GrpcResultView view = null;\n        try {\n            view = viewClass.newInstance();\n        } catch (Throwable e) {\n            throw new RuntimeException(\"create view instance failure, viewClass:\" + viewClass, e);\n        }\n        this.registerView(view);\n    }\n\n    /**\n     * Get model class of result view\n     *\n     * @return","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/alibaba/arthas/blob/21cf2e9ba52b305290be7223b980ff504bb9cb5b/labs/arthas-grpc-web-proxy/src/main/java/com/taobao/arthas/grpcweb/grpc/view/GrpcResultViewResolver.java#L84-L120","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: model type erased, getModelClass returns null\nresolver.registerView(myLambdaView); // throws 'model class is null'\n\n// after: specify explicitly\nresolver.registerView(MyResultModel.class, myLambdaView);","handlingStrategy":"validation","validationCode":"Class modelClass = GrpcResultViewResolver.getModelClass(view);\nif (modelClass == null) {\n    // use explicit overload to avoid the NPE\n    resolver.registerView(knownModelClass, view);\n} else {\n    resolver.registerView(view);\n}","typeGuard":null,"tryCatchPattern":"try {\n    resolver.registerView(view);\n} catch (NullPointerException e) {\n    if (e.getMessage().contains(\"model class is null\")) {\n        resolver.registerView(MyResultModel.class, view); // explicit\n    } else { throw e; }\n}","preventionTips":["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."],"tags":["arthas","grpc-web-proxy","reflection","view-registry","null"],"backgroundTag":null,"analyzedSha":"21cf2e9ba52b305290be7223b980ff504bb9cb5b","analyzedAt":"2026-08-14T00:57:07.243Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}