Is there documentation on adapting apps to Vaadin 7.2? Having lots of trou

Our application was running fine with Vaadin 7.1.5. When I upgraded to 7.2, I started seeing intermittent “IllegalStateException” messages from AtmosphereFramework in the tomcat log (we’re using an embedded Tomcat 7.0.53, I think). No knowing anything about “Atmosphere”, I was somewhat at a loss what to do. I couldn’t find anything on the Vaadin site about atmosphere other than a year old forum post (https://vaadin.com/forum/#!/thread/3447412) that suggested I change my web.xml to make my servlet use 3.0 servlet spec (it was using 2.4 and I got that straight off the Vaadin web site when I originally created the app) and to add true. I did both, but that seemed to have no effect. Eventually I found another suggestion on the 'net that I needed to add the “async-supported” directly in the servlet service processing via

requestIn.setAttribute("org.apache.catalina.ASYNC_SUPPORTED", true);

that seemed to work - the IllegalStateExceptions went away. But now, I see NullPointerExceptions whenever I close the browser tab that has our application in it. Google’ing returns years old references to the response output stream that is referenced by InternalOutputBuffer (the class causing the NullPointerException) is null. Now I’m stuck - I have no idea what I should be doing here (I’m not really a servlet-savvy developer).

I’m assuming 7.2 does a lot more stuff async and/or immediately and that’s causing these problems. I don’t use “Atmosphere” in our application at all so, theoretically, all this stuff should be pretty much invisible to me - i.e. part of Vaadin’s “implementation”. But perhaps there’s some boilerplate web app setup/config I need and don’t have? Any help/insights would be much appreciated.

Below are both the initial IllegalStateException and subsequent NullPointerException stack traces for reference:
May 21, 2014 10:29:05 AM org.atmosphere.cpr.AtmosphereFramework doCometSupport

SEVERE: AtmosphereFramework exception
java.lang.IllegalStateException: Not supported.
at org.apache.catalina.connector.Request.startAsync(Request.java:1658)
at org.apache.catalina.connector.RequestFacade.startAsync(RequestFacade.java:1029)
at javax.servlet.ServletRequestWrapper.startAsync(ServletRequestWrapper.java:379)
at org.atmosphere.cpr.AtmosphereRequest.startAsync(AtmosphereRequest.java:678)
at org.atmosphere.container.Servlet30CometSupport.suspend(Servlet30CometSupport.java:93)
at org.atmosphere.container.Servlet30CometSupport.service(Servlet30CometSupport.java:68)
at org.atmosphere.container.Tomcat7Servlet30SupportWithWebSocket.doService(Tomcat7Servlet30SupportWithWebSocket.java:67)
at org.atmosphere.container.TomcatWebSocketUtil.doService(TomcatWebSocketUtil.java:98)
at org.atmosphere.container.Tomcat7Servlet30SupportWithWebSocket.service(Tomcat7Servlet30SupportWithWebSocket.java:62)
at org.atmosphere.cpr.AtmosphereFramework.doCometSupport(AtmosphereFramework.java:1802)
at com.vaadin.server.communication.PushRequestHandler.handleRequest(PushRequestHandler.java:143)
at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1405)
at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:237)
at com.blackstratus.reports.ReportsServlet.service(ReportsServlet.java:62)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)

