Pages

Showing posts with label grails. Show all posts
Showing posts with label grails. Show all posts

Sunday, April 5, 2015

Grails 3 Released. Setting up -javaagent

Grails 3 was released just recently and with all the new stuff it looks really-really-really awesome release! (Really hope that Grails will find the new home now). The two key changes for me are 1) moving to Gradle instead of Gant, and 2) building on top of Spring Boot. NOw it looks like it's basically the Gradle project with custom conventions that are derived from Grails 2.x.

For the first time, it feels like Grails is not a toy framework any more :)

What's not that cool (my own very subjective opinion), is the introduction of application.yml. It's almost impossible to modify it without reading the documentation. Even XML version of it (yes!) would have been more practical.

There are many other nice things added - go look for yourself.

Setting up a -javaagent argument for Grails 3

My personal interest with any new framework or server is usually related to the projects I'm working with. Thus, the first thing I wanted to check is how could I set up a -javaagent for Grails 3 application. Turns out, it's not as simple as you would expect.

Thanks to @bsideup, here's the snippet that you'd have to add to build.gradle file to setup a -javaagent argument, given that the agent JAR is located somewhere in file system:

In the example above, xrebel.jar is the agent package that is located somewhere in my file system. One can use the absolute path just fine in there.

Here's the another snippet, with DSL-style:

With this, I can confirm, that XRebel works with Grails 3 :)

Wednesday, August 11, 2010

Having fun with Grails and JRebel

Gails is a fun framework to work with. Recently, I had to figure out how "dynamic" the framework is.

BTW, IntelliJ IDEA Grails support just rocks!

One thing that is definitely useful - to tell Grails not to re-deploy the application after a new change has been introduced. You can do that by adding -Ddisable.auto.recompile=true to VM parameters of your application start script.


By default, controllers and service classes are initialized dynamically by Grails, but with the option above enabled it lets you to skip the re-deploy phase. Re-deploy of the application is required once you change Java classes, which may be included in your Grails application - this will be solved using JRebel as you will see below. Let's see a small example for that.

1) Create a new controller, called ActionController (grails create-controller action), which will delegate its calls to a service, HelloService (grails create-service hello), which will just return a string:



ActionController.groovy


class ActionController {
   def helloService

  def helloAction = {
    render(helloService.serviceMethod(params.name))
  }
}

HelloService.groovy

class HelloService {
  def String serviceMethod(String name) {
    return "hello ${name}!"
  }
}

HelloService is injected to the ActionController by convention. Run the Grails app with grails -Ddisable.auto.recompile=true run-app or from IDE as shown above. ActionController.helloAction is the entry point for our application: 


It tells now "hello Anton!"

Let's add another service to the application. Say, it will be GoodbyeService (grails create-service goodbye):

GoodbyeService.groovy

class GoodbyeService {
  def String serviceMethod(String name) {
    return "bye ${name}!"
  }
}

... and change the ActionController accordingly:

ActionController.groovy

class ActionController {
  def helloService
  def goodbyeService

  def helloAction = {
    render(helloService.serviceMethod(params.name))
  }

  def goodbyeAction = {
    render(goodbyeService.serviceMethod(params.name))
  }
}

So without any restart/redeploy phase, http://localhost:8080/jr-grails/action/goodbyeAction?name=Anton tells me "bye Anton!"

Perfect! I'm productive! :)

Now try another example, including some Java sources from within the application. For instance, we have a DummyController which delegates the calls to Util class instead of a Grails service.


DummyController.groovy


class DummyController {
  def index = {
    render(jr.util.Util.value())
  }
}

Util.java


public class Util {
  public static String value(){
    return "hello";
  }
}

http://localhost:8080/jr-grails/dummy now gives "hello" in response.

The problem is that if you make some changes in the Util class and recompile it, the change will not be visible in the application. To see the changes, you would need to redeploy the application which may require some time once you have a more sophisticated application.

JRebel to the rescue!

JRebel will help you with the issue above. Once you download and install the software, it is possible to start the application from your favorite IDE (via dedicated plug-in) or by adding special parameters to the application start script: -javaagent:"jrebel.jar"

Now if you run the example (see above), and after it is started, try making some changes to the Util class (for instance, change "hello" to "goodbye"). Hit F5 and the corresponding change will be visible now. The console will also display a message - JRebel: Reloading class 'jr.util.Util' - meaning that JRebel has noticed that the class has been altered and you want to use it in your application.

Unfortunately this trick doesn't work for all cases in Grails. For instance, for CRUD functionality in Grails application, if a change is made on a domain class, JRebel will reload the classes, but the change is not propagated further to the view because of some magic that Grails does behind the scenes.  The good news is that JRebel support for Grails is still in progress. Stay tuned! :)

Disqus for Code Impossible