This quickstart will get you going with a Spring MVC Hibernate application that uses a Postgres database service, deployed to Heroku.
{.note} Sample code for the demo application is available on GitHub. Edits and enhancements are welcome. Just fork the repository, make your changes and send us a pull request.
- Java 1.8.0_45, Maven 3.2.5, Git 2.3.2, and the Heroku client (as described in the basic Java quickstart)
- An installed version of Postgres to test locally
The web app generated by Spring Roo expects you to set database connection properties in the file src/main/resources/META-INF/spring/database.properties
. However, it is not a good idea to hardcode database configuration into a file that is part of your project. Instead, we will edit the Spring configuration to read the configuration from an environment variable.
Heroku automatically provisions a small database when you create a Java application and sets the DATABASE_URL
environment variable to a URL of the format
postgres://user:password@hostname:port/dbname
You can also provision a larger database service yourself using the heroku addons
command. Either way, the database connection information will be stored in the DATABASE_URL
variable.
Create a new URI spring bean initialized with this environment variable by adding this to src/main/resources/META-INF/spring/applicationContext.xml
:
:::xml
<bean class="java.net.URI" id="dbUrl">
<constructor-arg value="${DATABASE_URL}"/>
</bean>
Edit the dataSource
section in src/main/resources/META-INF/spring/applicationContext.xml
and replace the property place holders with the following:
:::xml
<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource">
<property name="driverClassName" value="${database.driverClassName}"/>
<property name="url" value="#{ 'jdbc:postgresql://' + @dbUrl.getHost() + @dbUrl.getPath() }"/>
<property name="username" value="#{ @dbUrl.getUserInfo().split(':')[0] }"/>
<property name="password" value="#{ @dbUrl.getUserInfo().split(':')[1] }"/>
...
To run your app locally set the DATABASE_URL variable in your local environment to point to your local postgres database, for example:
:::term
$ export DATABASE_URL=postgres://scott:tiger@localhost/myapp
Let's run the app locally first to test that it all works. You must have a Postgres database up and running and accessible on the DATABASE_URL
you specified above.
:::term
$ mvn package
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building sbweb 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ sbweb-jetty ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 205 resources
[INFO]
[INFO] --- maven-compiler-plugin:2.5.1:compile (default-compile) @ sbweb-jetty ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ sbweb-jetty ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /Users/joelau/Dropbox/work/alvis-web- interface/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:2.5.1:testCompile (default-testCompile) @ sbweb-jetty ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ sbweb-jetty ---
[INFO] No tests to run.
[INFO]
[INFO] --- maven-war-plugin:2.2:war (default-war) @ sbweb-jetty ---
[INFO] Packaging webapp
[INFO] Assembling webapp [sbweb-jetty] in [/Users/joelau/Dropbox/work/alvis-web- interface/target/sbweb-jetty-1.0-SNAPSHOT]
[INFO] Processing war project
[INFO] Copying webapp resources [/Users/joelau/Dropbox/work/alvis-web-interface/src/main/webapp]
[INFO] Webapp assembled in [695 msecs]
[INFO] Building war: /Users/joelau/Dropbox/work/alvis-web-interface/target/sbweb-jetty-1.0-SNAPSHOT.war
[INFO] WEB-INF/web.xml already added, skipping
[INFO] META-INF/maven/org.spee/sbweb-jetty/pom.xml already added, skipping
[INFO] META-INF/maven/org.spee/sbweb-jetty/pom.properties already added, skipping
[INFO]
[INFO] --- maven-dependency-plugin:2.3:copy (default) @ sbweb-jetty ---
[INFO] Configured Artifact: org.mortbay.jetty:jetty-runner:7.4.5.v20110725:jar
[INFO] org.mortbay.jetty:jetty-runner:7.4.5.v20110725:jar already exists in /Users/joelau/Dropbox/work/alvis-web-interface/target/dependency
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 11.849 s
[INFO] Finished at: 2015-06-26T12:43:54+01:00
[INFO] Final Memory: 16M/220M
[INFO] ------------------------------------------------------------------------
:::term
$ java -jar target/dependency/jetty-runner.jar target/*.war
Go to http://localhost:8080 and test it out by creating a new record.
Commit your changes to Git:
:::term
$ git add .
$ git commit -m "Ready to deploy"
Create the app:
:::term
$ heroku create
Creating high-lightning-129... done, stack is cedar
http://high-lightning-129.herokuapp.com/ | git@heroku.com:high-lightning-129.git
Git remote heroku added
Deploy your code:
:::term
$ git push heroku master
Counting objects: 227, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (117/117), done.
Writing objects: 100% (227/227), 101.06 KiB, done.
Total 227 (delta 99), reused 220 (delta 98)
-----> Heroku receiving push
-----> Java app detected
-----> Installing Maven 3.0.3..... done
-----> Installing settings.xml..... done
-----> executing .maven/bin/mvn -B -Duser.home=/tmp/build_1jems2so86ck4 -s .m2/settings.xml -DskipTests=true clean install
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building petclinic 0.1.0.BUILD-SNAPSHOT
[INFO] ------------------------------------------------------------------------
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 36.612s
[INFO] Finished at: Tue Aug 30 04:03:02 UTC 2011
[INFO] Final Memory: 19M/287M
[INFO] ------------------------------------------------------------------------
-----> Discovering process types
Procfile declares types -> web
-----> Compiled slug size is 62.7MB
-----> Launching... done, v5
http://pure-window-800.herokuapp.com deployed to Heroku
Congratulations! Your web app should now be up and running on Heroku. Open it in your browser with:
:::term
$ heroku open
-
Install Java JDK 8u25 http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
-
Install Git 2.2.1 http://git-scm.com/download/mac
-
Install NetBeans 8.0.2
-
Open Terminal and check, if Git is installed by hitting “git”
-
Create local directory where Git repository will be cloned to.
-
Go to that repository in Terminal.
-
Clone repository through Terminal by hitting: “git clone https://[USERNAME]@bitbucket.org/rfs/alvis-web-interface.git”
-
Open NetBeans and open project “alvis-web-interface” from local directory. Ignore all errors…
-
Right-click “AlvisWebInterface” in Projects tab
-
Click “Resolve Missing Server…”
-
Add server…
-
Create directory for a server and install GlassFish 4.1
-
Finish by accepting default settings for Domain Location.
-
Select GlassFish 4.1 server
—
This part should already be obsolete because of recent implementations in .properties files. For reference only…
—
-
If there is an error, go right-click “AlvisWebInterface” again and go to “Properties”
-
Set the “Web Pages Folder” directory to “alvis-Web-Interface/web” and the “WEB-INF Folder” directory to “alvis-Web-Interface/web/WEB-INF”
-
Go to “Services” tab next to the “Projects” tab, open “Servers” and right-click “GlassFish server 4.1” and select “Start”
-
Hit green play triangle in the top menu bar of NetBeans (Run Project). There may be some errors coming in the “Output” console below…
-
Hit the hammer and broom button (“Clean and Build Project”) next to the green triangle button.
-
If missing the source folder in “Project tab”, add the src folder in AlvisWebInterface Properties (through right-click).
-
Add libraries in Properties. Through “Add JAR/Folder” button add [alvis-web-interface/web/WEB-INF/lib] and the alvis.jar file (wherever it sits) and through “Add Library…” add Spring Framework 4.0.1., Spring Web MVC 4.0.1. and JSTL 1.2.2.
-
Hit hammer and broom button.
-
We were having this error: ant -f "/Users/marekkultys/Git Repos/alvis-web-interface" -Dnb.internal.action.name=rebuild -DforceRedeploy=false "-Dbrowser.context=/Users/marekkultys/Git Repos/alvis-web-interface" clean dist /Users/marekkultys/Git Repos/alvis-web-interface/nbproject/build-impl.xml:237: Must set build.dir BUILD FAILED (total time: 0 seconds)
If the error is “Must set build.dir”, go to build.xml file (ctrl+shift+o) and paste this code in the penultimate line just before the final statement:
-
Refer to this article if there are problems: http://www.adam-bien.com/roller/abien/entry/how_to_fix_the_libs
-
Update actual path of Java settings files. To do that, hit Command+comma in NetBeans and select Java tab, then Ant tab, and in Properties window add the actual path of absolute “org-netbeans-modules-java-j2seproject-copylibstask.jar” file. The command line added to Properties should look something like this: libs.CopyLibs.classpath=/Applications/NetBeans/NetBeans 8.0.2.app/Contents/Resources/NetBeans/java/ant/extra/org-netbeans-modules-java-j2seproject-copylibstask.jar
-
Create “images” directory in “alvis-web-interface/build/web”.
-
Add Alvis project to NetBeans (File > Open Project).
-
Update libraries for Alvis. Right-click to go to Alvis “Properties”, select “Libraries” and click “Add JAR/Folder” and select all. Libraries in red in the “Properties” window can be deleted.
-
Pull content from the repository.
-
Quit NetBeans and run it again.
-
Play the “Alvis Web Interface” project.
-
If there is an error, try adding “/SB” to the end of URL. The address should look something like this: http://localhost:8080/alvis-web-interface/SB