Connecting to the Salesforce REST APIs with Spring Boot and Java

Broadly speaking there are two types of integrations with Salesforce, either a system-to-system integration or a user interface integration. One of the primary ways to do these integrations is by using the Salesforce REST API. When using the Salesforce REST API you need to obtain an access token that identifies who is making the requests. OAuth 2 provides an HTTP interface to obtain a Salesforce access token.

When using the Salesforce OAuth 2 API there are three options for obtaining an access token:

  1. Use the Web Server Flow where a Salesforce user in a traditional web app is asked to authorize a third party application which then allows the web server to obtain an access token.
  2. Use the User Agent Flow where a Salesforce user in a mobile or JavaScript web app is asked to authorize a third party application which then allows the client side application (native mobile, JavaScript, etc) to obtain an access token.
  3. Use the Username and Password Flow where stored credentials for a system-to-system integration user are exchanged for an access token.

The OAuth Web Server Flow can seem tricky to implement by hand because there are a number of necessary steps but luckily this flow is pretty standard so many libraries have done the hard work for us. In the case of a Java Spring application the hard work has all been done by the Spring Security OAuth library. And Spring Boot makes it super easy to setup a new application that has everything needed for the OAuth Web Server Flow.

Let’s walk through the different pieces of a simple web application which has the OAuth stuff, fetches Accounts from the Salesforce REST API, and renders them in a web page via JavaScript. (Note: You can skip straight to the completed project if you just want to deploy the app on Heroku or get it all running locally.)

First we need a build system to manage dependencies, run the app, and assemble the app for deployment. I’ve chosen Gradle so here is my build.gradle:

buildscript {
    repositories {
        mavenLocal()
        mavenCentral()
        maven {
            url 'https://plugins.gradle.org/m2/'
        }
    }
    dependencies {
        classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.4.2.RELEASE'
    }
}
 
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
 
repositories {
    mavenLocal()
    mavenCentral()
}
 
dependencies {
    compile 'org.springframework.boot:spring-boot-starter-web:1.4.2.RELEASE'
    compile 'org.springframework.boot:spring-boot-devtools:1.4.2.RELEASE'
    compile 'org.springframework.boot:spring-boot-starter-security:1.4.2.RELEASE'
    compile 'org.springframework.security.oauth:spring-security-oauth2:2.0.12.RELEASE'
    compile 'org.webjars:salesforce-lightning-design-system:2.1.4'
    compile 'org.webjars:jquery:3.1.1'
}

There you can see dependencies on the Spring Boot stuff, the Spring Security OAuth library and a few WebJars for the UI.

Now we need to set some properties for the Spring Security stuff. There are a few different ways to set these and you should make sure that your OAuth client id and secret don’t end up in SCM. At a minimum you will need these settings:

security.oauth2.client.client-authentication-scheme = form
security.oauth2.client.authentication-scheme = header
security.oauth2.client.grant-type = authorization_code
security.oauth2.client.access-token-uri = https://login.salesforce.com/services/oauth2/token
security.oauth2.client.user-authorization-uri = https://login.salesforce.com/services/oauth2/authorize
security.oauth2.resource.user-info-uri = https://login.salesforce.com/services/oauth2/userinfo
security.oauth2.client.client-id = YOUR_SALESFORCE_CONNECTED_APP_CLIENT_ID
security.oauth2.client.client-secret = YOUR_SALESFORCE_CONNECTED_APP_CLIENT_SECRET

I put all of the settings except the client id and secret in a src/main/resources/application.properties file. For the other settings you can use environment variables or config settings on Heroku. Spring Boot automatically will look for the client id and secret in environment variables named SECURITY_OAUTH2_CLIENT_CLIENT_ID and SECURITY_OAUTH2_CLIENT_CLIENT_SECRET.

Next we need a Spring component that will handle the REST communication with Salesforce including the query for Accounts and deserialization from JSON. Here is my src/main/java/com/example/Force.java code:

package com.example;
 
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.oauth2.client.OAuth2ClientContext;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.stereotype.Component;
 
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
@Component
public class Force {
 
    private static final String REST_VERSION = "35.0";
 
    @Bean
    private OAuth2RestTemplate oAuth2RestTemplate(OAuth2ProtectedResourceDetails resource, OAuth2ClientContext context) {
        return new OAuth2RestTemplate(resource, context);
    }
 
