我们在生产中面临一个奇怪的问题。我们的是部署在 Tomcat 7 中的 Web 应用程序。我们使用 Antisamy-1.5.3.jar 来预防 XSS。每个用户请求都被一个过滤器拦截,该过滤器会扫描请求中的任何恶意内容。这个设置在 Tomcat 6 中运行了一年多。我们迁移到 Tomcat 7。用户在打开应用程序时打开和关闭 NoClassDefFoundError(不一致),但是当 Tomcat 重新启动时它工作正常。
下面是抛出异常的流程
用户请求被 AntiSamyFilter 拦截,并调用 owasp.validator.html.AntiSamy 类(AntiSamy 内部类)上的 scan 方法。
下面是扫描方法的代码
public CleanResults scan(String taintedHTML, Policy policy) throws ScanException, PolicyException { return new AntiSamyDOMScanner(policy).scan(taintedHTML); }
当在上面的代码中引用 AnitSamyDOMScanner 类时,AntiSamyDOMScanner 超类的静态初始化块 - AbstractAntiSamyScanner 被调用,如下所示
private static ResourceBundle getResourceBundle() { try { return ResourceBundle.getBundle("AntiSamy", Locale.getDefault()); } catch (MissingResourceException mre) { } return ResourceBundle.getBundle("AntiSamy", new Locale("en", "US")); }
这是引发异常的地方,因为由于某种原因,tomcat 无法加载资源包 - AntiSamy_en_US.properties 文件存在于根级别的 jar 文件中。由于这是静态块中的错误,因此抛出 ExceptionInInitializer 最终导致 NoClassDefFoundError。
下面是一起查看的两个异常 - 我们可以看到 NoClassDefFoundError 是由于 AbstractAntiSamyScanner 的静态 init 块中的异常引起的。
SEVERE: Servlet.service() for servlet [jsp] in context with path [/app] threw exception [javax.servlet.ServletException: java.lang.NoClassDefFoundError: Could not initialize class org.owasp.validator.html.scan.AntiSamyDOMScanner] with root cause
java.lang.NoClassDefFoundError: Could not initialize class org.owasp.validator.html.scan.AntiSamyDOMScanner
at org.owasp.validator.html.AntiSamy.scan(AntiSamy.java:93)
at org.apache.jsp.index_jsp._jspService(index_jsp.java:124)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
java.lang.NoClassDefFoundError: Could not initialize class org.owasp.validator.html.scan.AntiSamyDOMScanner StackTrace: javax.servlet.ServletException: java.lang.NoClassDefFoundError: Could not initialize class org.owasp.validator.html.scan.AntiSamyDOMScanner at
我们尝试在 Tomcat lib 和 WEB-INF/classes 下复制 Antisamy.properties,但没有成功。关于什么可能导致 AbstractAntiSamyScanner 在 jar 中找不到资源包的任何想法?