如何解决如何使用 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.xml
(default
和 jsp
)中的 servlet 标记为 override'able,我必须在Pax Web 8...
重点是 - 感谢您提供非常复杂的示例,我肯定会将其转换为 Pax Web 8 的集成测试。很快(ish)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。