flow-and-components-documentation icon indicating copy to clipboard operation
flow-and-components-documentation copied to clipboard

Add documentation on how to deploy a production mode Flow app to Tomcat via Eclipse Servers tab

Open Peppe opened this issue 6 years ago • 3 comments

Deploying a Vaadin app to Tomcat 8.0.x, 8.5.x and 9.0.x being built with production mode has some visual elements broken.

Steps to reproduce

  1. Download Beverage buddy from https://vaadin.com/start/v10-simple-ui
  2. Import it to Eclipse
  3. Download Tomcat and extract it
  4. Add Tomcat to Eclipse via the servers tab
  5. Add the app to deployment to Tomcat
  6. Double click server -> Open Launch Configuration -> Arguments -> Add to VM arguments -Dvaadin.productionMode
  7. Start up the server from servers tab.

Broken parts

When trying to start, you get the following exception and the app doesn't start.

java.lang.IllegalArgumentException: Unable to create an instance of 'com.vaadin.starter.beveragebuddy.ui.views.reviewslist.ReviewsList'. The constructor threw an exception.
	at com.vaadin.flow.internal.ReflectTools.createProxyInstance(ReflectTools.java:507)
	at com.vaadin.flow.internal.ReflectTools.createInstance(ReflectTools.java:444)
	at com.vaadin.flow.di.DefaultInstantiator.getOrCreate(DefaultInstantiator.java:64)
	at com.vaadin.flow.di.Instantiator.createRouteTarget(Instantiator.java:157)
	at com.vaadin.flow.router.internal.AbstractNavigationStateRenderer.lambda$getRouteTarget$1(AbstractNavigationStateRenderer.java:114)
	at java.util.Optional.orElseGet(Optional.java:267)
	at com.vaadin.flow.router.internal.AbstractNavigationStateRenderer.getRouteTarget(AbstractNavigationStateRenderer.java:113)
	at com.vaadin.flow.router.internal.AbstractNavigationStateRenderer.handle(AbstractNavigationStateRenderer.java:165)
	at com.vaadin.flow.router.Router.handleNavigation(Router.java:178)
	at com.vaadin.flow.router.Router.navigate(Router.java:150)
	at com.vaadin.flow.router.Router.initializeUI(Router.java:91)
	at com.vaadin.flow.component.UI.lambda$doInit$0(UI.java:205)
	at java.util.Optional.ifPresent(Optional.java:159)
	at com.vaadin.flow.component.UI.doInit(UI.java:205)
	at com.vaadin.flow.server.BootstrapHandler.createAndInitUI(BootstrapHandler.java:988)
	at com.vaadin.flow.server.BootstrapHandler.synchronizedHandleRequest(BootstrapHandler.java:388)
	at com.vaadin.flow.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40)
	at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1541)
	at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:345)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:94)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:502)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1132)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:684)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1539)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1495)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at com.vaadin.flow.internal.ReflectTools.createProxyInstance(ReflectTools.java:476)
	... 39 more
Caused by: java.lang.IllegalStateException: Can't find resource 'frontend://src/views/reviewslist/reviews-list.html' via the servlet context
	at com.vaadin.flow.component.polymertemplate.DefaultTemplateParser.getTemplateContent(DefaultTemplateParser.java:111)
	at com.vaadin.flow.component.polymertemplate.TemplateDataAnalyzer.parseTemplate(TemplateDataAnalyzer.java:180)
	at com.vaadin.flow.component.polymertemplate.TemplateInitializer.<init>(TemplateInitializer.java:91)
	at com.vaadin.flow.component.polymertemplate.PolymerTemplate.<init>(PolymerTemplate.java:78)
	at com.vaadin.flow.component.polymertemplate.PolymerTemplate.<init>(PolymerTemplate.java:93)
	at com.vaadin.starter.beveragebuddy.ui.views.reviewslist.ReviewsList.<init>(ReviewsList.java:78)
	... 44 more

```

Peppe avatar Apr 18 '18 07:04 Peppe

Tested and found within the https://github.com/vaadin/beverage-starter-flow/issues/193 ticket.

Peppe avatar Apr 18 '18 07:04 Peppe

I'm not sure what to do with this ticket. From the user perspective this is definitely an issue: it's impossible to get running application in production mode out of the box. From the other point of view: there are missing steps and limitation in eclipse servers tab resources registration:

  • it's not enough just to start the server in the production mode via VM argument -Dvaadin.productionMode. It's not enough in any configuration: this just starts the server but the application is not build for production.
  • Even if the application is build and ready to production it won't work with the web server registered via Eclipse servers tab out of the box.

So : first of all one needs to build the application for production using maven plugin. It's described here in details. The beverage application is already configured for the production and one needs to run mvn -Dvaadin.productionMode package to package application for production.

Now when the application is build for production it may be started. But you should either start it deploying it as a WAR (and use my_starter_project-1.0-SNAPSHOT.war) or use extracted folder my_starter_project-1.0-SNAPSHOT (inside target). The web module registered as a resource via the Eclipse server tab doesn't do neither one nor another. I don't know the exact details of the way how eclipse deploys the application which is the project registered as a web module but I assume it uses target folder of the project for that. This folder contains classes and frontend directory but it's not enough for production mode. It should attach target/build/ as a web resources root. And I don't see how I can configure that via Eclipse.

The way how I may make it work is: register module via the Modules tab inside Eclipse servers tab and add an external web module with target/my_starter_project-1.0-SNAPSHOT as a root. This root contains all resources in order.

So the ticket is kind of invalid but it also makes sense: it's too hard (and not obvious) to run application in production using Eclipse servers tab.

But I don't see easy ways how it can be improved. If you have any ideas please let me know.

denis-anisimov avatar Apr 23 '18 12:04 denis-anisimov

I think it would be enough if we could just highlight "How to deploy to Tomcat in Eclipse" in our documentation.

The thing is, that we don't really currently have any place for such documentation at the moment. I was thinking that we could add it to the getting started tutorial, since it already expects you to use Eclipse, but it already instructs people to run Jetty using Maven plugin via Eclipse, which is IMO a better option. And I don't want to bloat the tutorial as it already is quite lengthy.

Another option would be to add another documentation page, maybe under Advanced Topics, and describe there "Deploying to Application Servers" where the workaround of adding a module could be described. But let's see if we would have anything else for that documentation.

pleku avatar Apr 23 '18 13:04 pleku