Getting the number of active sessions in Tomcat

This is really useful when you’re trying to determine if your Java application running on a Tomcat server is currently serving any clients. For example, if your server is under use, you can avoid taking it offline for maintenance or upgrade. Or, you can use it to determine the load on a server.

Essentially Tomcat has some internal statistics that can be accessed using JMX (Java Management Extension). More information and details for that are available here: https://tomcat.apache.org/tomcat-8.0-doc/monitoring.html

The Tomcat JMX stats can be accessed in several ways. This article will cover how to access them from within the tomcat serer, which was our requirement. Since the application deployed to the tomcat server will be running locally on the JVM running tomcat, JMX can be accessed locally from the Java code, and no remote setup is required.

The code is as simple as this:

MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
ObjectName objectName = new ObjectName("Catalina:type=Manager,context=/,host=localhost");
int activeSessions = (Integer) mBeanServer.getAttribute(objectName, "activeSessions");

And that’s it! You’ll get the number of active sessions tomcat is reporting. And since this is running within the application deployed to tomcat, no remote setup or custom JVM arguments for tomcat are required.

Vaadin upgrade from 7.4.5 to 7.6.1

I was recently tasked with upgrading our Vaadin applications at work from version 7.4.5 to version 7.6.1. I came across an issue that took me a long time to figure out, so I thought I’d share in case anyone else is running into the same.

The process went pretty smoothly at first. We use Ivy for our projects, and simply updating the Vaadin version in ivy.xml allowed all the new library files to be downloaded. Then I re-compiled the widgetset, and took one of our applications out for a spin.

Lo and behold I got an error stating: “Failed to load the bootstrap javascript: ./VAADIN/vaadinBootstrap.js?v=7.6.1”. I did some investigating, and noticed that the vaadinBootstrap.js served to the browser looked like a binary file, whereas the browser was trying to interpret it as a JavaScript file.

I eventually realized that the vaadinBootstrap.js is compressed. I did everything I could to verify that the compression filters were correct, but the browser for some reason seemed like it was not uncompressing vaadinBootstrap.js before trying to interpret it.

Turns out that in prior versions of Vaadin, with the Vaadin demo applications, Vaadin had stuck in a CompressionFilter using net.sf.ehcache.constructs.web.filter.GzipFilter to web.xml. It compressed all *.js, *.html, *.css files (which only works if the browser/client announces it supports it in the HTTP headers) before serving it. HOWEVER, in the new version of Vaadin (7.6.1) it seems that there are some new compression filters already built in! Hence, the content (in this case vaadinBootstrap.js) was compressed twice! So the browser would uncompress it as it should, but that would yield a second compressed file! Sheesh. Had almost pulled my hair out before I figured this out.

The solution was to get rid of all the custom compression filters using net.sf.ehcache.constructs.web.filter.GzipFilter from our web.xml. And then everything started working smoothly.

Vaadin: Executing custom JavaScript from a thread, or loading custom JavaScript functions into global scope

As you may know already, in Vaadin you can use com.vaadin.ui.JavaScript.getCurrent().execute(…) function to execute some custom JavaScript on the client browser.

  1. Executing custom JavaScript from a thread:
    The above works well as long as the JavaScript execute() method is being called on the main UI thread. However, if JavaScript.getCurrent().execute() is called from a background thread, the JavaScript won’t get executed until there is a periodic refresh of the UI, or there’s a UI event (triggered by the user, such as a mouse click somewhere). This can seem to cause erratic behavior, with the JavaScript executing at unpredictable times. (Side note: any Vaadin UI access/manipulation from a background thread needs to be done inside com.vaadin.UI.getCurrent().access(new Runnable() { … });, and also note that you want to do your time-consuming heavy lifting first (such as retrieving data from the back end) and then go into UI.getCurrent().access(…) to manipulate the UI).To get around this problem, simply use Vaadin Push. You’ll need to enable push if not already (see Vaadin documentation on how). Then depending on the push mode you’ve used (manual or automatic) you’ll either need to call com.vaadin.ui.UI.getCurrent().push() or not (for manual mode you’ll need to call the push() method, for automatic mode it will be called after the runnable you send to the UI.access(…) method finishes executing). So call get JavaScript.execute(…), and then UI.push() last. Example:

    new Thread() {
        public void run() {
            //some long running background work
                 UI.getCurrent.access(new Runnable() {
                public void run() {
                    JavaScript.getCurrent().execute("alert('Background Task Complete!');");
                                UI.getCurent().push();
                }
            });
        }
    }.start();
  2. Loading custom JavaScript functions into global scope:
    This is extremely useful so you can define a JavaScript function which you can use later from JavaScript.getCurrent().execute(…), such as inside an event (a button click, for example). However, the JavaScript function will need to be in the global scope by injecting it into thetag for the HTML page served by Vaadin. To do this, use the following code while your Vaadin view is being created, or is being enter()’ed.

    StringBuilder script = new StringBuilder(); script .append("var head = document.getElementsByTagName('head')[0];") .append("var script = document.createElement('script');") .append("script.content='function sayHello() { alert(\"Hello!\");}';") .append("head.appendChild(script);"); JavaScript.getCurrent().execute(script.toString());

    Note: as I mentioned, a JavaScript function can only be loaded this way when the view is being created, or in the view’s enter() method. To create a function this way AFTER the page is already loaded (such as through some event), you’ll need to use Vaadin Push, and call UI.getCurrent().push() after the JavaScript.getCurrent().execute() even though you’re not on a background thread.

  3. You can define a function in the script tag being created above, which can then be called later on through JavaScript.getCurrent().execute(“sayHello();”); perhaps inside a Vaadin button click listener.

