我的 ErrorHandler 上的 Jetty Maven 插件 ClassNotFoundException
Jetty Maven plugin ClassNotFoundException on my ErrorHandler
我已经按照此 reciepe
创建了一个自定义错误处理程序
当我站在我的项目中并执行命令时
ls target/classes/foo/bar/error/MyErrorHandler*
然后显示:target/classes/foo/bar/error/MyErrorHandler.class
我添加了自定义 jetty.xml 内容:
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure class="org.eclipse.jetty.server.handler.ContextHandler">
<Set name="errorHandler">
<New class="foo.bar.error.MyErrorHandler"/>
</Set>
</Configure>
这是我的pom.xml
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<configuration>
<classesDirectory>target/classes</classesDirectory>
<httpConnector>
<port>9999</port>
</httpConnector>
<jettyXml>src/test/resources/jetty-errorhandler.xml</jettyXml>
</configuration>
当我运行mvn jetty:run -X
我收到以下错误:
[DEBUG] parse: file:/home/vagrant/git/seopp/seopp-kunde/src/test/resources/jetty-errorhandler.xml
[DEBUG] parsing: sid=file:/home/vagrant/git/seopp/seopp-kunde/src/test/resources/jetty-errorhandler.xml,pid=null
[DEBUG] resolveEntity(-//Jetty//Configure//EN, http://www.eclipse.org/jetty/configure.dtd)
[DEBUG] Redirected entity http://www.eclipse.org/jetty/configure.dtd --> jar:file:/var/cache/maven_repository/org/eclipse/jetty/jetty-xml/9.2.11.v20150529/jetty-xml-9.2.11.v20150529.jar!/org/eclipse/jetty/xml/configure_9_0.dtd
[WARNING] Config error at <Set name="errorHandler">
<New class="foo.bar.error.MyErrorHandler"/>
</Set>
[INFO] Jetty server exiting.
Caused by: java.lang.ClassNotFoundException: foo.bar.error.MyErrorHandler
at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:50)
at org.codehaus.plexus.classworlds.realm.ClassRealm.unsynchronizedLoadClass(ClassRealm.java:271)
at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:247)
at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:239)
at org.eclipse.jetty.util.Loader.loadClass(Loader.java:86)
at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.nodeClass(XmlConfiguration.java:364)
at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.newObj(XmlConfiguration.java:754)
at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.itemValue(XmlConfiguration.java:1125)
怎么找不到我的MyErrorHandle文件?
它在我的 target/classes 目录中,路径正确。
我最终让它工作了,尽管我仍然想知道是否存在更好的解决方案。
对我来说,该解决方案似乎与一般的 Maven 插件 class 路径管理更相关,而不是 Jetty 本身。 Maven 插件将其实际定义为插件依赖项的内容添加到它们的 classpath 中。它显然也适用于 Jetty 插件(除非它还实现了一些通过配置启用的其他机制,仍有待发现)。
我创建了一个示例项目并使用了您提供的配置,具有相同的 ClassNotFoundException
。我解决了它,将项目本身添加为 Jetty 插件的依赖项(唯一的解决方案?),即提供自定义处理程序的项目 class.
工作 POM 下方:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sample</groupId>
<artifactId>jetty-error</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.2.8.v20150217</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<webApp>
<contextPath>/jetty-error</contextPath>
</webApp>
<httpConnector>
<port>7777</port>
</httpConnector>
<classesDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</classesDirectory>
<jettyXml>src/main/resources/jetty.xml</jettyXml>
</configuration>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>9.2.8.v20150217</version>
</dependency>
<dependency>
<groupId>com.sample</groupId>
<artifactId>jetty-error</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>system</scope>
<systemPath>${basedir}/lib/jetty-error-0.0.1-SNAPSHOT.jar</systemPath>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>9.2.8.v20150217</version>
</dependency>
</dependencies>
</project>
注意:我的包装是 war
,但应该没什么区别。在这种情况下,我还为插件依赖使用了一个 system
范围,没关系,这只是为了快速使其工作(我的公司 maven 存储库有问题并且 maven 没有在缓存中查找它首先,但我不想进一步调查,这不是本次练习的目标)。
因此,为了进行快速测试,我临时从项目中创建了一个 jar
并添加到 lib
目录中,但它可以作为构建的一部分轻松自动化(我真的想证明它需要成为 Jetty Maven 插件的一部分而不是 Jetty 服务器的一部分才能通过 jetty:run
).
下面是我的简单错误处理程序:
package com.sample.jetty;
import java.io.IOException;
import java.io.Writer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.ErrorHandler;
public class MyErrorHandler extends ErrorHandler {
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
throws IOException {
response.getOutputStream().println("error!");
}
public void handleErrorPage(HttpServletRequest request, Writer writer, int code, String message)
throws IOException {
writer.write("error!");
}
public void writeErrorPage(HttpServletRequest request, Writer writer, int code, String message, boolean showStacks)
throws IOException {
writer.write("error!");
}
public void writeErrorPageHead(HttpServletRequest request, Writer writer, int code, String message)
throws IOException {
writer.write("error!");
}
public void writeErrorPageBody(HttpServletRequest request, Writer writer, int code, String message,
boolean showStacks) throws IOException {
writer.write("error!");
}
public void writeErrorPageMessage(HttpServletRequest request, Writer writer, int code, String message, String uri)
throws IOException {
writer.write("error!");
}
public void writeErrorPageStacks(HttpServletRequest request, Writer writer) throws IOException {
writer.write("error!");
}
}
否 class 未发现在您的配置中使用它的异常。我还通过以下码头配置将其设置为全局 (jetty.xml
):
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN"
"http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Call name="addBean">
<Arg>
<New class="com.sample.jetty.MyErrorHandler">
<Set name="server"><Ref refid="Server" /></Set>
</New>
</Arg>
</Call>
</Configure>
然后输入了错误的地址(即 http://localhost:7777/whatever
),然后我从自定义错误处理程序中收到了 error!
消息(有效!)。
所以,结论是:class 必须是插件 classpath 的一部分,因为确实 运行 jetty:run
我们是 运行 Maven 插件。
我上面的示例可以进一步改进(在更标准的 maven approach/folder(即非系统范围)中生成 jar/loading jar;使用多模块 maven 项目,出现错误模块中的处理程序和另一个模块中的 jetty 插件,以便依赖该模块;等等),但原理可能是相同的。这是一项具有挑战性的调查。遗憾的是在线教程和文档对此主题没有太大帮助。
我已经按照此 reciepe
创建了一个自定义错误处理程序当我站在我的项目中并执行命令时
ls target/classes/foo/bar/error/MyErrorHandler*
然后显示:target/classes/foo/bar/error/MyErrorHandler.class
我添加了自定义 jetty.xml 内容:
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure class="org.eclipse.jetty.server.handler.ContextHandler">
<Set name="errorHandler">
<New class="foo.bar.error.MyErrorHandler"/>
</Set>
</Configure>
这是我的pom.xml
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<configuration>
<classesDirectory>target/classes</classesDirectory>
<httpConnector>
<port>9999</port>
</httpConnector>
<jettyXml>src/test/resources/jetty-errorhandler.xml</jettyXml>
</configuration>
当我运行mvn jetty:run -X
我收到以下错误:
[DEBUG] parse: file:/home/vagrant/git/seopp/seopp-kunde/src/test/resources/jetty-errorhandler.xml
[DEBUG] parsing: sid=file:/home/vagrant/git/seopp/seopp-kunde/src/test/resources/jetty-errorhandler.xml,pid=null
[DEBUG] resolveEntity(-//Jetty//Configure//EN, http://www.eclipse.org/jetty/configure.dtd)
[DEBUG] Redirected entity http://www.eclipse.org/jetty/configure.dtd --> jar:file:/var/cache/maven_repository/org/eclipse/jetty/jetty-xml/9.2.11.v20150529/jetty-xml-9.2.11.v20150529.jar!/org/eclipse/jetty/xml/configure_9_0.dtd
[WARNING] Config error at <Set name="errorHandler">
<New class="foo.bar.error.MyErrorHandler"/>
</Set>
[INFO] Jetty server exiting.
Caused by: java.lang.ClassNotFoundException: foo.bar.error.MyErrorHandler
at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:50)
at org.codehaus.plexus.classworlds.realm.ClassRealm.unsynchronizedLoadClass(ClassRealm.java:271)
at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:247)
at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:239)
at org.eclipse.jetty.util.Loader.loadClass(Loader.java:86)
at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.nodeClass(XmlConfiguration.java:364)
at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.newObj(XmlConfiguration.java:754)
at org.eclipse.jetty.xml.XmlConfiguration$JettyXmlConfiguration.itemValue(XmlConfiguration.java:1125)
怎么找不到我的MyErrorHandle文件? 它在我的 target/classes 目录中,路径正确。
我最终让它工作了,尽管我仍然想知道是否存在更好的解决方案。 对我来说,该解决方案似乎与一般的 Maven 插件 class 路径管理更相关,而不是 Jetty 本身。 Maven 插件将其实际定义为插件依赖项的内容添加到它们的 classpath 中。它显然也适用于 Jetty 插件(除非它还实现了一些通过配置启用的其他机制,仍有待发现)。
我创建了一个示例项目并使用了您提供的配置,具有相同的 ClassNotFoundException
。我解决了它,将项目本身添加为 Jetty 插件的依赖项(唯一的解决方案?),即提供自定义处理程序的项目 class.
工作 POM 下方:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sample</groupId>
<artifactId>jetty-error</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.2.8.v20150217</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<webApp>
<contextPath>/jetty-error</contextPath>
</webApp>
<httpConnector>
<port>7777</port>
</httpConnector>
<classesDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</classesDirectory>
<jettyXml>src/main/resources/jetty.xml</jettyXml>
</configuration>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>9.2.8.v20150217</version>
</dependency>
<dependency>
<groupId>com.sample</groupId>
<artifactId>jetty-error</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>system</scope>
<systemPath>${basedir}/lib/jetty-error-0.0.1-SNAPSHOT.jar</systemPath>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>9.2.8.v20150217</version>
</dependency>
</dependencies>
</project>
注意:我的包装是 war
,但应该没什么区别。在这种情况下,我还为插件依赖使用了一个 system
范围,没关系,这只是为了快速使其工作(我的公司 maven 存储库有问题并且 maven 没有在缓存中查找它首先,但我不想进一步调查,这不是本次练习的目标)。
因此,为了进行快速测试,我临时从项目中创建了一个 jar
并添加到 lib
目录中,但它可以作为构建的一部分轻松自动化(我真的想证明它需要成为 Jetty Maven 插件的一部分而不是 Jetty 服务器的一部分才能通过 jetty:run
).
下面是我的简单错误处理程序:
package com.sample.jetty;
import java.io.IOException;
import java.io.Writer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.ErrorHandler;
public class MyErrorHandler extends ErrorHandler {
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
throws IOException {
response.getOutputStream().println("error!");
}
public void handleErrorPage(HttpServletRequest request, Writer writer, int code, String message)
throws IOException {
writer.write("error!");
}
public void writeErrorPage(HttpServletRequest request, Writer writer, int code, String message, boolean showStacks)
throws IOException {
writer.write("error!");
}
public void writeErrorPageHead(HttpServletRequest request, Writer writer, int code, String message)
throws IOException {
writer.write("error!");
}
public void writeErrorPageBody(HttpServletRequest request, Writer writer, int code, String message,
boolean showStacks) throws IOException {
writer.write("error!");
}
public void writeErrorPageMessage(HttpServletRequest request, Writer writer, int code, String message, String uri)
throws IOException {
writer.write("error!");
}
public void writeErrorPageStacks(HttpServletRequest request, Writer writer) throws IOException {
writer.write("error!");
}
}
否 class 未发现在您的配置中使用它的异常。我还通过以下码头配置将其设置为全局 (jetty.xml
):
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN"
"http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Call name="addBean">
<Arg>
<New class="com.sample.jetty.MyErrorHandler">
<Set name="server"><Ref refid="Server" /></Set>
</New>
</Arg>
</Call>
</Configure>
然后输入了错误的地址(即 http://localhost:7777/whatever
),然后我从自定义错误处理程序中收到了 error!
消息(有效!)。
所以,结论是:class 必须是插件 classpath 的一部分,因为确实 运行 jetty:run
我们是 运行 Maven 插件。
我上面的示例可以进一步改进(在更标准的 maven approach/folder(即非系统范围)中生成 jar/loading jar;使用多模块 maven 项目,出现错误模块中的处理程序和另一个模块中的 jetty 插件,以便依赖该模块;等等),但原理可能是相同的。这是一项具有挑战性的调查。遗憾的是在线教程和文档对此主题没有太大帮助。