Converted Files

20161019-grails-goodness-skip-bootstrap-code

Skip Bootstrap Code

Grails normally will run any *Bootstrap classes at startup. A Bootstrap class has a init and destroy closure. The init closure is invoked during startup and destroy when the application stops. The class name must end with Bootstrap and be placed in the grails-app/init folder. Since Grails 3.2 we can skip the execution of Bootstrap classes by setting the Java system property grails.bootstrap.skip with the value true.

In the following example Bootstrap class we simply add a println to see the effect of using the system property grails.bootstrap.skip:

// File: grails-app/init/mrhaki/Bootstrap.groovy
package mrhaki

class Bootstrap {
    def init = { servletContext ->
        println "Run Bootstrap"
    }
    
    def destroy = {
    }
}

First we build the application and than start it from the generated WAR file:

$ gradle build
...
:build

BUILD SUCCESSFUL

Total time: 22.235 secs
$ java -jar build/libs/sample-app-0.1.war
Run Bootstrap
Grails application running at http://localhost:8080 in environment: production

Next we use the Java system property grails.bootstrap.skip:

$ java -Dgrails.bootstrap.skip=true -jar build/libs/sample-app-0.1.war
Grails application running at http://localhost:8080 in environment: production

Notice the println statement from Bootstrap.groovy is not invoked anymore.

Written with Grails 3.2.1

Original blog post written on October 19, 2016.

20161118-grails-goodness-notebook-is-updated

Grails Goodness Notebook Is Updated

Grails Goodness Notebook has been updated with the latest blog posts. If you have purchased the book before you can download the latest version of the book for free.

  • Saving Server Port In A File
  • Creating A Runnable Distribution
  • Change Version For Dependency Defined By BOM
  • Use Random Server Port In Integration Tests
  • Running Tests Continuously
  • Add Git Commit Information To Info Endpoint
  • Adding Custom Info To Info Endpoint
  • Add Banner To Grails 3.1 Application
  • Creating A Fully Executable Jar
  • Pass JSON Configuration Via Command Line

Original blog post written on November 18, 2016.

20161123-gails-goodness-enabling-grails-view-in

Enabling Grails View In IntelliJ IDEA For Grails 3

IntelliJ IDEA 2016.3 re-introduced the Grails view for Grails 3 applications. Grails 2 applications already were supported with a Grails view in IDEA. Using this view we get an overview of all the Grails artifacts like controller, services, views and more. We can easily navigate to the the class files we need. Now this view is also available for Grails 3 applications.

To enable the view we must click on the view selector in the project view:

