Porotype Notes from a Vaadineer

Serving static content with Vaadin

TV Nation: 16/365

I’ve heard the question “how do I serve static resources with Vaadin” (and it’s relatives) quite many times, so I thought it’s time to address this subject.

This is actually not so much a Vaadin specific issue, but mostly a generic servlet issue - but there are some Vaadin specific things you should know.

Also, Vaadin applications are quite often mapped to “/*”, which requires you to know how to configure your setup correctly to use the ‘default’ servlet for static content - I think this is the main reason Vaadin developers seem to struggle with this.

Let’s start:

Using the default servlet

Quite often you have your Vaadin application (or any servlet for that matter) set up to handle all paths ‘below’ its context:

<servlet>
    <servlet-name>MyApp</servlet-name>
    ...
</servlet>
<servlet-mapping>
    <servlet-name>MyApp</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

The application will now handle http://…/, http://…/asd as well as http://…/asd/foo and so on.

But wait! You have some static files you want to serve - perhaps an image, or a html help file. You create a folder named ‘static’ and put the files there, but http://…/static/help.html just renders the servlet, because it’s handling all the things. Default servlet to the rescue:

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/static/*</url-pattern>
</servlet-mapping>

This tells your servlet container to use the ‘default’ servlet for anything under the ‘static’ path (I tested with Tomcat and Jetty - YMMV if you are using something else). The default servlet is a built-in servlet that is made for serving static files (note that you are still serving files trough a servlet - more on that later).

Serving VAADIN

Vaadin applications use some static resources, such as widgetsets (GWT javascript files) and themes (css and image files). These are loaded from paths starting with ‘VAADIN’, as you can see with e.g Firebug. For convenience these file are by default packaged into the vaadin.jar and served from it trough the Vaadin servlet, but this is not the most efficient way, and it’s recommended that you deploy the static resources separately in production environments.

Let’s start by using the ‘default’ servlet to serve static Vaadin resources: first extract the ‘VAADIN’ folder from the vaadin.jar to the root of your web application (a jar is a regular zip file - use unzip or any application that can handle zips):

    marc$ pwd
    /Users/marc/Projects/Staticfiles/WebContent
    marc$ unzip WEB-INF/lib/vaadin-6.7.1.jar `unzip -Z -1 WEB-INF/lib/vaadin-6.7.1.jar | grep VAADIN/`

Then add this after your application’s mapping in web.xml:

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/VAADIN/*</url-pattern>
</servlet-mapping>

NOTE If you update the vaadin.jar, you have to remember to update the VAADIN folder (by re-extracting from the new jar), since the files in the jar might have changed. This is one of the reasons it’s convenient to serve the files directly from the jar while developing the application.

However, we’re still serving the static files trough a servlet, which is usually not the most efficient way (note that different servlet containers perform differently in this regard). Let’s look at how that can be fixed.

Going for performance

Serving static files trough the servlet containers default servlet is usually not seen as the most efficient way to serve static files. Instead, there are servers that are particularly good at serving static content, so for production environments it might make sense to have a setup where the static content is served by such a server, while the application requests are passed trough to the servlet container.

Note that servers evolve, and you might be able to get sufficient performance for your use-case without using separate file servers and get away with a simpler setup.

Also, I am not going to show you how to configure any particular server for performance, since this might vary depending on your setup. Instead, I’ll just show the basic idea, and point in (hopefully) the right direction.

YMMV, please test it yourself :-)

Apache httpd

A common setup is to have an Apache server in front of the servlet container. AJP currently seems to be the prefered way to do this with Tomcat, while mod_proxy is strongly recommended for Jetty.

Nginx

Another setup that is very popular at the moment to use Nginx to serve static files. Setup Nginx to listen to port 80 (or whichever port your application should run on), tomcat/jetty on 8080, and do something like this in your nginx.conf:

location / {
    #servlet
    proxy_pass http://127.0.0.1:8080/;
}
location ~ .*/VAADIN/.* {
    root   <FILESYSTEM_PATH_TO_STATIC_CONTENT>;
    index  index.html index.htm;
}

Note that this is a quick example - you should familiarize yourself with Nginx configuration and set it up to suit your needs. You might want to look at the JavaServers example.

CDNS

Finally, you might want to consider deploying your static files on a CDNS instead of serving the content yourself.

Summary

When making a production deployment, please make sure that static resources are extracted from the vaadin.jar and served using a method that matches your performance requirements (‘default’ servlet, Apache httpd, Nginx, CDNS, …) Verify that your requirements are met by testing and measuring!

Also make sure that the cache headers are set appropriately for the static content, and that gzip compression is enabled - also for JSON responses (unless you have specific reasons for not doing so).

Finally, if you want me to elaborate on any of this, please let me know!