May 21, 2014 2:30:12 PM com.vaadin.server.DefaultErrorHandler doDefault
SEVERE:
java.lang.NullPointerException
at org.apache.coyote.http11.InternalOutputBuffer.realWriteBytes(InternalOutputBuffer.java:215)
at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:480)
at org.apache.coyote.http11.InternalOutputBuffer.endRequest(InternalOutputBuffer.java:159)
at org.apache.coyote.http11.AbstractHttp11Processor.action(AbstractHttp11Processor.java:758)
at org.apache.coyote.Response.action(Response.java:174)
at org.apache.coyote.Response.finish(Response.java:291)
at org.apache.catalina.connector.OutputBuffer.close(OutputBuffer.java:320)
at org.apache.catalina.connector.CoyoteOutputStream.close(CoyoteOutputStream.java:108)
at org.atmosphere.cpr.AtmosphereResponse.closeStreamOrWriter(AtmosphereResponse.java:848)
at org.atmosphere.cpr.AtmosphereInterceptorWriter.close(AtmosphereInterceptorWriter.java:94)
at org.atmosphere.cpr.AtmosphereResponse$2.close(AtmosphereResponse.java:557)
at org.atmosphere.cpr.AtmosphereResponse.closeStreamOrWriter(AtmosphereResponse.java:848)
at org.atmosphere.cpr.AtmosphereInterceptorWriter.close(AtmosphereInterceptorWriter.java:94)
at org.atmosphere.cpr.AtmosphereResponse.close(AtmosphereResponse.java:836)
at org.atmosphere.cpr.AtmosphereResourceImpl.cancel(AtmosphereResourceImpl.java:720)
at org.atmosphere.cpr.AtmosphereResourceImpl.close(AtmosphereResourceImpl.java:785)
at com.vaadin.server.communication.AtmospherePushConnection.disconnect(AtmospherePushConnection.java:291)
at com.vaadin.server.communication.PushHandler.disconnect(PushHandler.java:395)
at com.vaadin.server.communication.PushHandler.onDisconnect(PushHandler.java:317)
at org.atmosphere.cpr.AtmosphereResourceImpl.onDisconnect(AtmosphereResourceImpl.java:663)
at org.atmosphere.cpr.AtmosphereResourceImpl.notifyListeners(AtmosphereResourceImpl.java:582)
at org.atmosphere.cpr.AtmosphereResourceImpl.notifyListeners(AtmosphereResourceImpl.java:564)
at org.atmosphere.cpr.AsynchronousProcessor.completeLifecycle(AsynchronousProcessor.java:426)
at org.atmosphere.interceptor.OnDisconnectInterceptor.inspect(OnDisconnectInterceptor.java:64)
at org.atmosphere.cpr.AsynchronousProcessor.invokeInterceptors(AsynchronousProcessor.java:280)
at org.atmosphere.cpr.AsynchronousProcessor.action(AsynchronousProcessor.java:146)
at org.atmosphere.cpr.AsynchronousProcessor.suspended(AsynchronousProcessor.java:95)
at org.atmosphere.container.Servlet30CometSupport.service(Servlet30CometSupport.java:66)
at org.atmosphere.container.Tomcat7Servlet30SupportWithWebSocket.doService(Tomcat7Servlet30SupportWithWebSocket.java:67)
at org.atmosphere.container.TomcatWebSocketUtil.doService(TomcatWebSocketUtil.java:98)
at org.atmosphere.container.Tomcat7Servlet30SupportWithWebSocket.service(Tomcat7Servlet30SupportWithWebSocket.java:62)
at org.atmosphere.cpr.AtmosphereFramework.doCometSupport(AtmosphereFramework.java:1802)
at com.vaadin.server.communication.PushRequestHandler.handleRequest(PushRequestHandler.java:143)
at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1405)
at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:237)
at com.blackstratus.reports.ReportsServlet.service(ReportsServlet.java:63)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)

Hi Thomas, Atmosphere is the library/framework Vaadin uses to implement server push. Because it handles communication on a low level and calls Vaadin, not vice versa, we cannot simply abstract out all the error conditions it may encounter. That would not necessarily be a sensible thing to do, either.

The nature of server push (and not just Vaadin’s implementation of it!) is currently such that some low-level details, odd error conditions and incompatibilities will necessarily leak through any abstraction, and to use push robustly in a Vaadin application unfortunately necessitates some understanding of the gritty details. The biggest problem is that HTTP-based push mechanisms such as HTTP streaming and long polling are intrinsically hacks, using HTTP in ways it was not meant to be used, and websockets, the “real” push technology, are not yet well-supported by all browsers and servers.

That said, I think the NullPointerException you’re getting is caused by a Vaadin bug. The server tries to close a connection that was already closed by the browser when closing the tab. I’ll open a ticket.

Hi Johannes,
“…and to use push robustly in a Vaadin application unfortunately necessitates some understanding of the gritty details…” - but that’s just it: my application
doesn’t
use this push mechanism: it is something Vaadin does (or needs to do) internally in order to get the level of interactivity it advertises as a core feature. The fact that I, as a Swing programmer without much webapp experience could create an interactive Vaadin app without a steep learning curve was definitely the reason we chose Vaadin.

I have no knowledge of the underlying libraries you use - until the switch from 7.1.5 to 7.2, I didn’t have to. Sadly I have no idea why I needed to change my app’s servlet specification to 3.0 and add the above code line to my servlet’s service() method - I certainly didn’t find it by looking at Vaadin 7.2 release notes. I just google’ed all day and randomly tried things people suggested. All I know is that the above changes caused the IllegalStateException from AtmosphereFramework to go away. But I’m left wondering what other things I’m not configuring - out of ignorance?

Thanks for opening the ticket. Let me know the ticket # so I can vote for it.

Thanks for having taken the time to respond. If the above reads like a big whine, I apologize. I love Vaadin - I guess I’m a bit frustrated because I, not knowing webapp programming, can’t tell what errors are due to my ignorance in that domain and which are shortcomings/bugs in Vaadin.

Best regards,
Tom

