Grails application with AngularJS: Setup – Part 1

There are several posts about setting up AngularJS, but a few specific to Grails environment. If you have been a Grails developer and want to explore using AngularJS framework for front-end, here is step by step guide to get started. Grails and AngularJS are both full-fledged mvc frameworks on their own. Using the positives from both can be a killer comination to build fast and modern dynamic web applications.

Notes:

  • Instructions are for Windows OS
  • Directories only for reference
  • All versions as of writing this article. Substitute with newer versions as appropriate.
  • Pre-installed: JDK 1.7.0_51: C:\Programs\Java\jdk_1.7.0_51
  • Pre-installed: Grails 2.3.6: C:\Programs\Grails\grails-2.3.6

This setup does not use the angularjs-resources Grails plugin. It replaces the resources plugin entirely with asset-pipeline plugin and uses npm/bower to manage javascript dependencies directly. AngularJS does work with grails resources plugin too, but I feel it becomes difficult to maintain when adding more angular modules.

Step: Install pre-req software

Install Node.js -> http://nodejs.org/ to C:\Programs\nodejs
Install Git -> http://git-scm.com/downloads

Ensure PATH contains: c:\programs\nodejs; c:\programs\git\cmd

Open new command prompt (new, because your PATH would have been modified)

npm install -g npm
npm install -g bower

Step: Create new Grails app

cmd> cd c:\projects
cmd> grails create-app angrails
#All commands executed from the following directory, unless specified
cmd> cd angrails

Step: Switch from resources plugin to using asset-pipeline plugin

AngularJS will work with resources plugin too, but when you start installing many javascript components, the ApplicationResources can become clumsy. Asset pipeline is the new Grails plugin (based on Rails asset pipeline) that makes it easier to manage static resources, javascript, sass/less etc.

Edit BuildConfig.groovy

delete: resources, zipped-resources, cached-resources, yui-minify-resources lines

add:┬ácompile “:asset-pipeline:1.6.1”

cmd> grails refresh-dependencies

That will create grails-app/assets/* sub-directories

cmd> move web-app\css\* grails-app\assets\stylesheets
cmd> move web-app\js\* grails-app\assets\javascripts
cmd> move web-app\images\* grails-app\assets\images
cmd> move web-app\images\skin grails-app\assets\images
cmd> rmdir web-app\css web-app\js web-app\images

Step: Fix main.gsp to use asset-pipeline

Edit main.gsp

Comment/Delete following lines:

<link rel="shortcut icon" href="${resource(dir: 'images', file: 'favicon.ico')}" type="image/x-icon">
<link rel="apple-touch-icon" href="${resource(dir: 'images', file: 'apple-touch-icon.png')}">
<link rel="apple-touch-icon" sizes="114x114" href="${resource(dir: 'images', file: 'apple-touch-icon-retina.png')}">
<link rel="stylesheet" href="${resource(dir: 'css', file: 'main.css')}" type="text/css">
<link rel="stylesheet" href="${resource(dir: 'css', file: 'mobile.css')}" type="text/css">
<g:javascript library="application"/>
<r:layoutResources/> (2 places)

Add the following lines above <g:layoutHead/>

<asset:javascript src="application.js"/>
<asset:stylesheet href="main.css"/>
<asset:link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>

Any other ${resources} images, replace with <asset:image src=”– filename –“/>

Delete ApplicationResources.groovy

Step: Add jQuery dependency

cmd> cd c:/projects/angrails/grails-app/assets
cmd> bower install jquery
cmd> bower install angular

That will create bower_components directory and the js libraries (inside grails-app/assets/bower_components)

Step: Add Javascript dependencies

Edit grails-app/assets/javascripts/application.js

Replace the content with:

//= require jquery/dist/jquery
//= require angular/angular
//= require_tree views
//= require_self
console.log("angrails manifest load complete.");

Note that when using //=require you do not specify the bower_components directory. Asset-pipeline plugin skips the first directory after grails-app/assets.

cmd> grails run-app
Goto http://localhost:8080/angrails

End of Part 1: We have installed AngularJS and asset-pipeline for a Grails app.

In Part 2, we shall install Karma Test Runner for testing AngularJS javascripts.

Advertisements

Grails plugin dependency issues

Ran into a few problems with Grails plugin dependencies here are some solutions.

Applies to Stack

Grails 2.3.0, cache:1.1.1, asset-pipeline:1.0.4, mongodb:1.3.0, shiro:1.2.0, hibernate:3.6.10.1, database-migration:1.3.5

Problem 1:

Conditions: Using cache:1.1.1

grails compile fails with error:

| Error Compilation error: startup failed:
Compile error during compilation with javac.
C:\Grails\MyProject\target\work\plugins\cache-1.1.1\src\java\grails\plugin\cache\web\filter\PageFragmentCachingFilter.java:46: error: package net.sf.ehcache.constructs.blocking does not exist
import net.sf.ehcache.constructs.blocking.LockTimeoutException;

Solution 1:

Add the following in the BuildConfig dependencies section (if mongodb is used by a plugin, this should go into plugin’s BuildConfig dependencies)

dependencies {
 compile "net.sf.ehcache:ehcache-core:2.4.6"
 }</code>


Verification 1:

Delete target/* from any plugin and project sources
grails compile

Problem 2:

Conditions: You are using shiro:1.2.0 + Servlet API v3.0. Shiro includes servelt-api 2.5 by default and is causing a conflict.

grails compile fails with error:

C:\Grails\MyProject\target\work\plugins\cache-1.1.1\src\java\grails\plugin\cache\web\GenericResponseWrapper.java:154: error: method does not override or implement a method from a supertype
@Override
^
C:\Grails\MyProject\target\work\plugins\cache-1.1.1\src\java\grails\plugin\cache\web\filter\PageFragmentCachingFilter.java:398: error: cannot find symbol
contentType = response.getContentType();

^
Solution 2:

To eliminate this problem, exclude servlet-api from Shiro for shiro-cas:

dependencies {
compile("org.apache.shiro:shiro-cas:1.2.2") {
excludes "servlet-api"
}
}

Verification 2:

Delete target/*
grails compile

Problem 3:

Conditions: You are using shiro:1.2.0 + mongodb:1.0.3 – hibernate:3.6.10.1 – database-migration:1.3.5 (ie hibernate and database-migration are not included)

grails compile fails with error:

| Error Fatal error during compilation org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
C:\Grails\MyProject\target\work\plugins\hibernate-2.2.4\.\HibernateGrailsPlugin.groovy: 18: unable to resolve class org.codehaus.groovy.grails.plugins.orm.hibernate.HibernatePluginSupport
@ line 18, column 1.
import org.codehaus.groovy.grails.plugins.orm.hibernate.HibernatePluginSupport
^

IntelliJ IDEA 13 may also throw a “IDEA hook: Grails not found!” error.

This is due to a dependency of shiro on hibernate-2.2.4 api.

Soution 3:

runtime (":shiro:1.2.0") {
excludes "hibernate"
}

Verification 3:

Delete target/*
grails compile

One way to sort out such errors is to run the grails dependency-report and look for the jar file which causes the problem. Trace back from jar file to the actual included plugin or dependency and add the excludes in either dependencies section or plugins section appropriately.