Enjoy!

Making a Vaadin window transparent/translucent

We had a need to do this recently, and it wasn’t obvious, so I thought I’d share.

One thing to note is that if the window is modal, this trick won’t work. Since for modal windows, Vaadin adds some more styling around the window to the back the background “dimmed”, thus giving a stronger visual focus on the modal window. For regular (non-modal) windows, this trick works great, especially if you just want to overlay some information on content behind the window.

In your java code, add the following style to your Vaadin Window:

myWindow.addStyleName("translucent");

In your theme stylesheet for your application (most likely a “.scss” file), add the following styles:

.v-window-translucent
{
  background-color: rgba(255,255,255,0.6) !important;
}
div.v-window-translucent .v-window-contents {
  background: rgba(255,255,255,0.6);
}

Then compile your theme, and refresh your page. Viola! Your window will now be translucent.

To tweak the translucency, modify the “a” (alpha) value in the rgba inside the theme style. 0.6 worked well for us, making it a bit translucent. To make it less translucent, try a value greater than 0.6. And to make it completely transparent, try 0.

Enjoy!

Resolving Vaadin push with long polling issues in AWS Elastic Beanstalk

This took me a long time to figure out, so I thought I’d share it with anyone else struggling with this.

When you upload a Vaadin application to the AWS Elastic Beanstalk, Tomcat sits behind an Apache server that proxies connections to it. (Note: this may apply to you even if you’re not in AWS/ElasticBeanstalk. If you use Apache as a proxy to an application server, be it Tomcat or something else, this could still be an issue).

If you’re using Vaadin push in long polling mode (Transport.LONG_POLLING), it turns out that the connection between the client (browser) and server (tomcat, or your other java application server) gets dropped due to a timeout issue. If there is no data exchanged between the server (tomcat) and the client (browser), then the connection is deemed “idle” by Apache and gets dropped. This is an issue because with long polling, the HTTP connection remains open indefinitely, and that’s information is pushed to the client from the server.

Now with Vaadin’s push, it’s supposed to recover from a dropped connection. The connection is supposed to just get reestablished, and everything resumes. That’s an ideal scenario. In my experience, that doesn’t always work the way it should. If I’m on a Vaadin web app through my browser, and sit idle for a while, when I come back to it a lot of time it resumes fine (I can see push reestablishing itself in the console), but a lot of times the app just hangs forever.

Another thing to note is that Vaadin sends a heartbeat to the client, to check if the client is still there. The default heartbeat is every 5 minutes. When a heartbeat is sent, Apache’s idle connection timeout is reset. So if there is no user activity for a few minutes, the goal is to adjust the configuration so that the heartbeat happens before Apache times out the HTTP connection.

So the solution for this is to

  1. Modify Apache’s timeout for idle connections. I believe the default setting in AWS’s configuration for Apache, is 60 seconds. You’ll need to ssh into your server, edit /etc/httpd/conf/httpd.conf, and look for the “Timeout” directive. Change the Timeout directive to be greater-than the default Vaadin heartbeat of 5 minutes. Try 6 minutes (note: the Timeout value is in seconds), so you’d set “Timeout 360”. The downside of this approach is if your server has hundreds of thousands of requests, surely some legitimately idle connections (where the client is gone without cleaning up and not coming back) will linger for longer than 60 seconds, this affecting your system performance.
  2. Modify Vaadin’s heartbeat to be less than 60 seconds. You can edit your web.xml, and add an heartbeatInterval parameter like so:
        <context-param>
            <param-name>heartbeatIntervalparam-name>
            <param-value>120param-value>
        context-param>
  3. You can tweak both the Vaadin heartbeat, and the Apache Timeout value to some reasonable values that suit your needs the best. Just make sure that the heartbeat interval is shorter than the timeout.

Enjoy!