Hi Johannes,

can you give me a link to the ticket? I can’t find it on Trac.

Thank you,

lorenzo

As a guy who who will be planning on moving to 7.2 a bit later down the line (currently on 7.1.15), I am quite interested in Thomas being answered fully by those in the know!

I was also having that exception in 7.2, but not anymore in version 7.2.1.

Hi all,

Sorry, I completely forgot about filing the ticket.
It’s here now.

Thomas, if you actually
do not use
server push (eg. have the @Push annotation in your UI or the pushMode init parameter in your web.xml) then something is very wrong and I’m going to need a more comprehensive bug report preferably with a test case. If you do, but just mean that Vaadin should abstract the gritty details away, then what I said unfortunately stands. As much as I’d like everything to just work, the technology isn’t there yet, but we want to offer our users the option to use push if they understand the potential issues. If you feel we’ve too optimistically marketed the push feature as “it just works”, then I apologize for my part.

The same holds in general: As much as Vaadin tries to smooth out the kinks in web app development, the fact remains that the web is a completely different platform than the desktop, and all the differences simply cannot and should not be abstracted away.

André: Which one of the exceptions do you mean, the IllegalStateException or the NullPointerException?

Everybody: If you really do not use push in your application, you should simply not deploy the vaadin-push jar and save a few potential headaches.

NullPointerException

Johannes,
Thanks for the detailed reply - especially the part at the end, where you tell us to simply not deploy vaadin-push.jar if we’re not using push. I had no idea that I’m supposed to leave that jar out - maybe that will fix my problems (will let you know once I had a chance to try.) Perhaps you should at least update the READM.TXT file that comes with the zip distribution. It currently still reads (emphasis/underline added by me):

