In a Nutshell: Deploying a Java webapp to Heroku

This post walks you through getting started with Heroku and deploying a simple Spring MVC web app.

  • Follow the Getting Started guide to get your Heroku Toolbelt setup
  • Login to Heroku from the commandline with ‘heroku login’
  • Since Heroku does not provide it’s own app server, you configure your pom.xml to pull in a dependency on a container, like Jetty (this is from the Getting Started with Spring MVC guide)
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.3</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals><goal>copy</goal></goals>
            <configuration>
                <artifactItems>
                    <artifactItem>
                        <groupId>org.mortbay.jetty</groupId>
                        <artifactId>jetty-runner</artifactId>
                        <version>7.4.5.v20110725</version>
                        <destFileName>jetty-runner.jar</destFileName>
                    </artifactItem>
                </artifactItems>
            </configuration>
        </execution>
    </executions>
</plugin>

The Heroku Getting Started with Java instructions give some steps on how to run your app locally by running Java from the command line and passing a classpath pointing to your target dir, but this seems odd since Jetty is able to run from Mavan against your created war file or even the code compiled to your target dir using the ‘mvn jetty:run’ command. Add the following to the above <plugins> section to enable and use this approach instead:

<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
</plugin>

  • Heroku uses a file named ‘Procfile’ in the root of your project to tell Heroku how to run your code. Add this file, and inside it add this one line
web: java $JAVA_OPTS -jar target/dependency/jetty-runner.jar --port $PORT target/*.war
  • Create your new app on Heroku with ‘heroku create –stack cedar’
  • Add and commit your code if you haven’t already, then push to your heroku remote git:
git add . git commit -m "commit comment" git push heroku master

At this point Heroku should build you app remotely and start it up.

If you see this error about the jetty-runner.jar missing, then you forgot to add the plugin part to your pom.xml to copy the jetty jar to the target/dependency dir:

Unable to access jarfile target/dependency/jetty-runner.jar

JSTL String test oddity

I’ve come across this multiple times, and for some reason this always catches me out. You’d think being that EL has ‘eq’ and ‘ne’ operators that work with Strings that this should work:

<c:if test="${hello.name ne ''}">
    Hello <c:out value="${hello.name}"/>
</c:if>

This seems to make sense that it would do what you think it should do, but no, it always returns true. The code you’re looking for is using EL operator ’empty’:

<c:if test="${!empty hello.name}">
    Hello <c:out value="${hello.name}"/>
</c:if>

Git notes

Typical add/commit/push workflow:

#add local change ready to commit
git add .

#git commit changes to repo
git commit -m "commit message"

#push to remote repo
git push [optional remote repo name here, eg origin, etc]

Find changes committed locally compared with remote repo, i.e. to find what you’ve committed locally but not yet pushed:

git diff --stat [remote repo name]

List associated remote repos and their locations:

git remote -v

Add a new remote repo to an existing local app/repo:

git remote add remotename remote_git_repo_url