首页 > 解决方案 > 如何使用 Pax-Web 在 Karaf 4.3.2 上运行 Vaadin 8 或 20 应用程序?

问题描述

我以为我在某个地方读到了可以在以下内容之间切换的内容:

码头
雄猫
野蝇

feature:install war但是,对于与.

好像这还不够,我在 Jetty 上几乎没有成功(版本 9.4.40v20210413 似乎在 Karaf 4.3.2 中,这是相当新的,所以原则上应该可以工作)。

我试图部署一个 Vaadin 8.5.2 应用程序(我从 8.6 读到某些东西可能会被破坏,我不想作为第一件事进行调查)。

karaf@root()> web:list
ID  │ State       │ Web-State   │ Level │ Web-ContextPath │ Name
────┼─────────────┼─────────────┼───────┼─────────────────┼────────────────────────────────
110 │ Active      │ Failed      │ 80    │ /learningfusion │ 
learningfusion (1.0.0.SNAPSHOT)
111 │ Active      │ Deployed    │ 80    │ /connect4       │ connect4 (1.0.0)

所以 connect4 应用程序应该可以正常工作,但是浏览 localhost:8181/connect4 会给我一个 403 错误。

我怎样才能解决这个问题?(命令比“做什么”更受赞赏,因为我目前可能不明白“如何”实现这一点,因为我是这方面的初学者)。

而列表中的另一个应用程序是 Vaadin20 生产模式应用程序,它在启动时给了我一个 NPE,所以我想先尝试其他两个应用程序容器来辅助调试。

如果有的话,有人可以指出我的相关文件吗?

标签: apache-karafvaadin8vaadin-flowapache-karaf-feature

解决方案


我用 Karaf 4.3.2 + Pax Web 7.3.16检查了https://github.com/enver-haase/Playground/tree/master/connect4org.springframework.web.SpringServletContainerInitializer#onStartup() ,问题出在方法上。或者更确切地说,它是由 Pax Web (pax-web-extender-war) 处理的。

SpringServletContainerInitializer 注释为:

@HandlesTypes(WebApplicationInitializer.class)

这意味着(根据 JavaEE Servlets 规范)给我所有实现WebApplicationInitializerinterface的类。

但是 Pax Web 7(尽管我已经在尚未发布的 Pax Web 8 中修复了它)只是通过WebApplicationInitializer.class自身。

这导致了 Spring Web 简单地调用的情况:

servletContext.log("No Spring WebApplicationInitializer types detected on classpath");

虽然(在检查 Tomcat 时),类列表是(如预期的那样):

webAppInitializerClasses: java.util.Set  = {java.util.HashSet@2416}  size = 6
 0 = {@2419} "class com.infraleap.connect4.Connect4Application"
 1 = {@2420} "class org.springframework.web.context.AbstractContextLoaderInitializer"
 2 = {@2421} "class org.springframework.boot.web.support.SpringBootServletInitializer"
 3 = {@2422} "class org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration$JerseyWebApplicationInitializer"
 4 = {@2423} "class org.springframework.web.servlet.support.AbstractDispatcherServletInitializer"
 5 = {@2424} "class org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer"

并且 Vaadin 可以成功启动。

我检查了 Pax Web 8(尚未发布)并且设置是正确的:

webAppInitializerClasses = {java.util.LinkedHashSet@7795}  size = 6
 0 = {@7798} "class org.springframework.web.context.AbstractContextLoaderInitializer"
 1 = {@7799} "class org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer"
 2 = {@7800} "class com.infraleap.connect4.Connect4Application"
 3 = {@7801} "class org.springframework.web.servlet.support.AbstractDispatcherServletInitializer"
 4 = {@7802} "class org.springframework.boot.web.support.SpringBootServletInitializer"
 5 = {@7803} "class org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration$JerseyWebApplicationInitializer"

而且我发现我必须更改默认实现org.ops4j.pax.web.service.spi.servlet.OsgiDynamicServletContext#setInitParameter()(它应该UnsupportedOperationException根据 OSGi CMPN 140 白板规范抛出......) - 我修复了它。

但是现在,状态是当 spring-boot-web 尝试配置(我看到它被正确调用)调度程序 servlet 时,它无法将其映射到“/”路径下,因为已经映射了默认 servlet。根据 Servlets 规范,这是不可能的,但是 Tomcat 将conf/web.xml(defaultjsp) 中的 servlet 标记为可覆盖,我必须在 Pax Web 8 中做同样的事情......

关键是 - 感谢非常复杂的示例,我肯定会将它变成 Pax Web 8 的集成测试。很快(ish)。


推荐阅读