Video: Java, Play Framework & Scala Apps on Heroku

By James Ward | Published: February 10, 2012

If you haven’t been able to make it to one of my Java User Group talks about Heroku but you want to see the presentation, then you are in luck! The Portland JUG recorded my talk on Running Java, Play Framework, and Scala Apps on the Cloud with Heroku. Check it out and let me know if you have any questions or comments. Thanks!

Posted in Heroku, Java, Play Framework, Scala | Leave a comment

Video: Spring Roo and Grails Apps on the Cloud

By James Ward | Published: February 9, 2012

At SpringOne 2GX I did a presentation about running Spring Roo (really Spring anything) and Grails apps on the cloud with Heroku. A video recording of my session has been posted on InfoQ.

If you want to try out Spring Roo or Grails on Heroku then one way is to deploy a copy of one of the demos I showed. I’ve created a little app that makes that easy. Just go to java.herokuapp.com and select a demo then enter your email address (your Heroku username) and click Go! A copy of the demo will be deployed for you on Heroku and then you will see instructions on how to get started with it. Give it a try and let me know what you think.

Posted in Heroku, Java, Spring | Leave a comment

Deploy Containerless Tapestry Apps on Heroku

By James Ward | Published: February 8, 2012

Recently I spent some time with Howard Lewis Ship, creator of the Apache Tapestry web framework. Howard is a technical rock star so it was really fun to sit down with him and hack on some code. Our goal was to make it easy for people to run their Tapestry apps on the cloud with Heroku. You can run anything on Heroku so there are a variety of ways to run Tapestry apps on Heroku. We wanted to put together something that helps Tapestry users run their apps in the most optimal way. What we came up with is available in Howard’s tapx-heroku package on GitHub. Lets walk through what it does.

The JettyMain class provides a simple way to start a Java web app using an embedded Jetty server. This “Containerless” method has these advantages over the traditional container deployment model:

  • The HTTP handling library (Jetty in this case) is a dependency of my application. This alleviates pain caused by differences in developer and production deployment environments.
  • My app is just a plain Java library so it can be packaged as a regular JAR file and used as a dependency itself.
  • The application starts up super fast.
  • I have a way to setup the application (like the session storage provider) in code instead of having to do it in XML.
  • Development cycles are faster as a result of lightweight packaging and deployment. With IntelliJ or JRebel class hot-swapping can make those cycles even shorter. (This is also an out-of-the-box feature with Tapestry.)

To use JettyMain with your Tapestry app, we just need to update the Maven build (pom.xml) file. You can do this with an existing app or start from scratch using the Tapestry Maven Archetype. Here is a simple pom.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="maven.apache.org/POM/4.0.0" xmlns:xsi="www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="maven.apache.org/POM/4.0.0 maven.apache.org/maven-v4_0_0.xsd">
 
    <modelVersion>4.0.0</modelVersion>
 
    <groupId>org.example</groupId>
    <version>1.0-SNAPSHOT</version>
    <name>herokuapp</name>
    <artifactId>herokuapp</artifactId>
    <packaging>jar</packaging>
 
    <repositories>
        <repository>
            <id>howardlewisship</id>
            <url>howardlewisship.com/snapshot-repository</url>
        </repository>
    </repositories>
 
    <dependencies>
        <dependency>
            <groupId>org.apache.tapestry</groupId>
            <artifactId>tapestry-core</artifactId>
            <version>5.3.2</version>
        </dependency>
        <dependency>
            <groupId>com.howardlewisship</groupId>
            <artifactId>tapx-heroku</artifactId>
            <version>1.2-SNAPSHOT</version>
        </dependency>
    </dependencies>
 
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.4</version>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals><goal>copy-dependencies</goal></goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
 
</project>

This specifies Tapestry and the tapx-heroku libraries as dependencies. The tapx-heroku library will automatically pull in the Jetty dependencies. The maven-dependency-plugin will copy the runtime dependencies from the local Maven cache to the target/dependency directory so that we can easily setup the application’s runtime classpath.

To build the app locally just run:

