如何使用 Pax-Web 在 Karaf 4.3.2 上运行 Vaadin 8 或 20 应用程序?

问题描述

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

码头
雄猫
野蝇

然而,与 feature:install war 一起使用时,我既找不到那个地方,也不知道在 Karaf CLI 上输入什么来在这三个之间切换。

好像这还不够,我在 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,所以我首先 喜欢尝试其他两个应用程序容器以帮助调试。

如果有相关文档,有人可以指点我吗?

解决方法

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

SpringServletContainerInitializer 注释为:

@HandlesTypes(WebApplicationInitializer.class)

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

但是 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() 的默认实现(根据 OSGi CMPN 140 白板规范,它应该抛出 UnsupportedOperationException...) - 我修复了它。

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

重点是 - 感谢您提供非常复杂的示例,我肯定会将其转换为 Pax Web 8 的集成测试。很快(ish)。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...