JBoss代理场景下堆栈跟踪Unknown Source问题排查
NullPointerException 排查问题解答
异常堆栈信息
2023-04-10 13:54:50,790 ERROR [org.jboss.as.ejb3.invocation] (default-threads - 44) [ ] [null ] [ ] [ ] [ ] JBAS014134: EJB Invocation failed on component VotingResultsHelper for method public void com.example.voting.impl.helpers.VotingResultsHelper.calculateNewProtocol(com.example.voting.api.dto.request.OnlineVotingProtocolMakeRequest,com.example.voting.impl.persistence.model.VotingVersion): .... at com.example.voting.impl.helpers.VotingResultsHelper$$$view1332.calculateNewProtocol(Unknown Source) at sun.reflect.GeneratedMethodAccessor4488.invoke(Unknown Source) [:1.8.0_111] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.8.0_111] at java.lang.reflect.Method.invoke(Method.java:498) [rt.jar:1.8.0_111] at org.jboss.weld.util.reflection.SecureReflections$13.work(SecureReflections.java:267) at org.jboss.weld.util.reflection.SecureReflectionAccess.run(SecureReflectionAccess.java:52) at org.jboss.weld.util.reflection.SecureReflectionAccess.runAsInvocation(SecureReflectionAccess.java:137) at org.jboss.weld.util.reflection.SecureReflections.invoke(SecureReflections.java:263) at org.jboss.weld.bean.proxy.EnterpriseBeanProxyMethodHandler.invoke(EnterpriseBeanProxyMethodHandler.java:115) at org.jboss.weld.bean.proxy.EnterpriseTargetBeanInstance.invoke(EnterpriseTargetBeanInstance.java:56) at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:105) at com.example.voting.impl.helpers.VotingResultsHelper$Proxy$_$$_Weld$Proxy$.calculateNewProtocol(VotingResultsHelper$Proxy$_$$_Weld$Proxy$.java) at com.example.voting.impl.VotingMessageServiceImpl.makeOnlineVotingProtocol(VotingMessageServiceImpl.java:661) ... Caused by: java.lang.NullPointerException
问题解答
1. 代理类方法的异常定位、构建部署调整及"Unknown Source"原因
- 无法直接定位代理类
VotingResultsHelper$$$view1332中calculateNewProtocol()方法的具体异常行号,因为代理类是运行时动态生成的,没有对应的源代码和调试符号信息。 - 需要调整构建部署方式:
- 编译
VotingResultsHelper类时保留完整调试符号(避免使用-g:none编译参数,默认编译会包含行号、变量名等调试信息); - 部署时不要剥离类文件的调试属性,确保原始业务类的调试信息能被JVM识别。
- 编译
- 两个方法显示差异的原因:
VotingResultsHelper$$$view1332是JBoss Weld动态生成的代理类,生成过程中未嵌入调试行号信息,JVM无法关联到源文件和行号,因此显示Unknown Source;makeOnlineVotingProtocol()来自真实业务类VotingMessageServiceImpl,该类编译时保留了调试符号,部署时未被修改,所以能显示具体行号661。
2. 异常是否发生在calculateNewProtocol()本身还是其调用的私有方法
无法100%确定异常的具体发生位置,堆栈未显示私有方法有两种可能:
- 异常确实出现在
calculateNewProtocol()方法的直接代码中,比如直接访问了空对象的属性或方法; - 异常发生在其调用的私有方法中,但由于私有方法缺少调试信息,或者JVM在代理调用过程中截断了堆栈信息,导致私有方法的调用栈未被记录。
要精准定位,可采取以下措施:
- 确保
VotingResultsHelper类的所有方法(包括私有方法)都保留调试信息,重新构建部署后复现问题; - 在
calculateNewProtocol()及其调用的私有方法中添加关键变量的非空检查日志,追踪空指针出现的节点。
内容的提问来源于stack exchange,提问作者Joe D
相关产品推荐
相关产品推荐