mvn package

To launch the application run:

java -cp target/dependency/*:target/classes com.howardlewisship.tapx.heroku.JettyMain

That’s it! Tapestry, tapx-heroku (JettyMain), Jetty, your application classes, and the rest of the required dependencies are all loaded into the JVM and the web server is started. Super simple stuff!

The JettyMain app has a few optional command line arguments for overriding the defaults. You can see those by running:

java -cp target/dependency/*:target/classes com.howardlewisship.tapx.heroku.JettyMain -help

If you want to try out a simple app that already has this setup then I have one on GitHub that you can copy locally by doing a git clone:

git clone https://github.com/jamesward/hellotapestry.git

Now lets run this on the cloud with Heroku. To follow along you need to install the Heroku toolbelt and signup for a Heroku.com account. Don’t worry, you won’t need to enter a credit card to give this a try because Heroku gives you 750 free dyno hours per application, per month. (Wondering what a “dyno” is? Check out: How Heroku Works)

We need to tell Heroku what process on the system to run in order to start up the web application. To do this we need a file named Procfile (with a capital ‘P’) in the project’s root directory. The contents of that file should be:

web:   java -cp target/dependency/*:target/classes com.howardlewisship.tapx.heroku.JettyMain

In this case we will upload the source up to Heroku where it will run the Maven build. This is the standard Heroku deployment mechanism because it makes the deployment process super fast and makes sure that there are no discrepancies between the different environments. The dependencies are downloaded on the cloud (i.e. very quickly) instead of doing the typical lengthy package and upload process. But you can also upload binary assets if you prefer. Heroku uses git for file upload so if you don’t already have the project files in a git repo then you need to create the repo, add the files, and commit them:

git init
git add src pom.xml Procfile
git commit -m init

Now we can provision an application on Heroku by logging in from the Heroku CLI and creating an application on the “cedar” stack:

heroku login
heroku create -s cedar

The application can now be uploaded using git:

git push heroku master

When the upload has finished Heroku will run the Maven build, deploy the compiled application onto a dyno, and start the web process defined in the Procfile. Test out the application in your browser by running:

heroku open

Great! You now have a Tapestry app running on the cloud! But there is one other cool thing the JettyMain does for us. Java web applications often use in-memory session state which does not work well with the server affinity model that is necessary for scalable cloud deployments. Out-of-the-box Tapestry uses the session state very minimally but it’s possible that your application uses it more heavily. Heroku dynos are intended to be stateless so they can be managed, scaled, and configured without disrupting active users. This means that the session state needs to be in an external store. Luckily Jetty makes it easy to transparently move session state to an external MongoDB system (see my Using MongoDB for a Java Web App’s HttpSession post for more details).

The JettyMain app has this functionality built in as long as you either set the mongo-url application parameter or have set either a MONGOHQ_URL or MONGOLAB_URL environment variable. On Heroku it’s very easy to create a MongoDB system for your application to use. The Heroku add-ons provide numerous Cloud Services to Heroku apps, including two MongoDB providers: MongoLab and MongoHQ. Both have free tiers, so pick one and then add it by running either of these commands:

heroku addons:add mongolab
heroku addons:add mongohq

This will automatically provision the MongoDB system, set the connection information in the expected environment variable, and then restart your dyno(s) so that they pickup the new configuration. The JettyMain will now switch Jetty’s session storage provider to the MongoDB system instead of using in-memory storage. Cool stuff!

Let me know if you have any questions and thanks Howard for putting this together!

Posted in Heroku, Java, Tapestry | 6 Comments

Run Grails on the Cloud with Heroku

By James Ward | Published: February 7, 2012

Support for Grails on Heroku was recently announced and I’d like to walk you through the steps to create a simple Grails app and then deploy it on the cloud with Heroku. Before you get started install Grails 2.0.0, install the Heroku toolbelt, install git, and signup for a Heroku.com account. Don’t worry, you won’t need to enter a credit card to give this a try because Heroku gives you 750 free dyno hours per application, per month. (Wondering what a “dyno” is? Check out: How Heroku Works) Let’s get started.

Step 1) Create the app:

grails create-app grailbars

You’ll need to do the rest of this from inside the newly created “grailbars” directory:

cd grailbars

Step 2) Create a new domain object:

grails create-domain-class com.jamesward.grailbars.Bar

Step 3) Edit the grails-app/domain/com/jamesward/grailbars/Bar.groovy file so it looks like:

package com.jamesward.grailbars
 
class Bar {
    String name
}

Step 4) Generate the controllers and views for the Bar model:

grails generate-all com.jamesward.grailbars.Bar

Step 5) Run the app locally to test it out:

grails run-app

Now open it in your browser: localhost:8080/grailbars

Step 6) Heroku provides a free Postgres database that we want our application to use. The easiest way to do that is using the Heroku Grails Plugin. Edit the grails-app/conf/BuildConfig.groovy file and add the heroku and cloud-support plugins to the “plugins” section:

   compile ':heroku:1.0'
   compile ':cloud-support:1.0.8'

Also add the Postgres JDBC driver as a dependency by adding the following to the “dependencies” section:

    runtime 'postgresql:postgresql:9.1-901-1.jdbc4'

Step 7) Setup a git repository for the project which will be used for transferring the files to Heroku:

grails integrate-with --git
git init
git add application.properties grails-app test web-app
git commit -m init

Step 8) Login with the Heroku CLI:

heroku login

Step 9) Ceate a new application using the “cedar” stack:

heroku create -s cedar

Step 10) Upload your application to Heroku:

git push heroku master

Now open the application running on Heroku in your browser (the URL was in the “heroku create” and “git push” output). Verify that it works. Awesome! You just built a Grails app and deployed it on the Cloud with Heroku! For more details on using Grails on Heroku, visit the Heroku Dev Center and checkout the Heroku Grails Plugin documentation. Let me know if you have any questions. Thanks!

Posted in Grails, Heroku | 3 Comments

Next Gen Web Apps with Scala, BlueEyes, and MongoDB

By James Ward | Published: February 6, 2012

Web application architecture is in the midst of a big paradigm shift. Since the inception of the web we’ve been treating the browser like a thin client. Apps just dump markup to the browser which is then rendered. Every interaction requires a request back to the server which then returns more logic-less markup to the browser. In this model our web applications are server applications. There are certainly advantages to this model – especially when the markup consumers don’t have the capabilities to do anything more (or have inconsistent capabilities).

Web browser modernization has paved the way to move from the old “browser as a thin client” model to more of a Client/Server model where the client-side of the application actually runs in the browser. There are a lot of names for this new model, Ajax being a step along the way, and perhaps HTML5 being the full realization of Client/Server web apps.

There are hundreds of new libraries, tools, programming languages, and services that support the creation of these next generation web (and mobile) apps. One thing that is certainly lacking is one cohesive, end-to-end solution. I have no doubt that we will be seeing those crop up soon, but in the mean time lets pick a few libraries and build a couple simple apps to get a better understanding of what this new model looks like.

I’ve decided to try this with a stack consisting of Scala for my back-end code, BlueEyes for handling data access and serialization with transport over HTTP, MongoDB for data storage, and JavaScript with jQuery for the client-side. I’m going to keep this very simple and not pull in anything else. In future articles I’ll expand on this foundation.

So lets dive into some code. All of the code is on GitHub. If you want to get a local copy just do:

git clone git://github.com/jamesward/helloblueeyes.git

This project uses the Scala Build Tool (SBT) for downloading dependencies, compiling, and packaging. Follow the SBT setup instructions if you want to be able to compile the code on your machine. If you want to use IntelliJ or Eclipse then run one of the following commands:

sbt gen-idea
sbt eclipse

Lets start with some BlueEyes basics. BlueEyes is a lightweight web framework built on Netty (a really high performance, NIO-based HTTP library). BlueEyes makes it easy to define a tree of HTTP request handling patterns. I chose BlueEyes because it’s really lightweight and utilizes some nice features of the Scala language to make the code very concise. It’s kinda like a DSL for HTTP request handling.

To get started with BlueEyes we first need to create an AppServer that provides a way to start the server and a place to plug services into. Here is the code for the AppServer:

package net.interdoodle.example
 
object AppServer extends EnvBlueEyesServer with HelloHtmlServices with HelloJsonServices with HelloStartupShutdownServices with HelloMongoServices

My AppServer is an object which means it’s a singleton (that makes sense because I can’t have more than one of these in a single instance). The AppServer extends EnvBlueEyesServer which is a wrapper around the base BlueEyesServer that provides a way to get the HTTP port via an environment variable (this is necessary for running on Heroku – which we will get to later). The AppServer composes in a bunch of Services that actually setup HTTP request pattern trees.

Starting with the simplest one, HelloHtmlServices we have:

trait HelloHtmlServices extends BlueEyesServiceBuilder with BijectionsChunkString {
  val helloHtml = service("helloHtml", "0.1") { context =>
      request {
        path("/") {
          produce(text/html) {
            get { request =>
              val content = <html>
                <body>Hello, world!</body>
              </html>
              val response = HttpResponse(content = Some(content.buildString(true)))
              Future.sync(response)
          }
        }
      }
    }
  }
}

Using the BlueEyesServiceBuilder the HelloHtmlServices trait creates a service that consists of a big pattern match that goes something like this: For a request to path “/”, produce an HTML response when there is a HTTP GET request. Notice that the response is actually wrapped in a Future. This is an important part of the next generation web app architecture. Because the underlying HTTP server is NIO-based (non-blocking), the actual HTTP handling threads can be very efficiently managed so that a thread is only in use when actual IO is happening. BlueEyes supports this by using Future wrapped responses, allowing the HTTP thread to be unblocked by back-end processing.

If you want to try this out locally run the following to compile the app and create a Unix script that makes it easy to start the AppServer:

sbt stage

Now start the AppServer process:

target/start net.interdoodle.example.AppServer

Verify that HelloHtmlServices is working by opening the following URL in your browser:
localhost:8080/

Now lets walk through a few steps to deploy this application on the cloud with Heroku.
Step 1) Sign up for a Heroku account
Step 2) Install the Heroku Toolbelt
Step 3) Login to Heroku from the command line:

heroku login

Step 4) Create a new application on Heroku using the Cedar stack:

heroku create -s cedar

Step 5) Deploy the app on Heroku:

git push heroku master

Step 6) Verify that the app works in your browser:

heroku open

Great! We have an app built with Scala and BlueEyes running on the cloud. Now for the next piece of the architecture. The UI of the application will be written in JavaScript and will run on the client-side. But we need to have a way to transfer data between the client and the server. JSON has become the regular way to do this because it is parsed easily and quickly on the client. So a BlueEyes service will generate some JSON data that can then be consumed by a JavaScript application running on the client. But how do we get that JavaScript application running on the client? This is the next piece of the architecture.

Ideally the JSON services are served separately from the client-side of the application (where the client-side includes all HTML, JavaScript, CSS, images, and other static assets). It is also ideal to serve the client-side from a Content Delivery Network (CDN) so that it’s edge cached and loads super fast. Dynamic assets (the JSON services) can’t be edge cached so there is a logical (and functional) separation between the client-side and the server-side. But there is a problem with this approach.

The CDN and the JSON services hosts each have different DNS names and browsers don’t allow cross-origin requests (actually they don’t allow access to the responses). There are a few different ways to deal with this (JSONP, br hackery, etc) but the approach I’m taking is simple. The JSON services server will serve an entry point / thin shim web page. That shim then loads the rest of the client-side from the CDN and since the origin of the web page is the same as the JSON services, there is no need to make a cross-origin request. (Side note: There is a new way to do cross-origin requests cleanly and natively in the browser, but it’s not ubiquitously supported yet.)

Here is HelloJsonServices that illustrates these patterns:

trait HelloJsonServices extends BlueEyesServiceBuilder with BijectionsChunkJson 



gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.