    @Autowired
    private OAuth2RestTemplate restTemplate;
 
    @SuppressWarnings("unchecked")
    private static String restUrl(OAuth2Authentication principal) {
        HashMap<String, Object> details = (HashMap<String, Object>) principal.getUserAuthentication().getDetails();
        HashMap<String, String> urls = (HashMap<String, String>) details.get("urls");
        return urls.get("rest").replace("{version}", REST_VERSION);
    }
 
    public List<Account> accounts(OAuth2Authentication principal) {
        String url = restUrl(principal) + "query/?q={q}";
 
        Map<String, String> params = new HashMap<>();
        params.put("q", "SELECT Id, Name, Type, Industry, Rating FROM Account");
 
        return restTemplate.getForObject(url, QueryResultAccount.class, params).records;
    }
 
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class Account {
        public String Id;
        public String Name;
        public String Industry;
        public String Rating;
    }
 
    @JsonIgnoreProperties(ignoreUnknown = true)
    private static class QueryResult<T> {
        public List<T> records;
    }
 
    private static class QueryResultAccount extends QueryResult<Account> {}
 
}

There is some plumbing to setup the Spring REST Template which makes it easy to make the REST requests. The accounts method takes an OAuth2Authentication so that the URL can be determined. Finally there are some classes to represent the results from the query and the Account, which are created from the JSON data returned from the REST API.

For Spring Boot we need an application which will be run on the web server (or local machine for development). In this example the application will also contain our REST API implementation which will be used by a JavaScript UI. Here is the code for the src/main/java/com/example/SpringSalesforceApplication.java file:

package com.example;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
import java.util.List;
 
@SpringBootApplication
@RestController
@EnableOAuth2Sso
public class SpringSalesforceApplication {
 
    @Autowired
    private Force force;
 
    @RequestMapping("/accounts")
    public List<Force.Account> accounts(OAuth2Authentication principal) {
        return force.accounts(principal);
    }
 
    public static void main(String[] args) {
        SpringApplication.run(SpringSalesforceApplication.class, args);
    }
 
}

This does all the magic to create a Spring Boot web application which uses the Spring Security OAuth stuff, the Force component, and a REST controller. There is a single REST controller method in this application that handles requests to /accounts, does the query to Salesforce using the Force component, deserializes the results, then reserializes them as JSON. In this little example we aren’t seeing why we’d want to proxy the Salesforce REST API in this way since we are not doing any aggregation or transformation of data. But that would be straightforward to do if needed.

The final piece of this application is a web UI that uses the Spring Boot app’s /accounts REST method to get and then display the accounts. In this case I’m using jQuery to do that. Here is the code for the src/main/resources/static/index.html file:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta http-equiv="x-ua-compatible" content="ie=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
 
    <title>Hello Spring Salesforce</title>
 
    <link rel="stylesheet" type="text/css" href="webjars/salesforce-lightning-design-system/2.1.4/assets/styles/salesforce-lightning-design-system.min.css"/>
 
    <script type="text/javascript" src="webjars/jquery/3.1.1/jquery.min.js"></script>
    <script>
        $(function() {
          $.get("/accounts", function(data) {
            $("tbody").empty();
            $.each(data, function(i, account) {
              var tr = $("<tr>");
              tr.append($("<td>").text(account.Id));
              tr.append($("<td>").text(account.Name));
              tr.append($("<td>").text(account.Industry));
              tr.append($("<td>").text(account.Rating));
              $("tbody").append(tr);
            });
          });
        });
    </script>
</head>
<body>
    <header class="slds-global-header_container">
        <div class="slds-global-header slds-grid slds-grid--align-spread">
            <div class="slds-global-header__item">
                <div class="slds-text-heading--large">Hello Spring Salesforce</div>
            </div>
        </div>
    </header>
 
    <div class="slds-container--center slds-container--medium" style="margin-top: 60px;">
        <div class="slds-text-heading--medium">Salesforce Accounts</div>
 
        <table class="slds-table slds-table--bordered slds-table--cell-buffer">
            <thead>
                <tr class="slds-text-title--caps">
                    <th scope="col">
                        <div class="slds-truncate" title="Id">Id</div>
                    </th>
                    <th scope="col">
                        <div class="slds-truncate" title="Id">Name</div>
                    </th>
                    <th scope="col">
                        <div class="slds-truncate" title="Id">Industry</div>
                    </th>
                    <th scope="col">
                        <div class="slds-truncate" title="Id">Rating</div>
                    </th>
                </tr>
            </thead>
            <tbody>
            </tbody>
        </table>
    </div>
