Closed enver-haase closed 3 years ago
I checked your project and how you had changed your project to war packaging. I think it works by accident in jetty currently , probably not in different version. If you use war packaging, you should exclude jetty/tomcat (or mark as provided). Otherwise there will be server code, servlet implementation etc in your war file.
Check these instructions: https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto.traditional-deployment
That's funny, as this is what I discussed with a customer yesterday, theoretically mulling over what should be right and what should not. Will correct that. But -- what we also found is that while it is now probably broken in that it is Jetty dependent, maybe even down to a specific range of Jetty versions: it does work in standalone Jetty but not in the Jetty in Karaf bearing the exact same version number. So I will fix the theoretical issue but I do practically expect nothing from it.
Demo application is now working in both standalone Jetty (9.4.40.v20210413) and Tomcat (8.5.66).
Error deploying to Karaf now looks a little differently:
11:18:47.736 ERROR [paxweb-extender-2-thread-1] Error deploying web application
java.lang.NullPointerException: null
at com.vaadin.flow.server.startup.ApplicationConfiguration.lambda$get$0(ApplicationConfiguration.java:52) ~[?:?]
at com.vaadin.flow.server.VaadinServletContext.getAttribute(VaadinServletContext.java:73) ~[?:?]
at com.vaadin.flow.server.startup.ApplicationConfiguration.get(ApplicationConfiguration.java:49) ~[?:?]
at com.vaadin.flow.server.DeploymentConfigurationFactory.createPropertyDeploymentConfiguration(DeploymentConfigurationFactory.java:82) ~[?:?]
at com.vaadin.flow.server.startup.ServletDeployer$StubServletConfig.createDeploymentConfiguration(ServletDeployer.java:186) ~[?:?]
at com.vaadin.flow.server.startup.ServletDeployer.lambda$getServletConfigurations$0(ServletDeployer.java:293) ~[?:?]
at java.util.Optional.ifPresent(Optional.java:159) ~[?:1.8.0_291]
at com.vaadin.flow.server.startup.ServletDeployer.getServletConfigurations(ServletDeployer.java:292) ~[?:?]
at com.vaadin.flow.server.startup.ServletDeployer.contextInitialized(ServletDeployer.java:210) ~[?:?]
at com.vaadin.flow.server.startup.ServletContextListeners.contextInitialized(ServletContextListeners.java:44) ~[?:?]
at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext$3.call(HttpServiceContext.java:339) ~[?:?]
at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext$3.call(HttpServiceContext.java:335) ~[?:?]
at org.ops4j.pax.swissbox.core.ContextClassLoaderUtils.doWithClassLoader(ContextClassLoaderUtils.java:60) ~[?:?]
at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.callContextInitialized(HttpServiceContext.java:334) ~[?:?]
at org.eclipse.jetty.server.handler.ContextHandler.contextInitialized(ContextHandler.java:997) ~[?:?]
at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:746) ~[?:?]
at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:379) ~[?:?]
at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.startContext(HttpServiceContext.java:392) ~[?:?]
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:911) ~[?:?]
at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:288) ~[?:?]
at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doStart(HttpServiceContext.java:268) ~[?:?]
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:73) ~[?:?]
at org.ops4j.pax.web.service.jetty.internal.JettyServerImpl$1.start(JettyServerImpl.java:327) ~[?:?]
at org.ops4j.pax.web.service.internal.HttpServiceStarted.end(HttpServiceStarted.java:1264) ~[?:?]
at org.ops4j.pax.web.service.internal.HttpServiceProxy.end(HttpServiceProxy.java:456) ~[?:?]
at org.ops4j.pax.web.extender.war.internal.RegisterWebAppVisitorWC.end(RegisterWebAppVisitorWC.java:405) ~[?:?]
at org.ops4j.pax.web.extender.war.internal.model.WebApp.accept(WebApp.java:658) ~[?:?]
at org.ops4j.pax.web.extender.war.internal.WebAppPublisher$WebAppDependencyListener.register(WebAppPublisher.java:228) ~[?:?]
at org.ops4j.pax.web.extender.war.internal.WebAppPublisher$WebAppDependencyListener.addingService(WebAppPublisher.java:173) ~[?:?]
at org.ops4j.pax.web.extender.war.internal.WebAppPublisher$WebAppDependencyListener.addingService(WebAppPublisher.java:129) ~[?:?]
at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:943) ~[osgi.core-7.0.0.jar:?]
at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:871) ~[osgi.core-7.0.0.jar:?]
at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:256) ~[osgi.core-7.0.0.jar:?]
at org.osgi.util.tracker.AbstractTracked.trackInitial(AbstractTracked.java:183) ~[osgi.core-7.0.0.jar:?]
at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:321) ~[osgi.core-7.0.0.jar:?]
at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:264) ~[osgi.core-7.0.0.jar:?]
at org.ops4j.pax.web.extender.war.internal.WebAppPublisher.publish(WebAppPublisher.java:98) ~[?:?]
at org.ops4j.pax.web.extender.war.internal.WebObserver.deploy(WebObserver.java:217) ~[?:?]
at org.ops4j.pax.web.extender.war.internal.WebObserver$1.doStart(WebObserver.java:172) ~[?:?]
at org.ops4j.pax.web.extender.war.internal.extender.SimpleExtension.start(SimpleExtension.java:59) ~[?:?]
at org.ops4j.pax.web.extender.war.internal.extender.AbstractExtender.lambda$createExtension$0(AbstractExtender.java:277) ~[?:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_291]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_291]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [?:1.8.0_291]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [?:1.8.0_291]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_291]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_291]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_291]
Karaf apparently has limited support of Servlet 3.0 specification.
ServletContainerInitializer
s are called but the scanned classes are not passed to the onStartup
method as it's required by the Servlet 3.0 spec.
I cannot find the detailed documentation for the PAX-web version 7.0 but here http://ops4j.github.io/pax/web/5.x/ , "3.2. Servlet 3.0+ Capabilities"the limitation is mentioned:
Servlet container initializers are supported, but the @HandlesTypes annotation is currently ignored.
As a result : PAX-web (default HTTP support in Karaf) is not Servlet 3.0 compatible. So Vaadin app will not work in such servlet containers and we can't do anything with this: Servlet 3.0 spec is required.
You may try to workaround this via :
ServletContainerInitializer
ServletContainerInitializer
, instantiate them inside your own ServletContainerInitializer
and pass the required classes in a hardcoded way: you will have to find all the required classes (they depend on every ServletContainerInitializer
).ServletContainerInitializer
in Flow and it's not easy to do (even though some of them are just validation classes and can be ignored).The exception in this report is a consequence of the LookupServletContainerInitializer
execution.
PAX-web passes only interfaces from the @HandlesTypes
annotation and doesn't discover ANY class which is even inside the same flow-server
.
For WAR case at least LookupInitializer
class has to be passed in the set.
Then Lookup
will be initialized at least. And there will be no exception.
But then there will be no ANY route registered e.g. because the same will happen with RouteRegistryInitializer
which wil get ONLY two annotations from its @HandlesTypes
and that's it. But i t should get all the annotated classes from the WAR.
As a result : nothing will work because there is no any Route target.
This specific issue may be fixed via registering routes programmatically in fact.
Anyway: it will be tricky to go through all nonworking ServletContainerInitializer
and check what they do to be able to workaround them.
I close this issue since as I said: PAX-web is not Servlet 3.0 compatible and is not supported.
I don't know how common it is to use .war
packaging with Karaf and PAX-web. We have already listed a limitation in the documentation:
The Karaf http feature along with war feature provides HTTP Whiteboard implementation which is in practice the standard in Karaf. This implementation is known as PAX Web (see HTTP feature details here). PAX Web is not fully compliant to HTTP Whiteboard OSGi Compendium 7 specification: there are some issues related to ServletContextListener support. Due to these issues the recommended VaadinServlet registration way described in generic Using Vaadin with OSGi tutorial doesn’t work in PAX Web.
It’s still possible to use Vaadin OSGi support with PAX Web though. But the OSGiVaadinServlet should be used as a base class for the servlet which is registered in an OSGi bundle: ...
Not sure what else we should add there ?
The problem with the documentation is : it's about OSGi and all limitations are listed in OSGi section.
WAR has nothing to do with OSGi and this feature is specific for Karaf: it's possible to deploy plain web application (WAR) as is into Karaf and Karaf should behave like Servlet container in this case (not as OSGi container).
Karaf looks like Servlet 3.0 compatible container but in fact it's not: it doesn't support some things from the Servlet 3.0 spec (like ServletContainerInitializer
e.g.).
So Karaf should be mentioned in some sections where supported Servlet containers are listed instead OSGi.
a) Download and unzip: http://www.apache.org/dyn/closer.lua/karaf/4.3.2/apache-karaf-4.3.2.tar.gz Note that this is the latest version of Karaf and that it comes with a feature that uses Jetty 9.4.40.v20210413 to run web applications.
b) Download and unzip: https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-distribution/9.4.40.v20210413/jetty-distribution-9.4.40.v20210413.tar.gz
c) git clone git@github.com:enver-haase/Playground.git cd Playground/vaadin20-base mvn -Pproduction clean package
d) cp target/vaadin20-base-1.0-SNAPSHOT.war /path/to/jetty/webapps/
e) Test in Jetty: cd /path/to/jetty java -jar start.jar Point browser to http://localhost:8080, find the application context and click http://localhost:8080/vaadin20-base-1.0-SNAPSHOT/ -- test the application.
f) Test in Karaf; cd /path/to/karaf
in etc/users.properties uncomment the lines karaf = karaf,g:admingroup g\:admingroup = group,admin,manager,viewer,systembundles,ssh
Execute ./bin/start Wait a second or two. Execute ./bin/client In the Karaf CLI execute feature:install war See web:list -- it is empty yet. Check the log with log:tail (break to CLI with CTRL-C)
Now use another shell to cp /path/to/jetty/webapps/vaadin20-base-1.0-SNAPSHOT.war /path/to/karaf/deploy/
Follow the logs (see above) and dry your tears after seeing:
11:25:42.523 ERROR [paxweb-extender-2-thread-1] Error deploying web application java.lang.IllegalStateException: Unable to find ServletContextHandler for provided ServletContext at org.eclipse.jetty.websocket.server.NativeWebSocketServletContainerInitializer.onStartup(NativeWebSocketServletContainerInitializer.java:120) ~[?:?] at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext$1.call(HttpServiceContext.java:219) ~[?:?] at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext$1.call(HttpServiceContext.java:214) ~[?:?] at org.ops4j.pax.swissbox.core.ContextClassLoaderUtils.doWithClassLoader(ContextClassLoaderUtils.java:60) ~[?:?]
Point browser to http://localhost:8181/vaadin20-base -- as expected after seeing the exception above, nothing here.
web:list also gives you the state "Failed".
Tried this in macOS and Linux Ubuntu, both latest stable. Browser does not matter.