【问题标题】:Adding custom handler to jetty throws ClassNotFoundException向码头添加自定义处理程序会引发 ClassNotFoundException
【发布时间】:2020-05-27 22:31:28
【问题描述】:

我正在尝试向码头注入自定义处理程序。

我已经在我的应用程序代码中编写了处理程序,它被打包为一个战争。

package com.foo.bar

import javax.servlet.http.{HttpServletRequest, HttpServletResponse}
import org.eclipse.jetty.server.Request
import org.eclipse.jetty.server.handler.AbstractHandler

// scalastyle:off println
class CustomJettyHandler extends AbstractHandler {
  override def handle(target: String, baseRequest: Request,
                      request: HttpServletRequest, response: HttpServletResponse): Unit = {

    println("This is a custom jetty handler")
  }
}
// scalastyle:on println

然后我在jetty.xml 文件中注入了这个处理程序:

<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
........
........
<Call name="insertHandler">
    <Arg>
      <New id="CustomJettyHandler" class="com.foo.bar.CustomJettyHandler"/>
    </Arg>
</Call>
........

我现在以独立模式运行码头。请注意,我将CustomJettyHandler.class 所在的位置传递给jetty-start.jar

java -server -Dorg.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog -jar lib/jetty-start.jar OPTIONS=All --lib=lib/* --lib=webapps/root/WEB-INF/classes/com/foo/bar/* etc/jetty.xml etc/jetty-jmx.xml --debug

在我的应用程序日志中,我可以看到码头将我的自定义处理程序加载到其类路径,但最终由于ClassNotFoundException 而失败。有人能指出这哪里出了问题吗?

.......
rawlibref = webapps/root/WEB-INF/classes/com/foo/bar/*
expanded = webapps/root/WEB-INF/classes/com/foo/bar/*
getPaths('webapps/root/WEB-INF/classes/com/foo/bar/*')
Using relative path pattern: glob:**/webapps/root/WEB-INF/classes/com/foo/bar/*
Found [webapps/root/WEB-INF/classes/com/foo/bar/CustomJettyHandler.class]  /Users/...path_to_application.../webapps/root/WEB-INF/classes/com/foo/bar/CustomJettyHandler.class
Adding classpath component: /Users/...path_to_application.../webapps/root/WEB-INF/classes/com/foo/bar/CustomJettyHandler.class
.......
.......
.......
URLClassLoader.url[33] = file:/Users/...path_to_application.../webapps/root/WEB-INF/classes/com/foo/bar/CustomJettyHandler.class
Loaded 34 URLs into URLClassLoader
class org.eclipse.jetty.xml.XmlConfiguration - 9.4.24.v20191120
Command Line Args: /var/folders/z5/dmt38gq54kxcrrzpgvbl5m_c0000gp/T/start_6046998329479549547.properties /Users/...path_to_application.../etc/jetty.xml /Users/...path_to_application.../etc/jetty-jmx.xml
2020-05-27 14:46:13.676:INFO::main: Logging initialized @477ms to org.eclipse.jetty.util.log.StdErrLog
2020-05-27 14:46:13.934:INFO:oeju.TypeUtil:main: JVM Runtime does not support Modules
2020-05-27 14:46:14.007:WARN:oejx.XmlConfiguration:main: Config error at <Call name="insertHandler"><Arg>|      <New id="CustomJettyHandler" class="com.foo.bar.CustomJettyHandler"/>|    </Arg></Call> java.lang.ClassNotFoundException: com.foo.bar.CustomJettyHandler in file:///Users/...path_to_application.../etc/jetty.xml
2020-05-27 14:46:14.007:WARN:oejx.XmlConfiguration:main:
java.security.PrivilegedActionException: java.lang.ClassNotFoundException: com.foo.bar.CustomJettyHandler
    at java.security.AccessController.doPrivileged(Native Method)
    at org.eclipse.jetty.xml.XmlConfiguration.main(XmlConfiguration.java:1837)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.eclipse.jetty.start.Main.invokeMain(Main.java:218)
    at org.eclipse.jetty.start.Main.start(Main.java:491)
    at org.eclipse.jetty.start.Main.main(Main.java:77)
Caused by:
java.lang.ClassNotFoundException: com.foo.bar.CustomJettyHandler
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at org.eclipse.jetty.util.Loader.loadClass(Loader.java:64)
    at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.newObj(XmlConfiguration.java:1028)
    at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.itemValue(XmlConfiguration.java:1638)
    at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.value(XmlConfiguration.java:1539)
    at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.access$500(XmlConfiguration.java:369)
    at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration$AttrOrElementNode.getList(XmlConfiguration.java:1768)
    at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration$AttrOrElementNode.getList(XmlConfiguration.java:1744)
    at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.call(XmlConfiguration.java:919)
    at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.configure(XmlConfiguration.java:512)
    at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.configure(XmlConfiguration.java:454)
    at org.eclipse.jetty.xml.XmlConfiguration.configure(XmlConfiguration.java:354)
    at org.eclipse.jetty.xml.XmlConfiguration.lambda$main$0(XmlConfiguration.java:1874)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.eclipse.jetty.xml.XmlConfiguration.main(XmlConfiguration.java:1837)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.eclipse.jetty.start.Main.invokeMain(Main.java:218)
    at org.eclipse.jetty.start.Main.start(Main.java:491)
    at org.eclipse.jetty.start.Main.main(Main.java:77)

【问题讨论】:

    标签: scala jetty classnotfoundexception jetty-9


    【解决方案1】:

    你从哪里得到这个命令行?

    java -server \
      -Dorg.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog\
      -jar lib/jetty-start.jar\
      OPTIONS=All \
      --lib=lib/* \
      --lib=webapps/root/WEB-INF/classes/com/foo/bar/* \
      etc/jetty.xml \
      etc/jetty-jmx.xml \
      --debug
    

    这不适用于 Jetty 9.x 的 start.jar

    一些建议

    • 不要在 java 命令行上直接使用 XML,这是 start.jarjetty-home 模块系统的责任(顺序非常重要)。
      您选择的etc/jetty.xml and etc/jetty-jmx.xml 是一个不完整的xml 列表。 (您缺少所有相关的 XML 文件)
    • 不要编辑标准的 Jetty XML 文件,保留它们,否则以后升级会变得复杂。改用 XML 来注入您的行为(参见下面的示例)
    • OPTIONS 不受 Jetty 9.x 支持(这是老式 Codehaus / Jetty 6 行为)
    • 不鼓励您使用--lib=,它仅支持具有爆炸类树的jar 或目录的完全限定路径(不支持相对路径,不支持glob)。
    • -Dorg.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog 是一种设置日志记录的苛刻方式。创建一个jetty-logging.properties 文件并确保它存在于类路径中。

    jetty-logging.properties的示例内容

    org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
    org.eclipse.jetty.LEVEL=INFO
    #org.eclipse.jetty.deploy.LEVEL=DEBUG
    

    改为这样做。

    为您的新处理程序创建一个基于注入的 XML。

    my-handler.xml

    <?xml version="1.0"?>
    <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
    
    <Configure id="Server" class="org.eclipse.jetty.server.Server">
        <Call name="insertHandler">
            <Arg>
                <New id="CustomJettyHandler" class="com.foo.bar.CustomJettyHandler" />
            </Arg>
        </Call>
    </Configure>
    

    接下来正确创建您的 jetty-base 目录(对于 jetty 的 start.jar

    # Create your "jetty-base" directory
    $ mkdir /path/to/myjettybase
    $ cd /path/to/myjettybase
    
    # Establish the basic files / directories / modules that you want to use
    # You can find the configuration in start.ini or start.d/*.ini
    $ java -jar /path/to/jetty-home/start.jar --add-to-start=http,jmx,deploy,ext,resources
    
    # Copy your custom handler JAR into place
    $ cp /path/to/my-handlers.jar /path/to/myjettybase/lib/ext/
    # Copy your custom handler XML into place
    $ cp /path/to/my-handler.xml /path/to/myjettybase/etc/
    # Ensure that the custom handler XML is loaded into the jetty instance at the right point in the XML load order by declaring it to be used in a custom INI
    $ mkdir start.d
    $ echo "etc/my-handler.xml" >> start.d/my-handlers.ini
    
    # Copy your jetty-logging.properties into place
    $ cp /path/to/my-jetty-logging.properties /path/to/myjettybase/resources/jetty-logging.properties
    
    # verify that your configuration looks sane (including the server classpath)
    $ cd /path/to/myjettybase
    $ java -jar /path/to/jetty-home/start.jar --list-config
    
    # run your instance
    $ cd /path/to/myjettybase
    $ java -jar /path/to/jetty-home/start.jar
    

    但这还不是全部,鉴于您似乎想在 maven 风格的项目(或项目布局)中使用 jetty-home,您也可以这样做!

    可以在...上找到一个示例项目来展示这一点

    https://github.com/jetty-project/servlet-error-page-handling

    该 maven 项目也是一个有效的 jetty-base 目录,适合由您机器上其他地方的 jetty-home 存档执行。

    【讨论】:

    • 我将我的jetty-home目录下的myHandler相关文件和demo.war文件复制到/jetty-home/webapps目录下。我可以在--list-config 中看到我的处理程序:` 1: 1.0-SNAPSHOT | ${jetty.base}/lib/ext/jetty-custom-handler-1.0-SNAPSHOT.jar Jetty Active XMLs: ${jetty.base}/etc/my-handler.xml` 但是从 jetty home 运行服务器会得到@ 987654345@
    • 我什至尝试从jetty-base 执行此操作,这也导致:java.lang.IllegalStateException: No Method: &lt;Call name="insertHandler"&gt;&lt;Arg&gt; &lt;New id="CustomJettyHandler" class="com.github.calvincodes.CustomJettyHandler"/&gt; &lt;/Arg&gt;&lt;/Call&gt; on class org.eclipse.jetty.server.Server Caused by: java.lang.NoSuchMethodException: insertHandler at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.call(XmlConfiguration.java:1008) at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.call(XmlConfiguration.java:963)
    • “我的应用程序代码中打包为战争的处理程序”是您在 WAR 文件中还是在服务器类路径中的处理程序?
    • 我尝试过两种方法: 1. 在打包为war的模块中编写处理程序类,然后使用--lib将此模块的target/classes目录传递给码头范围。 2. 在模块中编写handler类,打包成jar,然后将jar复制到/lib/ext/ directory within jetty-base`目录下。这两种情况都显示正确的配置,但在码头启动时抛出异常。这是一个 GitHub 存储库,它重现了这两个问题。我还在 README 中添加了错误详细信息。 github.com/calvincodes/custom-handler-jetty
    • 您是否能够使用我在上一条评论中提到的存储库重现错误? github.com/calvincodes/custom-handler-jetty@joakim-erdfelt
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-15
    • 1970-01-01
    • 2011-11-11
    相关资源
    最近更新 更多