</body>
</html>

With this application running locally when I visit http://localhost:8080 in my browser, Spring Security notices that I don’t yet have an access token so it walks through the OAuth Web Server Flow with Salesforce and once complete renders the index.html page. The JavaScript on that page makes the REST request to /accounts which does the query to the Salesforce REST APIs and then returns the JSON back to the browser. Finally, the data is rendered in the table on the web page. Here is what it looks like:

In total there were only five pretty small files needed to have an end-to-end Salesforce REST API integration with a web application. Hopefully that gets you started! For full instructions on Heroku deployment of this application or to get the app running locally, check out the complete project on GitHub.

Let me know how it goes!

The 6 Minute Cloud/Local Dev Roundtrip with Spring Boot

Great developer experiences allow you go from nothing to something amazing in under ten minutes. So I’m always trying to see how much I can minimize getting started experiences. My latest attempt is to deploy a Spring Boot app on Heroku, download the source to a developer’s machine, setup & run the app locally, make & test changes, and then redeploy those changes — all in under ten minutes (assuming a fast internet connection). Here is that experience in about six minutes:

To try it yourself, start at the hello-springboot GitHub repo. Let me know how it goes!

NoSQL Inside SQL with Java, Spring, Hibernate, and PostgreSQL

There are many benefits to schema-less NoSQL datastores, but there are always trade-offs. The primary gift the NoSQL movement has given us is the variety of options we now have for data persistence. With NoSQL we no longer must try to shoehorn everything into a relational model. Now the challenge is in deciding which persistence model fits best with each domain in a system and then combining those models in a cohesive way. The general term to describe this is Polyglot Persistence and there are many ways to accomplish it. Lets walk through how you can combine a regular SQL model with a key-value NoSQL model using Java, Spring, Hibernate, and PostgreSQL.

This article covers the pieces of a simple web application which uses regular SQL and PostgreSQL’s hstore for key value pairs. This method is a mix of NoSQL inside SQL. One benefit of this approach is that the same datastore can be used for both the SQL and the NoSQL data.

In this example the server technologies will be Java, Spring, and Hibernate. (The same thing can also be done with Rails, Django, and many other technologies.) To add Hibernate support for hstore I found a fantastic blog about “Storing sets of key/value pairs in a single db column with Hibernate using PostgreSQL hstore type“. I won’t go through that code here but you can find everything in the GitHub repo for my demo project.

This demo app uses Maven to define the dependencies. Embedded Jetty is started via a plain ‘ole Java application that sets up Spring MVC. Spring is configured via Java Config for the main stuff, the web stuff, and the database stuff.

The client technologies will be jQuery and Bootstrap and there is a strict seperation between the client and server via RESTful JSON services. The whole client-side is in a plain ‘ole HTML file. Via jQuery / Ajax the client communicates to JSON services exposed via a Spring MVC Controller.

Ok. Now onto the NoSQL inside SQL stuff. This application stores “Contacts” that have a name but also can have many “Contact Methods” (e.g. phone numbers and email addresses). The “Contact Methods” are a good use of a schema-less, key-value pair column because it avoids the cumbersome alternatives: putting that information into a separate table or trying to create a model object that has all of the possible “Contact Methods”. So lets take a look at the simple Contact Entity:

package com.jamesward.model;
 
import net.backtothefront.HstoreUserType;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
 
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.util.HashMap;
import java.util.Map;
 
@Entity
@TypeDef(name = "hstore", typeClass = HstoreUserType.class)
public class Contact {
 
    @Id
    @GeneratedValue
    public Integer id;
 
    @Column(nullable = false)
    public String name;
 
    @Type(type = "hstore")
    @Column(columnDefinition = "hstore")
    public Map<String, String> contactMethods = new HashMap<String, String>();
 
}

If you are familiar with Hibernate / JPA then most of this should look pretty familiar to you. The new / interesting stuff is the contactMethods property. It is a Map<String, String> and it uses PostgreSQL’s hstore datatype. In order for that to work, the type has to be defined and the columnDefinition set. Thanks again to Jakub Głuszecki for putting together the HstoreHelper and HstoreUserType that make this possible.

