James Ward's complete blog can be found at: http://www.jamesward.com/

Items:   1 to 5 of 11   Next »

Monday, May 14, 2012

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. :)


Tuesday, May 8, 2012

I’ve created a Play 2 Tutorial and posted it on GitHub! The tutorial covers how to:

Each section has a corresponding branch in git so you can diff against my version to see if you’ve done everything correctly. Right now this is just for Play 2 with Java and Ebean but I’m working on doing this for Play 2 with Scala as well.

You can see a live demo of the final app at:
play2torial.herokuapp.com

It’s a pretty simple app but it should get you started building Play 2 apps and deploying them on the cloud with Heroku. If you want to take the shortcut to the end and get your own copy of the app running on Heroku then just do the following:

  1. Install git and the Heroku Toolbelt.
  2. Signup for an account on Heroku. (Don’t worry, this stuff is free.)
  3. Clone the play2torial git repo:
    git clone git://github.com/jamesward/play2torial.git
  4. Login to Heroku:
    heroku login
  5. Create a new app on Heroku (from within the play2torial directory):
    heroku create --stack cedar
  6. Upload the app to Heroku (from within the play2torial directory):
    git push heroku java-heroku_update:master
  7. Check out your app on the cloud:
    heroku open
  8. If you want to run the app locally, install Play 2 and then run:
    git checkout java-heroku_update
    play ~run

I hope this helps you learn Play 2! Let me know if you have any questions or comments. Thanks!


Monday, May 7, 2012

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:


Monday, April 30, 2012

This week I’ll be doing two presentation about Heroku:

Hope to see you there!


Monday, April 30, 2012

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!


Items:   1 to 5 of 11   Next »