Oracle WebLogic 12c RPC调用分发异常:原因分析与解决
首先,先明确这个java.lang.IllegalStateException: ServletConfig has not been initialized错误的触发场景:
这个错误通常发生在Web应用启动阶段,或者第一次接收GWT RPC请求时,核心原因是处理请求的Servlet实例(这里是SpringControllerGWT)没有被Web容器(WebLogic)正确初始化——ServletConfig没有被注入到GenericServlet的实例中,导致调用getServletName()等依赖ServletConfig的方法时抛出异常。
你提到只有Managed Server1出现这个问题,Server2正常,且排除了内存问题,那大概率是两个服务器的部署/初始化配置差异,或者Server1的应用初始化过程中存在异常。
错误日志详情
return (<Dec 20, 2019, 9:34:45,440 AM UTC> <Error> <ServletContext-/fierce> <ip-XXX> <XXX_mserver1> <[ACTIVE] ExecuteThread: '6' for queue: 'weblogic.kernel.Default (self-tuning)'> <<anonymous>> <> <c5b3824c-d0c5- 4bcb-a246-9eb864e8b2f7-00001333> <1576834485440> <[severity-value: 8] [rid: 0] [partition-id: 0] [partition-name: DOMAIN] > <BEA-000000> <Exception while dispatching incoming RPC call java.lang.IllegalStateException: ServletConfig has not been initialized at javax.servlet.GenericServlet.getServletName(GenericServlet.java:331) at javax.servlet.GenericServlet.log(GenericServlet.java:275) at com.google.gwt.user.server.rpc.RemoteServiceServlet.loadSerializationPolicy(RemoteServiceServlet.java:103) at com.google.gwt.user.server.rpc.RemoteServiceServlet.doGetSerializationPolicy(RemoteServiceServlet.java:293) at com.google.gwt.user.server.rpc.RemoteServiceServlet.getSerializationPolicy(RemoteServiceServlet.java:157) at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.prepareToRead(ServerSerializationStreamReader.java:454) at com.google.gwt.user.server.rpc.RPC.decodeRequest(RPC.java:237) at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:206) at com.XXX.ui.common.server.service.SpringControllerGWT.processCall(SpringControllerGWT.java:66) at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:248) at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62) at com.ui.common.server.service.SpringControllerGWT.handleRequest(SpringControllerGWT.java:51) at com.ui.common.server.service.SpringControllerGWT.handleRequest(SpringControllerGWT.java:49) at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:50) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) at javax.servlet.http.HttpServlet.service(HttpServlet.java:707) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) )
具体解决方案
1. 检查SpringControllerGWT的代码实现
这个类继承了GWT的RemoteServiceServlet,如果你们重写了它的init()方法,一定要确保调用了父类的初始化方法:
@Override public void init(ServletConfig config) throws ServletException { super.init(config); // 必须调用这一行,否则ServletConfig不会被注入 // 这里添加你们的自定义初始化逻辑 }
如果没有重写init()方法,要确认这个类没有被手动实例化(比如在Spring配置中错误地用new SpringControllerGWT()创建实例,而不是由Web容器管理)。
2. 对比Managed Server1和Server2的部署配置
- 应用启动顺序与加载时机:
登录WebLogic控制台,检查两个服务器上的应用启动顺序,确保Server1上的应用依赖的服务(比如Spring容器)先完成初始化。同时,在web.xml中给DispatcherServlet和SpringControllerGWT添加<load-on-startup>配置,让它们在应用启动时就初始化:<servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> <!-- 数字越小启动优先级越高 --> </servlet> - 服务器启动参数与系统属性:
检查两个服务器的启动脚本,确认除了内存参数外,没有其他差异(比如是否有不同的-D系统属性影响Spring或GWT的初始化)。
3. 排查Server1的应用初始化异常
查看Server1的WebLogic启动日志,检查应用启动阶段是否有其他异常(比如Spring Bean初始化失败、数据库连接异常等)——这些异常会导致应用初始化不完全,ServletConfig无法被正确注入。如果有前置异常,先解决这些问题。
4. 调整负载均衡的健康检查策略
如果你们使用了负载均衡器,确认它的健康检查逻辑是等待应用完全启动后才转发请求到Server1。比如,设置健康检查的URL为一个能验证Spring容器和GWT Servlet都初始化完成的接口,而不是简单的HTTP 200响应。
内容的提问来源于stack exchange,提问作者m0na

