首页 > 解决方案 > 除了 jar 之外,避免在 Jetty 中进行类路径类扫描

问题描述

为了使 Jetty 9.0 停止扫描类路径中的类和 jar,我按照文档中的描述进行了操作:首先,我在项目上创建了一个 WEB-INF\jetty-web.xlm 文件,其中包含以下内容:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">

<Configure class="org.eclipse.jetty.webapp.WebAppContext">

    <Call name="setAttribute">
        <Arg>org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern</Arg>
        <Arg>.\A</Arg>
    </Call>

</Configure>

然后在 web.xml 上我指定了两者<absolute-ordering/>并且metadata-complete="true我运行 Jetty-Dorg.eclipse.jetty.webapp.WebInfConfiguration.LEVEL=ALL-Dorg.eclipse.jetty.annotations.AnnotationParser.LEVEL=DEBUG确认扫描确实被跳过了,这对于 WebContext 来说似乎是正确的,因为扫描仪选择了 jar 列表,现在只列出了项目战争:

2021-02-07 21:43:58.971:INFO:oejsh.ContextHandler:Scanner-1: Started o.e.j.w.WebAppContext@6c7c5cac{Payroll,/payroll-groovy-1.0,file:///E:/Projetos/payroll_groovy/target/payroll-groovy-1.0/,AVAILABLE}{E:\Projetos\payroll_groovy\target\payroll-groovy-1.0.war}

但是,AnnotationParser显示 jar 扫描(我不明白两个日志的区别......):

2021-02-07 21:43:57.312:DBUG:oeja.AnnotationParser:qtp1595212853-27: Scanning class from jar file:///E:/Programas/jetty/lib/apache-jstl/org.apache.taglibs.taglibs-standard-impl-1.2.5.jar!/org/apache/taglibs/standard/Version.class->org/apache/taglibs/standard/Version.class[0]
2021-02-07 21:43:57.323:DBUG:oeja.AnnotationParser:qtp1595212853-29: Scanning class from jar file:///E:/Programas/jetty/lib/servlet-api-3.1.jar!/javax/servlet/AsyncEvent.class->javax/servlet/AsyncEvent.class[0]
2021-02-07 21:43:57.323:DBUG:oeja.AnnotationParser:qtp1595212853-29: Scanning class from jar file:///E:/Programas/jetty/lib/servlet-api-3.1.jar!/javax/servlet/AsyncListener.class->javax/servlet/AsyncListener.class[0]
2021-02-07 21:43:57.323:DBUG:oeja.AnnotationParser:qtp1595212853-27: Scanning class from jar file:///E:/Programas/jetty/lib/apache-jstl/org.apache.taglibs.taglibs-standard-impl-1.2.5.jar!/org/apache/taglibs/standard/functions/Functions.class->org/apache/taglibs/standard/functions/Functions.class[0]
2021-02-07 21:43:57.323:DBUG:oeja.AnnotationParser:qtp1595212853-29: Scanning class from jar file:///E:/Programas/jetty/lib/servlet-api-3.1.jar!/javax/servlet/DispatcherType.class->javax/servlet/DispatcherType.class[0]
2021-02-07 21:43:57.323:DBUG:oeja.AnnotationParser:qtp1595212853-29: Scanning class from jar file:///E:/Programas/jetty/lib/servlet-api-3.1.jar!/javax/servlet/Filter.class->javax/servlet/Filter.class[0]
2021-02-07 21:43:57.323:DBUG:oeja.AnnotationParser:qtp1595212853-27: Scanning class from jar file:///E:/Programas/jetty/lib/apache-jstl/org.apache.taglibs.taglibs-standard-impl-1.2.5.jar!/org/apache/taglibs/standard/resources/Resources.class->org/apache/taglibs/standard/resources/Resources.class[0]
2021-02-07 21:43:57.324:DBUG:oeja.AnnotationParser:qtp1595212853-29: Scanning class from jar file:///E:/Programas/jetty/lib/servlet-api-3.1.jar!/javax/servlet/FilterChain.class->javax/servlet/FilterChain.class[0]
2021-02-07 21:43:57.324:DBUG:oeja.AnnotationParser:qtp1595212853-27: Not a class: org/apache/taglibs/standard/resources/Resources.properties
2021-02-07 21:43:57.324:DBUG:oeja.AnnotationParser:qtp1595212853-27: Not a class: org/apache/taglibs/standard/resources/Resources_ja.properties
2021-02-07 21:43:57.324:DBUG:oeja.AnnotationParser:qtp1595212853-29: Scanning class from jar file:///E:/Programas/jetty/lib/servlet-api-3.1.jar!/javax/servlet/FilterConfig.class->javax/servlet/FilterConfig.class[0]
2021-02-07 21:43:57.324:DBUG:oeja.AnnotationParser:qtp1595212853-27: Scanning class from jar file:///E:/Programas/jetty/lib/apache-jstl/org.apache.taglibs.taglibs-standard-impl-1.2.5.jar!/org/apache/taglibs/standard/tag/common/core/CatchTag.class->org/apache/taglibs/standard/tag/common/core/CatchTag.class[0]
2021-02-07 21:43:57.324:DBUG:oeja.AnnotationParser:qtp1595212853-29: Scanning class from jar file:///E:/Programas/jetty/lib/servlet-api-3.1.jar!/javax/servlet/FilterRegistration$Dynamic.class->javax/servlet/FilterRegistration$Dynamic.class[0]

.
.
.

它一直持续到列出项目中的每个 jar 和每个类。如果我在 jetty-web.xml 中添加它:

<Call name="setAttribute">
    <Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg>
    <Arg>.\A</Arg>
</Call>

然后日志显示 jar 扫描停止,但类路径中的类并非如此:

2021-02-07 21:50:13.730:DBUG:oeja.AnnotationParser:qtp1595212853-29: Scanning class file:///E:/Projetos/payroll_groovy/target/payroll-groovy-1.0/WEB-INF/classes/com/vmc/DynamicClassFactory$_coreLangMethods_closure1.class
2021-02-07 21:50:13.737:DBUG:oeja.AnnotationParser:qtp1595212853-29: Scanning class file:///E:/Projetos/payroll_groovy/target/payroll-groovy-1.0/WEB-INF/classes/com/vmc/DynamicClassFactory$__clinit__closure2.class
2021-02-07 21:50:13.738:DBUG:oeja.AnnotationParser:qtp1595212853-29: Scanning class file:///E:/Projetos/payroll_groovy/target/payroll-groovy-1.0/WEB-INF/classes/com/vmc/DynamicClassFactory$__clinit__closure3.class
2021-02-07 21:50:13.739:DBUG:oeja.AnnotationParser:qtp1595212853-29: Scanning class file:///E:/Projetos/payroll_groovy/target/payroll-groovy-1.0/WEB-INF/classes/com/vmc/DynamicClassFactory.class
2021-02-07 21:50:13.741:DBUG:oeja.AnnotationParser:qtp1595212853-29: Scanning class file:///E:/Projetos/payroll_groovy/target/payroll-groovy-1.0/WEB-INF/classes/com/vmc/objectMemento/Caretaker.class
2021-02-07 21:50:13.742:DBUG:oeja.AnnotationParser:qtp1595212853-29: Scanning class file:///E:/Projetos/payroll_groovy/target/payroll-groovy-1.0/WEB-INF/classes/com/vmc/objectMemento/InMemoryObjectChangeProvider.class
2021-02-07 21:50:13.743:DBUG:oeja.AnnotationParser:qtp1595212853-29: Scanning class file:///E:/Projetos/payroll_groovy/target/payroll-groovy-1.0/WEB-INF/classes/com/vmc/objectMemento/Memento.class

.
.
.

奇怪的是,@WebListener我的类路径中的注释类没有加载(可能是因为元数据完整设置?)尽管AnnotationParser告诉它们都被扫描了。无论如何,我想避免所有扫描,因为不会有@WebListener带注释的类(我只是为了测试),所以花时间扫描它们是没有意义的。

那么如何阻止 Jetty 9.0 从我的类路径中扫描类呢?

标签: javaclasspathscanningjetty-9

解决方案


码头 9.0?确保您至少使用 Jetty 9.4.x。Jetty 9.0 主要版本使用的是 Servlet 3.1 规范的预发布/alpha 版本。您想从 9.0 升级到 9.4(这是 Servlet 3.1 顶级中 Jetty 的 4 个主要版本的跳跃,所以要做好准备。)

提醒一下,Jetty 版本控制(自 1995 年以来一直如此)是
<servlet_support>.<major_version>.<minor_version>

  • Jetty 9.x 表示 Servlet 3.1,
  • Jetty 10.x 表示 Servlet 4.0
  • Jetty 11.x 表示 Servlet 5.0

下一个值是该 servlet 支持级别内的主要版本。

至于您尝试使用该org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern属性来限制在 中扫描的内容WEB-INF/lib,这是要使用的正确属性,但只能存在于 XML 可部署文件中。

这是${jetty.base}/webapps/<name>.xml位置。

您尝试使用的WEB-INF/jetty-web.xml不正确,因为在完全配置所有 servlet 特定行为后应用此文件。(和 servlet 特定的行为是你想要配置的)

您需要在部署过程的最开始配置此属性,这意味着定义它的唯一位置是 XML 可部署文件中。

根据您Payroll,/payroll-groovy-1.0,file:///E:/Projetos/payroll_groovy/target/payroll-groovy-1.0/,AVAILABLE}{E:\Projetos\payroll_groovy\target\payroll-groovy-1.0.war的 XML 日志输出将是...

<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">

<Configure class="org.eclipse.jetty.webapp.WebAppContext">
  <Set name="contextPath">/Payroll</Set>
  <Set name="war">E:/Projetos/payroll_groovy/target/payroll-groovy-1.0.war</Set>
  <Call name="setAttribute">
    <Arg>org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern</Arg>
    <Arg>.*/scannable-[^/]*\.jar$</Arg>
  </Call>
</Configure>

这将部署你的战争,并且只扫描WEB-INF/libscannable-.


推荐阅读