Skip Navigation
Show nav
Heroku Dev Center
  • Get Started
  • Documentation
  • Changelog
  • Search
  • Get Started
    • Node.js
    • Ruby on Rails
    • Ruby
    • Python
    • Java
    • PHP
    • Go
    • Scala
    • Clojure
  • Documentation
  • Changelog
  • More
    Additional Resources
    • Home
    • Elements
    • Products
    • Pricing
    • Careers
    • Help
    • Status
    • Events
    • Podcasts
    • Compliance Center
    Heroku Blog

    Heroku Blog

    Find out what's new with Heroku on our blog.

    Visit Blog
  • Log inorSign up
View categories

Categories

  • Heroku Architecture
    • Dynos (app containers)
    • Stacks (operating system images)
    • Networking & DNS
    • Platform Policies
    • Platform Principles
  • Command Line
  • Deployment
    • Deploying with Git
    • Deploying with Docker
    • Deployment Integrations
  • Continuous Delivery
    • Continuous Integration
  • Language Support
    • Node.js
    • Ruby
      • Working with Bundler
      • Rails Support
    • Python
      • Background Jobs in Python
      • Working with Django
    • Java
      • Working with Maven
      • Java Database Operations
      • Working with Spring Boot
      • Java Advanced Topics
    • PHP
    • Go
      • Go Dependency Management
    • Scala
    • Clojure
  • Databases & Data Management
    • Heroku Postgres
      • Postgres Basics
      • Postgres Getting Started
      • Postgres Performance
      • Postgres Data Transfer & Preservation
      • Postgres Availability
      • Postgres Special Topics
    • Heroku Data For Redis
    • Apache Kafka on Heroku
    • Other Data Stores
  • Monitoring & Metrics
    • Logging
  • App Performance
  • Add-ons
    • All Add-ons
  • Collaboration
  • Security
    • App Security
    • Identities & Authentication
    • Compliance
  • Heroku Enterprise
    • Private Spaces
      • Infrastructure Networking
    • Enterprise Accounts
    • Enterprise Teams
    • Heroku Connect (Salesforce sync)
      • Heroku Connect Administration
      • Heroku Connect Reference
      • Heroku Connect Troubleshooting
    • Single Sign-on (SSO)
  • Patterns & Best Practices
  • Extending Heroku
    • Platform API
    • App Webhooks
    • Heroku Labs
    • Building Add-ons
      • Add-on Development Tasks
      • Add-on APIs
      • Add-on Guidelines & Requirements
    • Building CLI Plugins
    • Developing Buildpacks
    • Dev Center
  • Accounts & Billing
  • Troubleshooting & Support
  • Integrating with Salesforce
  • Language Support
  • Java
  • Java Advanced Topics
  • Deploying Tomcat-based Java Web Applications with Webapp Runner

Deploying Tomcat-based Java Web Applications with Webapp Runner

English — 日本語に切り替える

Last updated March 06, 2023

Table of Contents

  • Prerequisites
  • Create an application if you don’t already have one
  • Configure Maven to download Webapp Runner
  • Run your application
  • Deploy your application to Heroku
  • Use distributed HTTP sessions with Memcache
  • Clone the source

Webapp Runner allows you to launch an application in a Tomcat container on any computer that has a JRE installed. No previous steps to install Tomcat are required when using Webapp Runner. It’s a regular JAR file that can be executed and configured using the java command.

This article will walk you through building an application that launches with Webapp Runner and deploying that application to Heroku.

Follow each step to build an app from scratch, or skip to the end get the source for this article. You can also use almost any existing Maven webapp project.

Prerequisites

  • Basic Java knowledge, including an installed version of the JVM and Maven.
  • Basic Git knowledge, including an installed version of Git.

How does Webapp Runner work?

When using Webapp Runner you’ll launch your application locally and on Heroku with a command like this:

$ java -jar webapp-runner.jar application.war
deploying app from: /Users/johnsimone/dev/gitrepos/devcenter-webapp-runner/target/webappRunnerSample.war
Feb 14, 2012 5:21:44 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-bio-8080"]
Feb 14, 2012 5:21:44 PM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Tomcat
Feb 14, 2012 5:21:44 PM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/8.0.30
Feb 14, 2012 5:21:44 PM org.apache.catalina.startup.ContextConfig webConfig
INFO: No global web.xml found
Feb 14, 2012 5:21:44 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8080"]

Webapp Runner will then launch a Tomcat instance with the given war deployed to it. This takes advantage of Tomcat’s embedded APIs. Webapp Runner is open source so you can view or contribute to the source code.

Create an application if you don’t already have one

$ mvn archetype:generate -DarchetypeArtifactId=maven-archetype-webapp
...
[INFO] Generating project in Interactive mode
Define value for property 'groupId': : com.example
Define value for property 'artifactId': : helloworld

(you can pick any groupId or artifactId). You now have a complete Java web app in the helloworld directory.

Configure Maven to download Webapp Runner

Although not necessary for using Webapp Runner it’s a good idea to have your build tool download Webapp Runner for you since your application will need it to run. You could, of course, just download Webapp Runner and use it to launch your application without doing this. However having all of your dependencies defined in your build descriptor is important for application portability and repeatability of deployment. In this case we’re using Maven so we’ll use the dependency plugin to download the jar. Add the following plugin configuration to your pom.xml:

<build>
    ...
    <plugins>
        ...
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals><goal>copy</goal></goals>
                    <configuration>
                        <artifactItems>
                            <artifactItem>
                                <groupId>com.heroku</groupId>
                                <artifactId>webapp-runner</artifactId>
                                <version>9.0.72.1</version>
                                <destFileName>webapp-runner.jar</destFileName>
                            </artifactItem>
                        </artifactItems>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