[](https://3.bp.blogspot.com/-t5FNLZg3Cic/WDVLkWg13xI/AAAAAAAALrw/HuGJ7s4sj8UQ-DgW950luKESZnqDR16dQCPcB/s1600/idea-grails3-1.png)

We select the Grails option and we get an nice overview of our Grails project in the Grails view:

[](https://3.bp.blogspot.com/-yMZxTTfkTqo/WDVOhFayh2I/AAAAAAAALr8/8d88K3fXoOoKOj1cCfHWYcpLzmnsS3cqQCPcB/s1600/idea-grails3-2.png)

Also the New action is context sensitive in the Grails view. If we right click on the Services node we can see the option to create a new service class:

[](https://3.bp.blogspot.com/-rsrh7hJbK_Q/WDVPsveDYYI/AAAAAAAALsE/TUgYIQ0JTIgU5DfmM2tD6aSh15I8SothACLcB/s1600/idea-grails3-4.png)

If we right click on the root node we get the option to create Grails artifacts:

[](https://1.bp.blogspot.com/-d4pwd496vQk/WDVPTlHUr1I/AAAAAAAALsA/5R2q9CbSBusM-HrM9719-ww1xbmueA-wwCPcB/s1600/idea-grails3-3.png)

Written with IntelliJ IDEA 2016.3 and Grails 3.2.2

Original blog post written on November 23, 2016.

20161209-grails-goodness-writing-log-messages

Writing Log Messages With Grails 3.2 (Slf4J)

Grails 3.2 changed the logging implementation for the log field that is automatically injected in the Grails artefacts, like controllers and services. Before Grails 3.2 the log field was from Jakarta Apache Commons Log class, but since Grails 3.2 this has become the Logger class from Slf4J API. A big difference is the fact that the methods for logging on the Logger class don’t accepts an Object as the first argument. Before there would be an implicit toString invocation on an object, but that doesn’t work anymore.

In the following example we try to use an object as the first argument of the debug method in a controller class:

package mrhaki.grails3

class SampleController {

    def index() { 
        log.debug new Expando(action: 'index')
        [:]
    }
    
}

When we invoke the index action we get an exception:

...
2016-12-09 14:59:20.283 ERROR --- [nio-8080-exec-1] o.g.web.errors.GrailsExceptionResolver   : Missing\
MethodException occurred when processing request: [GET] /sample/index
No signature of method: ch.qos.logback.classic.Logger.debug() is applicable for argument types: (groov\
y.util.Expando) values: [{action=index}]
Possible solutions: debug(java.lang.String), debug(java.lang.String, [Ljava.lang.Object;), debug(java.\
lang.String, java.lang.Object), debug(java.lang.String, java.lang.Throwable), debug(org.slf4j.Marker, \
java.lang.String), debug(java.lang.String, java.lang.Object, java.lang.Object). Stacktrace follows:

java.lang.reflect.InvocationTargetException: null
        at org.grails.core.DefaultGrailsControllerClass$ReflectionInvoker.invoke(DefaultGrailsControll\
erClass.java:210)
        at org.grails.core.DefaultGrailsControllerClass.invoke(DefaultGrailsControllerClass.java:187)
        at org.grails.web.mapping.mvc.UrlMappingsInfoHandlerAdapter.handle(UrlMappingsInfoHandlerAdapt\
er.groovy:90)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
        at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(Applica\
tionContextHeaderFilter.java:55)
        at org.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.j\
ava:77)
        at org.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:\
67)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
Caused by: groovy.lang.MissingMethodException: No signature of method: ch.qos.logback.classic.Logger.d\
ebug() is applicable for argument types: (groovy.util.Expando) values: [{action=index}]
Possible solutions: debug(java.lang.String), debug(java.lang.String, [Ljava.lang.Object;), debug(java.\
lang.String, java.lang.Object), debug(java.lang.String, java.lang.Throwable), debug(org.slf4j.Marker, \
java.lang.String), debug(java.lang.String, java.lang.Object, java.lang.Object)
        at mrhaki.grails3.SampleController.index(SampleController.groovy:6)
        ... 14 common frames omitted
...

When we change the log statement to log.debug new Expando(action: 'index').toString() it works.

Another time saver and great feature is the use of placeholders {} in the logging message. This allows for late binding of variables that are used in the logging message. Remember when we used the Apache Commons Logging library we had to enclose a logging statement in a if statement to check if logging was enabled. Because otherwise the logging message with variable references was always evaluated, even though the logging was disabled. With Slf4J Logger we don’t have to wrap logging statements with an if statement if we use the {} placeholders. Slf4J will first check if logging is enabled for the log message and then the logging message is created with the variables. This allows for much cleaner code.

In the following example we use the placeholders to create a logging message that included the variable id:

package mrhaki.grails3

class SampleController {

    def show(final String id) {
        // Before Grails 3.2 we should write:
        // if (log.debugEnabled) {
        //     log.debug "Invoke show with id [$id]"
        // }
        // With Grails 3.2 it is only the debug method and 
        // String evaluation using {}.
        log.debug 'Invoke show with id [{}]', id
        [id: id]
    }
    
}

Written with Grails 3.2.3

Original blog post written on December 09, 2016.

20170221-grails-goodness-using-domain-classes

Using Domain Classes Without Persistence

Normally when we create a domain class in Grails we rely on GORM for all the persistence logic. But we can use the static property mapWith with the value none to instruct Grails the domain class is not persisted. This can be useful for example if we want to use a RestfulController for a resource and use the default data binding support in the RestfulController. The resource must be a domain class to make it work, but we might have a custom persistence implementation that is not GORM. By using the mapWith property we can still have benefits from the RestfulController and implement our own persistence mechanism.

In the following example we have a simple Book resource. We define it as a domain class, but tell Grails the persistence should not be handled by GORM:

// File: grails-app/domain/mrhaki/sample/Book.groovy
package mrhaki.sample

import grails.rest.Resource

@Resource(uri = '/books', superClass= BookRestfulController)
class Book {
    
    static mapWith = 'none'
    
    String title
    String isbn
    
    static constraints = {
        title blank: false
        isbn blank: false
        
        // Allow to set id property directly in constructor.
        id bindable: true
    }
    
}

The application also has a Grails service BookRepositoryService that contains custom persistence logic for the Book class. In the following RestfulController for the Book resource we use BookRepositoryService and override methods of RestfulController to have a fully working Book resource:

// File: grails-app/controllers/mrhaki/sample/BookRestfulController.groovy
package mrhaki.sample

import grails.rest.RestfulController

class BookRestfulController extends RestfulController<Book> {
    
    BookRepositoryService bookRepositoryService
    
    BookRestfulController(final Class<Book> resource) {
        super(resource)
    }

    BookRestfulController(final Class<Book> resource, final boolean readOnly) {
        super(resource, readOnly)
    }

    @Override
    protected Book queryForResource(final Serializable id) {
        bookRepositoryService.get(Long.valueOf(id))
    }
    
    @Override
    protected List<Book> listAllResources(final Map params) {
        bookRepositoryService.all
    }

    @Override
    protected Integer countResources() {
        bookRepositoryService.total
    }

    @Override
    protected Book saveResource(final Book resource) {
        bookRepositoryService.add(resource)
    }

    @Override
    protected Book updateResource(final Book resource) {
        bookRepositoryService.update(resource)
    }

    @Override
    protected void deleteResource(final Book resource) {
        bookRepositoryService.remove(resource.id)
    }
}

Written with Grails 3.2.6.

Original blog post written on February 21, 2017.

20170227-grails-goodness-custom-json-and-markup

Custom JSON and Markup Views For Default REST Resources

In Grails we can use the @Resource annotation to make a domain class a REST resource. The annotation adds a controller as URL endpoint for the domain class. Values for the domain class properties are rendered with a default renderer. We can use JSON and markup views to customize the rendering of the domain class annotated with a @Resource annotation. First we must make sure we include views plugin in our build configuration. Then we must create a directory in the grails-app/views directory with the same name as our domain class name. Inside the directory we can add JSON and markup views with names that correspond with the controller actions. For example a file index.gson or ` index.gml for the index action. We can also create a template view that is automatically used for a resource instance by adding a view with the name of the domain class prefixed with an underscore (_`).

In the next example application we create a custom view for the Book domain class that is annotated with the @Resource annotation:

// File: grails-app/domain/mrhaki/sample/Book.groovy
package mrhaki.sample

import grails.rest.Resource

@Resource(uri = '/books')
class Book {
    
    String title
    String isbn
    
    static constraints = {
        title blank: false
        isbn blank: false
    }    
}

Next we must make sure the Grails views code is available as a dependency. In our build.gradle file we must have the following dependencies in the dependencies {} block:

// File: build.gradle
...
dependencies {
    ....
    // Support for JSON views.
    compile "org.grails.plugins:views-json:1.1.5"
    // Support for markup views.
    compile "org.grails.plugins:views-markup:1.1.5"
    ....
}
...

It is time to create new JSON views for JSON responses. We create the directory grails-app/views/book/ and the file _book.gson. This template file is automatically used by Grails now when a Book instances needs to be rendered:

// File: grails-app/views/book/_book.gson
import grails.util.Environment
import mrhaki.sample.Book

model {
    Book book
}

json {
    id book.id
    version book.version
    title book.title
    isbn book.isbn
    information {
        generatedBy 'Sample application'
        grailsVersion Environment.grailsVersion
        environment Environment.current.name
    }
}

We also create the file index.gson to support showing multiple Book instances:

// File: grails-app/views/book/index.gson
import mrhaki.sample.Book

model {
    List<Book> bookList  
} 

// We can use template namespace
// method with a Collection.
json tmpl.book(bookList)

If we also want to support XML we need to create extra markup views. First we a general template for a Book instance with the name _book.gml:

// File: grails-app/views/book/_book.gml
import grails.util.Environment
import mrhaki.sample.Book

model {
    Book book
}

xmlDeclaration()
book {
    id book.id
    title book.title
    isbn book.isbn
    information {
        generatedBy 'Sample application'
        grailsVersion Environment.grailsVersion
        environment Environment.current.name
    }
}

Next we create the file index.gml to show Book instances. Note we cannot use the template namespace in the markup view opposed to in the JSON view:

// File: grails-app/views/book/_book.gml
import grails.util.Environment
import mrhaki.sample.Book

model {
    List<Book> bookList
}

xmlDeclaration()
books {
    bookList.each { bookInstance ->
        book {
            id bookInstance.id
            title bookInstance.title
            isbn bookInstance.isbn
            information {
                generatedBy 'Sample application'
                grailsVersion Environment.grailsVersion
                environment Environment.current.name
            }
        }
    }
}

We start our Grails application and use cUrl to invoke our REST resource:

$ curl -H Accept:application/xml http://localhost:8080/books/1
<?xml version='1.0' encoding='UTF-8'?>
<books>
    <book>
        <id>1</id><title>Gradle Dependency Management</title><isbn>978-1784392789</isbn><information>
            <generatedBy>Sample application</generatedBy><grailsVersion>3.2.6</grailsVersion><environm\
ent>development</environment>
        </information>
    </book><book>
        <id>2</id><title>Gradle Effective Implementation Guide</title><isbn>978-1784394974</isbn><info\
rmation>
            <generatedBy>Sample application</generatedBy><grailsVersion>3.2.6</grailsVersion><environm\
ent>development</environment>
        </information>
    </book>
</books>

$ curl -H Accept:application/xml http://localhost:8080/books/1
<?xml version='1.0' encoding='UTF-8'?>
<book>
    <id>1</id><title>Gradle Dependency Management</title><isbn>978-1784392789</isbn><information>
        <generatedBy>Sample application</generatedBy><grailsVersion>3.2.6</grailsVersion><environment>\
development</environment>
    </information>
</book>

$ curl -H Accept:application/json http://localhost:8080/books
[
    {
        "id": 1,
        "version": 0,
        "title": "Gradle Dependency Management",
        "isbn": "978-1784392789",
        "information": {
            "generatedBy": "Sample application",
            "grailsVersion": "3.2.6",
            "environment": "development"
        }
    },
    {
        "id": 2,
        "version": 0,
        "title": "Gradle Effective Implementation Guide",
        "isbn": "978-1784394974",
        "information": {
            "generatedBy": "Sample application",
            "grailsVersion": "3.2.6",
            "environment": "development"
        }
    }
]

$ curl -H Accept:application/json http://localhost:8080/books/1
{
    "id": 1,
    "version": 0,
    "title": "Gradle Dependency Management",
    "isbn": "978-1784392789",
    "information": {
        "generatedBy": "Sample application",
        "grailsVersion": "3.2.6",
        "environment": "development"
    }
}
$

Written with Grails 3.2.6.

Original blog post written on February 27, 2017.