使用Jetty的AbstractAnnotationConfigDispatcherServletInitializer

10

我正在使用Jetty 9.1.0.RC2和Spring 4。 有一个AbstractAnnotationConfigDispatcherServletInitializer,尝试通过以下方式启动初始化:

Server server = new Server();

WebAppContext webAppContext = new WebAppContext();
webAppContext.setContextPath("/");
webAppContext.setConfigurations(new Configuration[] { new AnnotationConfiguration() });
webAppContext.setParentLoaderPriority(true);

webAppContext.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", ".*/target/classes/.*");

server.setHandler(webAppContext);
server.start();
server.join();

但无法检测到:

No Spring WebApplicationInitializer types detected on classpath

你可以分享一下你解决这个问题的结果吗? - verystrongjoe
你能发布完整的类吗?在AbstractAnnotationConfigDispatcherServletInitializer中放置那段代码? - Logemann
你尝试使用过 AnnotationConfigWebApplicationContext 类吗?另外,你也可以使用这个开源项目 - igreenfield
1个回答

1
这是一个常见的问题。越来越多的人面临这个问题。有时它会导致错误,有时它只会提供“信息”。关于“信息”,没有问题(就像警告)。关于“错误”,发生这种错误的原因有很多种。我正在尝试给您一些解决方案。
有时候,Spring库和JDK版本不匹配会导致此错误。类是在较低版本的JDK中构建的,尝试在较高版本中运行可能会导致错误。然后我们需要使用Eclipse从Preferences\Java\Compiler更改,我们必须设置“编译器兼容级别:1.7”和“生成的.class文件兼容性:1.6”,“源兼容性:1.6”。
有些人发现log4j未配置以捕获错误输出,这会在后台抛出配置错误。
如果您正在使用Maven,则WEB-INF目录必须在您的Web应用程序内部。结构将为src/main/webapp/WEB-INF,它也解决了此问题。
如果未选择"Project -> Build Automatically",则可以通过执行以下操作强制生成“m2e-wtp文件夹和内容”:

“(右键单击您的项目) -> Maven -> Update Project…”

注意:确保取消选择“Clean Projects”选项。否则,target/classes的内容将被删除,您将回到原点。
  1. 将WebROOT文件目录添加到默认目录中,这样问题就会得到解决。

    属性->MyEclipse->部署程序集->添加

资源链接:

  1. 在类路径上未检测到Spring WebApplicationInitializer类型
  2. INFO: 在类路径上未检测到Spring WebApplicationInitializer类型
  3. 只有一个错误:在类路径上未检测到Spring WebApplicationInitializer类型

对于Tomcat,

  1. 如果Maven有tomcat7插件但JRE环境为1.6,则会出现此问题。然后您需要将tomcat7降级到tomcat6或将JDK和JRE版本升级到1.7。
  2. 有时需要停止Tomcat。然后清理项目清理服务器重新运行项目。有时缓存会导致此问题。按照这种方式操作后,可能会解决问题。

对于JBOSS,

@Sotirios Delimanolis 给出了一个非常好的答案。如下所示:

在典型的servlet应用程序中,您将拥有一个web.xml描述符文件,用于声明您的应用程序的servlets、filters、listeners、context params、security configuration等。自从servlet 3.0以来,你可以通过编程的方式完成大部分工作。

servlet 3.0提供了接口ServletContainerInitializer,您可以实现该接口。您的servlet容器将在META-INF/services/javax.servlet.ServletContainerInitializer文件中查找该类的实现,实例化它,并调用其onStartup()方法。

Spring已经构建了WebApplicationInitializer,作为一个adapter/helper,基于该接口。

您需要使用web.xml描述符或实现WebApplicationInitializer的类来设置和运行您的应用程序。

资源链接:

  1. Jboss未在类路径上检测到Spring WebApplicationInitializer类型

以下是使用Jetty进行简要详细回答:

Spring WebApplicationInitializer - how it works and what may go wrong

无需web.xml启动servlet上下文

版本3的servlet可以通过编程方式配置,而无需任何web.xml。 使用Spring及其Java配置,您创建一个实现org.springframework.web.WebApplicationInitializer的配置类。 Spring将自动查找所有实现此接口的类,并启动相应的servlet上下文。更准确地说,不是Spring在搜索这些类,而是servlet容器(例如jetty或tomcat)。 类org.springframework.web.SpringServletContainerInitializer带有注释 @ javax.servlet.annotation.HandlesTypes(WebApplicationInitializer.class) 并且实现了javax.servlet.ServletContainerInitializer 根据Servlet 3规范,容器将在类路径中调用org.springframework.web.SpringServletContainerInitializer.onStartup(Set<Class<?>>,ServletContext)实现该接口的每个类上,提供根据HandlesTypes定义的一组类

启动顺序,如果存在多个上下文

如果存在多个实现WebApplicationInitializer的类,则可以使用注释org.springframework.core.Ordered来控制它们启动的顺序。

可能出现的问题

类路径中存在不同版本的Spring

如果在类路径中有不同版本的WebApplicationInitializer,则servlet容器可能会扫描实现版本'A'WebApplicationInitializer类,而您的配置类实现了WebApplicationInitializer版本'B'。然后您的配置类将无法找到,servletcontext将无法启动。

意外的WebApplicationInitializers在类路径中

不要将任何WebApplicationInitializers打包到后续可能存在于其他Web应用程序的类路径中的jar或war中。当您不希望时,它们可能会被找到并启动。这在我使用Maven将WebApplicationInitializers打包到测试jar中并被其他测试重用时发生了。

类路径中的类过多

Servlet容器需要扫描类路径,类越多,花费的时间就越长。 至少Jetty有一个内置的超时机制,所以你可能会遇到一个

javax.websocket.DeploymentException thrown by
org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer

解决方案是告诉Jetty要扫描哪些jar包。这将使启动速度更快,并避免超时。在Maven中,您可以这样做:

pom.xml

<plugin>
     <groupId> org.eclipse.jetty</groupId >
     <artifactId> jetty-maven-plugin</artifactId >
     <configuration>
     <webAppConfig>
         <contextPath> /${project.artifactId}</contextPath >
         <webInfIncludeJarPattern> busines-letter-*.</webInfIncludeJarPattern >
     </webAppConfig>

Spring日志记录

当您配置日志记录时,您应该在日志中找到以下条目之一:

如果Spring找不到任何WebApplicationInitializer,则会在日志中看到:

No Spring WebApplicationInitializer types detected on classpath

如果Spring至少找到一个WebApplicationInitializer,您将会看到:
Spring WebApplicationInitializers detected on classpath: " + initializers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接