Now the rest is simple because it’s just plain Hibernate / JPA. Here is the ContactService that does the basic query and updates:

package com.jamesward.service;
 
import com.jamesward.model.Contact;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.CriteriaQuery;
 
import java.util.List;
 
@Service
@Transactional
public class ContactServiceImpl implements ContactService {
 
    @PersistenceContext
    EntityManager em;
 
    @Override
    public void addContact(Contact contact) {
        em.persist(contact);
    }
 
    @Override
    public List<Contact> getAllContacts() {
        CriteriaQuery<Contact> c = em.getCriteriaBuilder().createQuery(Contact.class);
        c.from(Contact.class);
        return em.createQuery(c).getResultList();
    }
 
    public Contact getContact(Integer id) {
        return em.find(Contact.class, id);
    }
 
    @Override
    public void addContactMethod(Integer contactId, String name, String value) {
        Contact contact = getContact(contactId);
        contact.contactMethods.put(name, value);
    }
 
}

Now that you understand how it all works, check out a live demo on Heroku.

If you want to run this app locally or on Heroku, then first you need to grab the source code and continue working inside the newly created spring_hibernate_hstore_demo directory:

$ git clone https://github.com/jamesward/spring_hibernate_hstore_demo.git
$ cd spring_hibernate_hstore_demo