The version of Webapp Runner is pinned to the version of the underlying Tomcat server. Thus, version 9.0.72.1 of Webapp Runner uses version 9.0.72 of Tomcat.

Run your application

To build your application simply run:

$ mvn package

And then run your app using the java command:

$ java -jar target/dependency/webapp-runner.jar target/*.war

That’s it. Your application should start up on port 8080.

Note: if you need your WAR file to be expanded before launching you can add the --expand-war option before target/*.war

Deploy your application to Heroku

Create a Procfile

You declare how you want your application executed in Procfile in the project root. Create this file with a single line:

web: java $JAVA_OPTS -jar target/dependency/webapp-runner.jar --port $PORT target/*.war

Webapp Runner serves the WAR file at the root path (i.e. the URL won’t include the WAR file name in the path). If you need to change this, use the --path option. For more information on Webapp Runner options, run the JAR file with the --help option.

Deploy to Heroku

Commit your changes to Git:

$ git init
$ git add .
$ git commit -m "Ready to deploy"

Create the app:

$ heroku create
Creating high-lightning-129... done, stack is heroku-18
http://high-lightning-129.herokuapp.com/ | git@heroku.com:high-lightning-129.git
Git remote heroku added

Deploy your code:

$ git push heroku main
Counting objects: 227, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (117/117), done.
Writing objects: 100% (227/227), 101.06 KiB, done.
Total 227 (delta 99), reused 220 (delta 98)

-----> Heroku receiving push
-----> Java app detected
-----> Installing Maven 3.0.3..... done
-----> executing .maven/bin/mvn -B -Duser.home=/tmp/build_1jems2so86ck4 -DskipTests=true clean install
       [INFO] Scanning for projects...
       [INFO]
       [INFO] ------------------------------------------------------------------------
       [INFO] Building webappRunnerSample Maven Webapp 1.0-SNAPSHOT
       [INFO] ------------------------------------------------------------------------
       ...
       [INFO] ------------------------------------------------------------------------
       [INFO] BUILD SUCCESS
       [INFO] ------------------------------------------------------------------------
       [INFO] Total time: 36.612s
       [INFO] Finished at: Tue Aug 30 04:03:02 UTC 2011
       [INFO] Final Memory: 19M/287M
       [INFO] ------------------------------------------------------------------------
-----> Discovering process types
       Procfile declares types -> web
-----> Compiled slug size is 4.5MB
-----> Launching... done, v5
       http://pure-window-800.herokuapp.com deployed to Heroku

Congratulations! Your web app should now be up and running on Heroku. Open it in your browser with:

$ heroku open

Deploying with the Heroku Maven Plugin

In lieu of Git deployment, you may use the Heroku Maven Plugin to deploy applications with webapp-runner. The setup for the Maven plugin is similar to what is described in this article, but there are a few key differences. In your pom.xml you will need to replace the maven-dependency-plugin with the heroku-maven-plugin and provide the proper configuration. Then, instead of deploying with a git push you will deploy with a mvn heroku:deploy-war command.

Use distributed HTTP sessions with Memcache

Explicitly storing session state in a database or other backend data store is a more scalable alternative to using distributed HTTP sessions.

Webapp runner supports the memcached-session-manager for Tomcat. In order to enable memcache backed sessions you need to make the configuration for your memcache instance available through environment variables and then enable the sesssion manager.

Make memcache configuration information available

The Heroku Memcachier Add On will set the required environment variables for you. Once you have an existing app get the add on by running:

$ heroku addons:create memcachier:dev

Note: you may have to verify your account before you can add this add on.

When running locally you can either set up a local install of memcache or connect to the remote memcache service provisioned for you by the Heroku add on.

When used with webapp runner the memcache backed session manager looks for 3 environment variables: MEMCACHIER_SERVERS, MEMCACHIER_USERNAME, MEMCACHIER_PASSWORD. You can set these to point to a local memcache install or connect to the remote memcache service provisioned for you by the Heroku add on by running heroku config and copying the values into local environment variables.

Enable memcached-session-manager

To enable memcache backed sessions with webapp runner you include the following flag: --session-store memcache

So if launching locally your command would now look like:

$ java -jar target/dependency/webapp-runner.jar --session-store memcache target/*.war

Or your Procfile would look like:

web:    java $JAVA_OPTS -jar target/dependency/webapp-runner.jar --port $PORT --session-store memcache target/*.war

Clone the source

If you want to skip the creation steps you can clone the finished sample (without memcache backed session):

$ git clone https://github.com/heroku/devcenter-webapp-runner

Keep reading

  • Java Advanced Topics

Feedback

Log in to submit feedback.

Warming Up a Java Process JVM Runtime Metrics

Information & Support

  • Getting Started
  • Documentation
  • Changelog
  • Compliance Center
  • Training & Education
  • Blog
  • Podcasts
  • Support Channels
  • Status

Language Reference

  • Node.js
  • Ruby
  • Java
  • PHP
  • Python
  • Go
  • Scala
  • Clojure

Other Resources

  • Careers
  • Elements
  • Products
  • Pricing

Subscribe to our monthly newsletter

Your email address:

  • RSS
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku Blog
    • Heroku News Blog
    • Heroku Engineering Blog
  • Heroku Podcasts
  • Twitter
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku
    • Heroku Status
  • Facebook
  • Instagram
  • Github
  • LinkedIn
  • YouTube
Heroku is acompany

 © Salesforce.com

  • heroku.com
  • Terms of Service
  • Privacy
  • Cookies
  • Cookie Preferences