[i]
To use in a web project:

  1. Copy

    all

    vaadin-* files except vaadin-client and vaadin-client-compiler to WEB-INF/lib in your project
  2. Copy lib/*.jar to WEB-INF/lib in your project
  3. Copy vaadin-client and vaadin-client-compiler to a lib folder which is on your classpath but will not be deployed. These files are only needed when compiling a module (widget set) to Javascript.
    [/i]

Best regards,
Tom

Have to agree with regards to jar deployment. There really needs to be a better list of what is and what isn’t needed at compile time/run time.

Disclaimer: There wasn’t such a list when we first moved to vaadin 7, but maybe it exists now?

Yeah, it should never be
required
that you leave the vaadin-push module out, it’s more like an optimization. I agree, though, that we should document better that it is optional.

Honestly, I’m quite baffled if it indeed in some cases would cause problems, especially the sort of push connection related NPE you’re seeing, in a non-push-using application and would like to investigate further, but as I said, I’ll need more info about the exact circumstances it occurs. Thomas, could you confirm whether you still see the issue on 7.2.1?

I will give 7.21 a try next week. I don’t know why I see these problems and you don’t. A couple possibilities to think about: (1) we don’t use a full Tomcat - we use embedded Tomcat; (2) although our app doesn’t use “push”, perhaps the Vaadin component we use - Charts - uses “push”?

Anyway, I will let you know Monday whether 7.21 has the problem with/without the push jar.

Johannes,
I downloaded the latest version of Vaadin - 7.22 - and didn’t include the “push” jar in my deployment. Now I only see
Jun 9, 2014 1:18:33 PM org.atmosphere.cpr.DefaultAnnotationProcessor configure
INFO: AnnotationProcessor class org.atmosphere.cpr.DefaultAnnotationProcessor$ServletContainerInitializerAnnotationProcessor being used

But it turns out, I lied with respect to not using “push”. My app’s “logout” function uses push to force all browser tabs back to the login page (I realized this when I still got an IllegalStateException :frowning:

When I put the “push” jar and my above-mentioned async-enabling stuff back in the code and re-deployed, everything(*) works in 7.22 - I see neither IllegalStateException nor NullPointerException. Yeah!

But I’d still like to see a document of some sort that describes what, exactly, is required for push to work - right now I have both true in my web.xml but, because that didn’t seem to work, also have the call
requestIn.setAttribute(“org.apache.catalina.ASYNC_SUPPORTED”, true);
in my servlet.service() method. Also, I have no idea why the Vaadin charts lib/ directory includes atmosphere-related jars - I don’t include them at the moment (becasue the README.txt for charts doesn’t tell me it needs them) and things “seem” to work without including them…
*I put the word “seem” in quotes, because I’ve noticed that with Vaadin 7.22 and Charts 1.16, when I click on a chart element to bring up a new Window (which is s long-running operation that does a database lookup), the new window doesn’t show until I move the cursor a bit - is that a totally independent bug - or due to me not including the atmosphere-related jars?

Don’t know if this can help, but I was able to replicate the issue described in ticket 13971 by writing a simple UI with push enabled and transport = Transport.LONG_POLLING (see the attached Eclipse project).
After starting Tomcat 7:

  • I open the UI in my web browser (Chrome, FWIW)
  • I wait for the background thread to finish (3 sec.)
  • I refresh the page

In this way I obtain the error sistematically. Switching transport to STREAMING seems to solve the problem (at least I was not able to reproduce it) but it creates other issues (on my webapp I switched to LONG_POLLING because with STREAMING I was experiencing a similar error when invalidating the http session, this is not shown in my project).

Thank you,

lorenzo
15328.zip (10.5 KB)

I tested the UI Lorenzo has attached, and actually I was also able to reproduce it using STREAMING. The issue seems to resemble the one reported by Atmosphere to Tomcat: https://issues.apache.org/bugzilla/show_bug.cgi?id=53075

I will try to dig more information.

The NPE issue with Push and Tomcat should be fixed in Vaadin 7.2.5
See
http://dev.vaadin.com/ticket/13971
for more details.

I tested the UI above with Vaadin 7.2.5. Indeed the NPE is not shown in the logs but in the browser the behaviour has not changed: the first page refresh results in a “Communication Problem” error.

SEVERE: Communication error: http://localhost:8080/LongPollingBug/VAADIN/vaadinPush.debug.js could not be loaded. Push will not work.

When I initially opened this thread, I tried these things on my own. Well, I finally got around to officially making our app switch from 7.1.5 to the now current 7.2.6. Everything seemed to work fine - i.e. no IllegalStateException and no NullPointerExceptions. But I am running into a bit of trouble when I log out of my application and then back in. My View’s doLogout() method is essentially this (in case it matters):

       VaadinSession vaadinSession = getUI().getSession();
       Collection<UI> uis = vaadinSession.getUIs();
       for (UI ui : uis) {    // tell every UI to bring up the Login view
           ((ReportsUI) ui).setUser(null);
           ui.getPage().setLocation("/reporting/"); 
           ui.push();
       }

The LoginView does come up fine, but when I hit the “submit” button to login, I see the following errors in the web server log. Does anyone know what’s going on? For what it’s worth, the browser is Safari 8.0, not Firefox (I repeated the procedure with Firefox, and I still see the first SEVERE message, but I don’t see the IOException).

Aug 6, 2014 11:14:43 AM com.vaadin.server.communication.PushHandler disconnect
SEVERE: Could not get UI. This should never happen, except when reloading in Firefox - see http://dev.vaadin.com/ticket/14251.
Aug 6, 2014 11:22:17 AM com.vaadin.server.DefaultErrorHandler doDefault
SEVERE: java.io.IOException: Stream closed
at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:413)
at org.apache.catalina.connector.CoyoteReader.read(CoyoteReader.java:101)
at com.vaadin.server.communication.ServerRpcHandler.getMessage(ServerRpcHandler.java:502)
at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:173)
at com.vaadin.server.communication.PushHandler$3.run(PushHandler.java:173)
at com.vaadin.server.communication.PushHandler.callWithUi(PushHandler.java:245)
at com.vaadin.server.communication.PushHandler.access$200(PushHandler.java:56)
at com.vaadin.server.communication.PushHandler$1.onRequest(PushHandler.java:76)
at org.atmosphere.cpr.AsynchronousProcessor.action(AsynchronousProcessor.java:174)
at org.atmosphere.cpr.AsynchronousProcessor.suspended(AsynchronousProcessor.java:95)
at org.atmosphere.container.Servlet30CometSupport.service(Servlet30CometSupport.java:66)
at org.atmosphere.container.Tomcat7Servlet30SupportWithWebSocket.doService(Tomcat7Servlet30SupportWithWebSocket.java:67)
at org.atmosphere.container.TomcatWebSocketUtil.doService(TomcatWebSocketUtil.java:98)
at org.atmosphere.container.Tomcat7Servlet30SupportWithWebSocket.service(Tomcat7Servlet30SupportWithWebSocket.java:62)
at org.atmosphere.cpr.AtmosphereFramework.doCometSupport(AtmosphereFramework.java:1802)
at com.vaadin.server.communication.PushRequestHandler.handleRequest(PushRequestHandler.java:144)
at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1401)
at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:237)
at com.blackstratus.reports.ReportsServlet.service(ReportsServlet.java:63)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at com.blackstratus.reports.ResourcesFilter.doFilter(ResourcesFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:315)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

This might not be your problem, but one thing that seems to be missing from your code is synchronizing access to the other UIs using UI.access(). You should use it also when accessing other UIs of the same session like you do here.