Webinar: Social Enterprise Java Apps on Heroku

Tomorrow, May 30th, I will be co-hosting a webinar about Social Enterprise Java Apps on Heroku. The webinar will be at both 2:00 p.m. GMT and 10:00 a.m. PDT. Register at: http://www.developerforce.com/events/webinars/2012-05-30/registration.php?d=70130000000sW7g

Here is the description:

In this webinar you will learn how to build Social Enterprise applications using Salesforce.com, Heroku, and Java. Through live coding and demonstrations you will learn how to instantly deploy and scale Java apps on the cloud with Heroku. You will also learn how to integrate those applications with Salesforce.com and Force.com through REST.

Hope to see you there!

Graphs in the Cloud: Spring + Neo4j on Heroku

Last week I hosted a webinar about running Java apps on Heroku that use the Spring Framework and the Neo4j graph database. Here is the recording of that webinar:

In the webinar I began by deploying a copy of the Spring MVC + Hibernate template app from heroku.com/java on Heroku. Then I made a few modifications to the app to switch the persistence from Hibernate / JPA to Neo4j. You can get the full source code on GitHub.

Here is a quick recap of what I did to switch the template app to use Neo4j:

  1. Added the Neo4j Heroku Add-on:
    heroku addons:add neo4j
  2. Added the Spring Data Neo4j dependencies (optionally you can remove the unused JPA dependencies) to the “pom.xml” Maven build descriptor:
  3. Modified the “src/main/java/com/example/service/PersonService.java” interface to use the Neo4j GraphRepository:
    package com.example.service;
    import com.example.model.Person;
    import org.springframework.data.neo4j.repository.GraphRepository;
    public interface PersonService extends GraphRepository<Person> {
  4. Removed the unneeded “src/main/java/com/example/service/PersonServiceImpl.java” DAO.
  5. Modified the “src/main/java/com/example/model/Person.java” POJO to be a @NodeEntity (instead of JPA Entity) and switched the “id” primary key property to be a Long annotated as a @GraphId:
    package com.example.model;
    import org.springframework.data.neo4j.annotation.GraphId;
    import org.springframework.data.neo4j.annotation.NodeEntity;
    public class Person {
        private Long id;
        // the rest is omitted
  6. Modified the “src/main/java/com/example/controller/PersonController.java” Spring MVC controller to use the new “PersonService”, take a Long parameter in the “deletePerson” method, and make the “deletePerson” and “addPerson” methods transactional:
    package com.example.controller;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.transaction.annotation.Transactional;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import com.example.model.Person;
    import com.example.service.PersonService;
    import java.util.Map;
    public class PersonController {
        private PersonService personService;
        public String listPeople(Map<String, Object> map) {
            map.put("person", new Person());
            map.put("peopleList", personService.findAll().iterator());
            return "people";
        @RequestMapping(value = "/add", method = RequestMethod.POST)
        public String addPerson(@ModelAttribute("person") Person person) {
            return "redirect:/people/";
        public String deletePerson(@PathVariable("personId") Long personId) {
            return "redirect:/people/";
  7. Then I modified the “src/main/resources/applicationContext.xml” Spring config file to use a file for local Neo4j storage in the “default” profile and then in the “prod” profile the “NEO4J_REST_URL”, “NEO4J_LOGIN”, and “NEO4J_PASSWORD” environment variables are used to connect to the Neo4j Heroku add-on service:
    <?xml  version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                               http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                               http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
                               http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
                               http://www.springframework.org/schema/data/neo4j http://www.springframework.org/schema/data/neo4j/spring-neo4j-2.0.xsd">
        <context:annotation-config />
        <context:spring-configured />
        <context:component-scan base-package="com.example" />
        <neo4j:repositories base-package="com.example.service"/>
        <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
            <property name="prefix" value="/WEB-INF/jsp/" />
            <property name="suffix" value=".jsp" />
        <tx:annotation-driven />
        <beans profile="default">
            <neo4j:config storeDirectory="target/neo4j-db"/>
        <beans profile="prod">
            <bean class="org.springframework.data.neo4j.rest.SpringRestGraphDatabase" id="graphDatabaseService">
                <constructor-arg index="0" value="#{systemEnvironment['NEO4J_REST_URL']}"/>
                <constructor-arg index="1" value="#{systemEnvironment['NEO4J_LOGIN']}"/>
                <constructor-arg index="2" value="#{systemEnvironment['NEO4J_PASSWORD']}"/>
            <neo4j:config graphDatabaseService="graphDatabaseService"/>
  8. After testing my changes locally (which actually didn’t work in my webinar due to a problem with Eclipse) I committed my changes to the git repo and pushed them to Heroku:
    git push heroku master

If you want to just skip to a working example on the cloud, simply follow the instructions in the project README.

Hopefully that helps you get started with Neo4j and Java applications on the cloud!

BTW: If you watched the webinar, you probably noticed that my Maven and Eclipse were misbehaving. Turns out that M2E didn’t read my Maven config and all I had to do was right-click on the project, select Maven, and then Update Project Configuration. That got everything back in sync. My excuse for not being able to figure that out during the demo… I usually use IntelliJ IDEA. :)

Heroku, Java, Play and Neo4j Presos: Denver JUG, Atlanta JUG, London Flash UG & Webinar

Over the next couple weeks I’ll be doing two Java User Group presentations, a Flash Platform User Group presentation and one Webinar. Hope to see you at one of these events:

Play Framework 2 & HTML5 on Heroku at Philly ETE and Devoxx Paris

Over the next few weeks I’ll be doing a few presentations about Java, Scala, Play Framework 2, HTML5, and Heroku:

Hope to see you there!

Java on Heroku at NH JUG and DevNexus 2012

This week I’ll will be doing a few presentations about running Java and Play apps on Heroku:

Hope to see you there!

Screencast: Java Template Apps on Heroku

Today Heroku launched a new way to get started deploying Java apps on the cloud. There are four different template apps you can start with including a Spring + Hibernate + Tomcat app, a Containerless Jetty app, a Play! app, and a JAX-RS app. Pick a template and with a few clicks a copy of the template will be deployed on Heroku – just for you! Get started at:


Here is a screencast that walks through the steps to deploy a new Java template app on Heroku, then setup SSH authentication (for pulling and pushing code with git), pull the code into Eclipse, make a change, and push the changes back to Heroku. Check it out and let me know what you think.

Java on Heroku Next Week at Cloudstock 2012

Next week in San Francisco at Cloudstock 2012 I will be doing a presentation called “Introduction to Heroku: Building Next Generation Apps”. Here is the session description:

Many emerging technology trends like PaaS, HTML5, mobile apps, API-driven development, and continuous deployment are changing the way we build and deliver software. Heroku is a polyglot cloud application platform at the forefront of these trends. This introductory session will teach you what Heroku is and how you can use it to build next-generation apps that make software delivery more efficient and scalable.

Check out the complete list of sessions. And register now before Cloudstock 2012 is sold out! Hope to see you there.