我们有一个spring-boot
使用嵌入式 Tomcat 的工作应用程序,其中一个 servlet 是旧版 Struts 1.3.10(不要问)。这工作得很好!
或者直到我们添加了BIRT
查看器 servlet,该init()
代码更改了线程的类加载器。
总结一下,@Confuguration
Struts Servlet 和 BIRT Servlet 都是正常ServletRegistrationBean
的。
中的BIRT Servlet正在init()
执行以下操作:
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
应用程序运行后,对于Struts Servlet的每个请求,它都会尝试从预填充的 HashMap 中解析所需的属性,其中键是 CLassLoader,但它无法找到匹配项:
ClassLoader cl = Thread.currentThread().getContextClassLoader();
这是结果:
2014-06-10 08:33:28.971 ERROR 16572 --- [nio-9087-exec-4] o.a.c.c.C.[.[.[/].[ActionServlet] : Servlet.service() for servlet [ActionServlet] in context with path [] threw exception [Cannot find catalog 'struts'] with root cause
我没有其他想法解决它的方法是在 init() 完成之前通过扩展 BIRT servlet 来恢复类加载器:
public class BirtEngineServletWorkaround extends BirtEngineServlet {
@Override
public void init(ServletConfig config) throws ServletException {
ClassLoader savedClassLoader = Thread.currentThread().getContextClassLoader();
super.init(config);
//return classloader to this thread o_O!
Thread.currentThread().setContextClassLoader(savedClassLoader);
}
}
问题:为什么允许更改线程的类加载器?在这种特殊情况下,这个设置或获取类加载器是错误的吗?如果它不在嵌入式容器中,类加载器会好吗?线程的类加载器应该是可变的吗?有人能这么好心,给我讲讲这个吗?