How to deploy your Eclipse RAP application to Heroku

In this post I'll teach you how to deploy your Eclipse RAP application to Heroku. You can find the whole example project on Github by clicking here.

As you know, Eclipse RAP applications can be configured in several ways. The application setup for this example is the RWT Standalone setup, i.e.:

  • We deploy the application as a WAR file
  • We use the Application Configuration API
  • We work on JEE compatibility mode
  • We do NOT use OSGI

Basic setup: Maven

To build our application we'll use maven. In order to work with Heroku, you need to make sure that you use at most Java 1.6 as target. Also, other that the standard dependencies for Eclipse RAP you need to add the javax.servlet api in the provided scope. For this project we use the following dependencies:

    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.eclipse.rap</groupId>
            <artifactId>org.eclipse.rap.rwt</artifactId>
            <version>2.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.core</groupId>
            <artifactId>commands</artifactId>
            <version>3.3.0-I20070605-0010</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.rap</groupId>
            <artifactId>org.eclipse.rap.jface</artifactId>
            <version>2.0.0</version>
        </dependency>
    </dependencies>

Limitations of Heroku and RAP 2.3 (and how to overcome them)

Heroku's launcher

The first limitation of Heroku is that you are not the owner of the application server. In fact, Heroku will let you launch only plain old java applications. 

Happily for us they also proved a launcher to launch WAR files in a Tomcat application server. You can use it to test your application before trying to deploy it to Heroku. To download it, just clone it here: https://github.com/heroku/devcenter-webapp-runner.git and follow the instructions in the README file to launch your war file.

Writing to the filesystem (or not)

The second one is that Heroku won't let you write to the file system (at least according to their reference). Indeed, the only place you can write to is the "/tmp" directory. The eclipse RAP framework, however, needs to write to the filesystem (at least in version 2.3, which I'm using). So, if you don't tell eclipse RAP framework where to write, it will try to write it to the '/' directory. Other than that, Tomcat 7 won't even let you try to write the '/' directory. On trying to read it (using the getRealPath() function) it will return null, which will crash the whole system even before it starts.

Solving this problem is a little bit trickier. You need to tell the RAP framework to write all the files in the directory '/tmp'. To do this requires setting a ServletContext attribute. One way to do this is to create a new class extending the RWTServletContextListener class. The new class should override the contextInitialized() method to set the right attribute in the servlet context.  The example is down below:

package net.lopezbobeda.rap.examples.mail;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;

import org.eclipse.rap.rwt.engine.RWTServletContextListener;

public class MyListener extends RWTServletContextListener{
@Override
public void contextInitialized(ServletContextEvent event) {
    ServletContext servletContext = event.getServletContext();
    servletContext.setAttribute(BasicApplication.RESOURCE_ROOT_LOCATION, "/tmp");
    super.contextInitialized(event);
}
}

Once you did this you need to modify the web.xml file and changing the listener to the new class you created. To do this, add the following lines to the web.xml file:

<listener>
<listener-class>net.lopezbobeda.rap.examples.mail.MyListener</listener-class>
</listener>

After doing this, the server won't stop anymore, however, it will still not work. The server will not crash, but your application will show a blank page instead the application itself.

Showing the resources

The final problem is that even if you get to write you content to the directory you want, you need to force Tomcat to serve it when needed. An easy solution for this problem is to create a FileServlet. Easier done than said, because BalusC has already created a FileServlet for us, so we just need to copy and paste it in our code and change a single parameter (really, Ctrl + C, Ctrl + V). The FileServlet code can be found here. In the FileServlet, you just need to define the base path to:

// Define base path somehow. You can define it as init-param of the
// servlet.
this.filePath = "/tmp/rwt-resources";


Then you need to register the FileServlet in web.xml for the address /rwt-resources. To do this, just add the following lines in the web.xml file:

<servlet>
<servlet-name>fileServlet</servlet-name>
<servlet-class>net.lopezbobeda.rap.examples.mail.FileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>fileServlet</servlet-name>
<url-pattern>/rwt-resources/*</url-pattern>
</servlet-mapping>

 


And that's all, you can now compile your RAP application and deploy it to Heroku using the command:

heroku deploy:war --war target/net.lopezbobeda.rap.example.mail-1.0.0.qualifier.war --app


If you have any questions or feedback, or this tutorial helped you, I'd appreciate a lot if you leave a comment and/or share it. If you are interested in other tutorials like this, do not hesitate to join the mailing list.

tweet: