金蝶Apusic9.0部署springboot,HttpServletResponse.setContentLengthLong方法去哪了?

摘要:问题背景 项目有需要使用AAS9.0(即,金蝶天燕)web中间件部署springboot程序,服务正常启动后,只要访问应用就出现报错提示java.lang.NoSuchMethodError: javax.servlet.http.Http
问题背景 项目有需要使用AAS9.0(即,金蝶天燕)web中间件部署springboot程序,服务正常启动后,只要访问应用就出现报错提示java.lang.NoSuchMethodError: javax.servlet.http.HttpServletResponse.setContentLengthLong(J)V,导致大部分请求都有问题 详细报错如下: 25-05-20 11:15:00.770 [HTTPHandler-6-50|MAVXY1OF] ERROR - Forwarding to error page from request [/output/@xx/login/dist/app.bundle.js] due to exception [javax.servlet.http.HttpServletResponse.setContentLengthLong(J)V] java.lang.NoSuchMethodError: javax.servlet.http.HttpServletResponse.setContentLengthLong(J)V at org.springframework.http.server.ServletServerHttpResponse.writeHeaders(ServletServerHttpResponse.java:130) at org.springframework.http.server.ServletServerHttpResponse.getBody(ServletServerHttpResponse.java:96) at org.springframework.http.converter.ResourceHttpMessageConverter.writeContent(ResourceHttpMessageConverter.java:143) at org.springframework.http.converter.ResourceHttpMessageConverter.writeInternal(ResourceHttpMessageConverter.java:114) at org.springframework.http.converter.ResourceHttpMessageConverter.writeInternal(ResourceHttpMessageConverter.java:45) at org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:227) 查看方法栈可以看到是spring-web包中的ServletServerHttpResponse.writeHeaders()调用了javax.servlet.http.HttpServletResponse.setContentLengthLong()最终导致的报错。 排查解决 API不兼容 借助arthas来查出为啥会报错,servletResponse变量对应的是javax.servlet.http.HttpServletResponse接口,直接反编译看下方法是不是没定义 jad javax.servlet.http.HttpServletResponse 发现的确没定义,不过不急,该接口继承了javax.servlet.ServletResponse,再往上查一层 jad javax.servlet.ServletResponse 发现的确没有setContentLengthLong(),这说明大概率是API不兼容。用问小白查了下发现是Servlet 3.1之后就添加了这个方法。 优先加载高版本servlet-api包 既然中间件中的javax.servlet.ServletResponse版本低,根据JVM类加载机制,可以调整classpath让JVM优先加载 javax.servlet-api新版本包。 怎么调呢?查了AAS部署位置docs目录中的文档,可以将javax.servlet-api放到AAS部署目录下的lib/endorsed中。
阅读全文