【问题标题】:AbstractAnnotationConfigDispatcherServletInitializer with JettyAbstractAnnotationConfigDispatcherServletInitializer 与 Jetty
【发布时间】:2014-03-05 16:50:05
【问题描述】:

我正在使用 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

【问题讨论】:

  • 你能分享你针对这个问题的结果吗?
  • 你能发布完整的课程吗?您将该代码放在 AbstractAnnotationConfigDispatcherServletInitializer 的什么位置?
  • 你试过用这个吗:AnnotationConfigWebApplicationContext class?你也可以使用这个OpenSource project

标签: java spring spring-mvc embedded-jetty


【解决方案1】:

这是一个常见问题。更多的人正面临这个问题。有时它会导致错误,或者有时它会像info 一样给出。 供参考,没有问题(就像警告一样)。 对于错误,发生此错误的原因有很多种。我试图给你一些解决方案。


  1. 有时 spring 库和 jdk 版本不匹配会导致此错误。 类是在较低版本的 jdk 中构建的,并试图在较高版本中运行 版本可能会导致错误。然后我们需要使用 Eclipse 进行更改 从 Preferences\Java\Compiler 我们必须设置“编译器合规性 级别:1.7" 和 "Generated .class files compatibility: 1.6", "来源 兼容性:1.6 英寸。
  2. 有些人认为 log4j 未配置为捕获错误 在后台引发配置错误的输出。
  3. 如果你使用的是 maven,那么 WEB-INF 目录必须在你的 网络应用程序。结构将是src/main/webapp/WEB-INF 它也解决了 这个问题。
  4. 如果没有选择"Project -> Build Automatically"。你可以强制 “m2e-wtp 文件夹和内容”的生成;

    "(右键单击 在你的项目上) -> Maven -> 更新项目..."

注意:确保 “清理项目”选项未选中。否则内容 目标/类将被删除,您将回到第一格。

  1. 将WebROOT文件目录添加到默认目录,然后这个 问题将得到解决。

    属性->MyEclipse->部署 组装->添加

资源链接:

  1. No Spring WebApplicationInitializer types detected on classpath
  2. INFO: No Spring WebApplicationInitializer types detected on classpath
  3. only one error: No Spring WebApplicationInitializer types detected on classpath

对于 tomcat,

  1. 如果 maven 有 tomcat7 插件但 JRE 环境是 1.6。然后 出现此问题。然后你需要将tomcat7 降级为tomcat6 或将 jdk 和 jre 版本升级到 1.7。
  2. 有时需要stop your tomcat。然后clean the project, clean the serverrun again your project。有时缓存会做到这一点 问题。按照这个方法,就可以解决了。

对于 JBOSS,

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

在典型的 servlet 应用程序中,您将有一个 web.xml 描述符文件来声明您的 serlvets, filters, listeners, context params, security configuration, etc。为您的应用程序。从servlet 3.0 开始,您可以通过编程方式完成大部分操作。

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

Spring 在该接口之上构建了WebApplicationInitializer,作为adapter/helper

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

资源链接:

  1. Jboss No Spring WebApplicationInitializer types detected on classpath

下面用 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 strong>版本“B”。而且不会找到您的配置类,也不会启动 sercletontexts。

类路径中出现意外的 WebApplicationInitializers

不要将任何WebApplicationInitializers 打包到您以后可能在其他Web 应用程序的类路径中的jar 或war 中。当您出乎意料时,它们可能会被发现并开始。当我将 WebApplicationInitializers 与 Maven 打包到测试罐中时,这发生在我身上,这些罐子被其他测试重用。

类路径中的多个类

servlet 容器必须扫描类路径,类越多,扫描时间越长。 至少 Jetty 有一个内置超时,所以你可能会得到一个

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

解决方案是告诉码头扫描哪些罐子。这将使 启动速度更快并避免超时。在 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 根本找不到 WebApplicationInitializer,您将在日志中看到:

No Spring WebApplicationInitializer types detected on classpath

如果 Spring 找到至少一个 WebApplicationInitializer,您将看到:

Spring WebApplicationInitializers detected on classpath: " + initializers

【讨论】:

    猜你喜欢
    • 2013-04-15
    • 2014-06-10
    • 2012-09-23
    • 1970-01-01
    • 2016-09-05
    • 1970-01-01
    • 2012-04-22
    • 2011-05-17
    • 2014-01-08
    相关资源
    最近更新 更多