To run locally:

  1. Setup your PostgreSQL database to support hstore by opening a psql connection to it:
    $ psql -U username -W -h localhost database
  2. Then enable hstore:
    => create extension hstore;
    => \q
  3. Build the app (depends on having Maven installed):
    $ mvn package
  4. Set the DATABASE_URL environment variable to point to your PostgreSQL server:
    $ export DATABASE_URL=postgres://username:password@localhost/databasename
  5. Start the app:
    $ java -cp target/classes:target/dependency/* com.jamesward.Webapp
  6. Try it out

Cool! Now you can run it on the cloud with Heroku. Here is what you need to do:

  1. Install the Heroku Toolbelt
  2. Login to Heroku:
    $ heroku login
  3. Create a new app:
    $ heroku create
  4. Add Heroku Postgres:
    $ heroku addons:add heroku-postgresql:dev
  5. Tell Heroku to set the DATABASE_URL environment variable based on the database that was just added (replace YOUR_HEROKU_POSTGRESQL_COLOR_URL with your own):
    $ heroku pg:promote YOUR_HEROKU_POSTGRESQL_COLOR_URL
  6. Open a psql connection to the database:
    $ heroku pg:psql
  7. Enable hstore support in your database:
    => create extension hstore;
    => \q
  8. Deploy the app:
    $ git push heroku master
  9. View the app on the cloud:
    $ heroku open

Fantastic! Let me know if you have any questions.

Containerless Spring MVC

Many of the new JVM-based web frameworks are ditching containers and WAR files and instead using a WAR-less / Containerless approach. But that doesn’t mean you have to ditch your favorite Java web framework. A while back I posted about going containerless with Tapestry. Now lets do the same with Spring MVC. You can grab the full source code from GitHub.

First we need a build that defines the dependencies. Here is the build.gradle file for my Gradle build:

apply plugin:'java'
apply plugin:'application'
 
version = '0.0.1-SNAPSHOT'
 
mainClassName = "com.jamesward.Webapp"
applicationName = "webapp"
 
repositories {
    mavenCentral()
}
 
dependencies {
    compile 'org.springframework:spring-webmvc:3.1.2.RELEASE'
    compile 'cglib:cglib:2.2.2'
    compile 'org.eclipse.jetty:jetty-webapp:8.1.5.v20120716'
}

There isn’t much to this build except a few dependencies: Spring MVC, CGLib, and Jetty.

The src/main/resources/assets/index.html file just contains simple HTML:

<!doctype html>
<html>
<body>
hello, world
</body>
</html>

The src/main/java/com/jamesward/WebConfig.java file uses Spring annotations to configure Spring MVC:

package com.jamesward;
 
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;
 
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
 
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations("classpath:/assets/");
    }
 
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("redirect:index.html");
    }
 
}

Finally, a simple “static void main” Java class is used to start Jetty. The src/main/java/com/jamesward/Webapp.java file just sets up the HTTP listener and starts it:

package com.jamesward;
 
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
 
 
public class Webapp {
 
    public static void main(String[] args) throws Exception {
 
        final AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
        applicationContext.register(WebConfig.class);
 
        final ServletHolder servletHolder = new ServletHolder(new DispatcherServlet(applicationContext));
        final ServletContextHandler context = new ServletContextHandler();
        context.setContextPath("/");
        context.addServlet(servletHolder, "/*");
 
        String webPort = System.getenv("PORT");
        if (webPort == null || webPort.isEmpty()) {
            webPort = "8080";
        }
 
        final Server server = new Server(Integer.valueOf(webPort));
 
        server.setHandler(context);
 
        server.start();
        server.join();
    }
 
}

That’s it! To build and run this project locally you can simple run:

./gradlew run

(Note: Run “gradlew.bat” on Windows.)

So simple it’s hard to believe it works. :) Let me know if you have any questions.

Integrating Java Spring Apps on Heroku with Force.com REST APIs

Recently I co-presented a webinar about how to integrate Java Spring Apps on Heroku with the Force.com / Salesforce.com REST APIs. Check out the recording:

I’ve also created an in-depth walk through of the code example and step-by-step instructions for setting up and deploying the example Java Spring app on Heroku. Check it out and let me know how it goes.

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:
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-neo4j-rest</artifactId>
        <version>2.0.1.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>4.2.0.Final</version>
    </dependency>
  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;
     
    @NodeEntity
    public class Person {
     
        @GraphId
        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;
     
    @Controller
    public class PersonController {
     
        @Autowired
        private PersonService personService;
     
        @RequestMapping("/")
        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)
        @Transactional
        public String addPerson(@ModelAttribute("person") Person person) {
            personService.save(person);
            return "redirect:/people/";
        }
     
        @RequestMapping("/delete/{personId}")
        @Transactional
        public String deletePerson(@PathVariable("personId") Long personId) {
            personService.delete(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"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
           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"/>
     
        <mvc:annotation-driven/>
     
        <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" />
        </bean>
     
        <tx:annotation-driven />
     
        <beans profile="default">
            <neo4j:config storeDirectory="target/neo4j-db"/>
        </beans>
     
        <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']}"/>
            </bean>
     
            <neo4j:config graphDatabaseService="graphDatabaseService"/>
        </beans>
     
    </beans>
  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. :)

WebJars in Spring MVC

Last week I announced the WebJars project that allows you to specify your web libraries (JavaScript, CSS, etc) as dependencies in your Java web applications. With some help from Jeremy Grelle I was able to get a simple WebJars Spring MVC example working.

First you will need to add the WebJars repository to your build. For Maven, just add the following to your “pom.xml” build file:

    <repositories>
        <repository>
            <id>webjars</id>
            <url>http://webjars.github.com/m2</url>
        </repository>
    </repositories>

Then add a WebJar dependency, like Twitter Bootstrap:

        <dependency>
            <groupId>com.github.twitter</groupId>
            <artifactId>bootstrap</artifactId>
            <version>2.0.2</version>
        </dependency>

Then you need to add a resource handler to Spring MVC that maps requests from a given path to files in the classpath. The WebJars are all inside of a “public” directory. If you are using Java configuration in Spring then you would do the following:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
 
  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/public/**").addResourceLocations("classpath:/public/");
  }
}

Or if you are using XML config then add the following to your Spring config:

<mvc:resources mapping="/public/**" location="classpath:/public/"/>

Then you can reference a WebJar’s assets with something like:

<link rel='stylesheet' media='screen' href='/public/stylesheets/bootstrap.min.css'>

How easy is that? Now you are managing your web libraries as versioned dependencies and you even get transitive dependencies! Check out the full source code for this example on GitHub: https://github.com/jamesward/spring_webjars_demo

Right now there are only a couple of WebJars so if you need something else then simply request a new one via a new issue on GitHub.

Please let me know what you think about this. Thanks!

Video: Spring Roo and Grails Apps on the Cloud

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.

My Upcoming Flex Sessions in Atlanta – DevNexus and Atlanta Flex User Group

In a few weeks I’ll be speaking in Atlanta at DevNexus and at the Atlanta Flex User Group. On March 21, 2011 at DevNexus I have two sessions:

On March 22, 2011 at the Atlanta Flex User Group I will be presenting about Flex 4.5 – The Non-Mobile New Features.

I hope to see you at DevNexus and at the Atlanta Flex User Group!