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

Wednesday, November 5, 2014

JSON converter is not working in unit tests in Grails

If calling grails.converters.JSON from unit test throws error like:

java.lang.RuntimeException: org.codehaus.groovy.grails.web.converters.exceptions.ConverterException: Unconvertable Object of class: my.blog.Post
	at org.codehaus.groovy.grails.web.converters.AbstractConverter.toString(AbstractConverter.java:111)
	at org.codehaus.groovy.runtime.InvokerHelper.format(InvokerHelper.java:616)
	at org.codehaus.groovy.runtime.InvokerHelper.format(InvokerHelper.java:559)


It is easy to fix this error by adding ControllerUnitTestMixin to the test definition like:

@TestMixin(ControllerUnitTestMixin)
@TestFor(BlogService)
class BlogServiceTests {
...


Friday, October 31, 2014

Grails requires restart after changes in domain class

Grails officially supports domain class reloading since version 2, but recently I found problems using it together with MongoDB GORM plugin, because it required application restart after every change to domain class.
So if Hibernate is primary GORM and Mongo is used only for some particular cases, disabling it can be a good option to make development easier.

Friday, October 17, 2014

Adding common methods to Grails domain objects

If you don't want to change your domain hierarchy, but need to add common function to multiple domains without copy/paste, one simple option is to create and implement trait. For example:
class Test implements LogTrait {
  String name
}

trait LogTrait {
  def springSecurityService

  def afterInsert() {
    log.info(this as JSON)
  }
}
Nice bonus is that events and injected services work just fine as it would be in original class.


Friday, August 15, 2014

Disable pretty printing of JSON in Grails

It is easy to print any object as JSON in Grails
[key:'value'] as JSON

But it gives human readable, nice, multiline formatted version of JSON with indents. If that is not needed, it is easy to switch it off, like:
new JSON([key:'value']).toString(true)
Much uglier, but does the job.

Wednesday, April 30, 2014

Launching Spring Boot in Groovy with Grab

Since launch of Spring Boot I was wondering why it needs separate CLI, especially for Groovy where there is already Grab. Of course CLI provides some additional features, like reloading and out of the box dependencies, but why no one runs Boot with vanilla Groovy? So I tried it myself, and it looks like problem is that there is conflict with default Groovy libs, because standard installation includes servlet-api-2.4.jar which does not work with current Tomcat or Jetty, and as there is no anything like fork mode in Grails, there is only one way to avoid it - not to load this jar (delete it or use custom load conf).

Otherwise this works fine for me:

@Grab("org.springframework.boot:spring-boot-starter-web:1.0.2.RELEASE")
@Grab("org.springframework.boot:spring-boot-starter-actuator:1.0.2.RELEASE")
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.web.bind.annotation.*

@RestController
@EnableAutoConfiguration
class ThisWillActuallyRun {

  @RequestMapping("/")
  String home() {
    "Hello World!"
  }
}
SpringApplication.run(ThisWillActuallyRun, args)


Tuesday, April 15, 2014

IllegalStateException Method on class was used outside of a Grails application

After upgrade to 2.3 and running Geb functional UI tests, they started to fail with error:

java.lang.IllegalStateException: Method on class [my.Test] was used outside of a Grails application. If running in the context of a test using the mocking API or bootstrap Grails correctly.
       at my.Test.currentGormStaticApi(Test.groovy)
       at my.Test.$static_methodMissing(Test.groovy)
       at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
       at groovy.lang.MetaClassImpl.invokeStaticMissingMethod(MetaClassImpl.java:1372)
       at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1360)
       at groovy.lang.ExpandoMetaClass.invokeStaticMethod(ExpandoMetaClass.java:1123)
       at org.codehaus.groovy.runtime.callsite.StaticMetaClassSite.call(StaticMetaClassSite.java:50)
       at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
       at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
       at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)


After some pretty painful investigation, I found out that problem is when running tests with new fork mode properties, and is easy to solve by removing these options from BuildConfig.groovy:

grails.project.fork = [
    test: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256, daemon:true],
    run: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256, forkReserve:false],
    war: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256, forkReserve:false],
    console: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256]
]

Thursday, April 3, 2014

MeteorJS like application in Grails

MeteorJS is new web framework that combines server-side and client-side programming into one, leaving mostly just client-side. I am defenitely not expert with tool and just seen demo on their homepage, but WOW effect is sure impressive. It suppose to kill all Rails and server-side development in general. Thank god I am full-stack developer, but anyway I am scared.

General idea behind this framework is autogenerating all server-side code, leaving mostly just configuration. Similar feature was recently introduced in Grails, so I was wondering - is it possible to create something similar to MeteorJS in Grails. And there is my experience.

Basically, it needs autogenerated REST, Javascript ORM and server push. REST is Grails feature since version 2.3; for client-side ORM I picked CanJS as it looks most similar to Meteor; for server push in Grails I picked spring-websocket plugin (because it is first result in Google, why else?). Unfortunately, spring-websocket is M1 and it relies on Spring 4, so Grails is 2.4M1 too, so it is not production safe, but MeteorJS is 0.8.0 now too, so we are even.

Application idea is simple TODO app. You can find full source here. There is defenitely some boilerplate code as it is not plugin, but I think in general it is pretty similar to MeteorJS example. It consists of 3 meaningful components: view, controller and domain object.

View is Mustache template, and is pretty straightforward if you are familiar with CanJS:

<h1>test</h1>
<table>
{{#todos}}
  <tr>
    <td>{{description}}</td><td><input type="checkbox" can-value="done"></td>
    <td><input type="button" value="Delete" can-click="delete"></td>
    </tr>
{{/todos}}
</table>

Description
<input type="text" can-value="description">
<input type="button" can-click="add" value="Add">

Controller is CanJS component with ORM definition:

var Todo = can.Model({
  findAll: function(id)   {return $.get('/grails-meteor-example/todos.json/')},
  findOne: function(id)   {return $.get('/grails-meteor-example/todos.json/'+id)},
  create:  function(data) {return $.post('/grails-meteor-example/todos.json/', data)},
  update:  function(id)   {return $.ajax({type: 'PUT',    url: '/grails-meteor-example/todos.json/'+id })},
  destroy: function(id)   {return $.ajax({type: 'DELETE', url: '/grails-meteor-example/todos/'+id, contentType: 'application/json' })}
}, {});

can.Component.extend({
  tag: "todos",
  template: can.view("todos.mustache"),
  scope: {
    todos: new Todo.List({}),
    description: can.compute(''),
    add: function() {
      new Todo({'description':this.description(), 'done':false}).save();
      this.description('');
    },
    delete: function(todo) {
      todo.destroy();
    }
  },
  events: {
    "{todo} change": function(){
      this.scope.attr('todos', new Todo.List({}));
    }
  }
});

$(document).ready(function() {
  $("body").html( can.view.mustache("<todos></todos>"));
});


Domain is Grails domain object mapped as REST controller:

package org.grmeteor

import grails.rest.Resource

@Resource(uri='/todos')
class Todo {
  String description
  boolean done
}


View is totally similar to MeteorJS. Controller is similar, but also contains ORM definition and server push event. Both could be easily autogenerated with Grails plugin, but at least push can be also left for practical applications (probably, you will not want to have notification with millions of parallel users). Domain is pure Grails overhead, but it would probably still be needed for SQL backends in MeteorJS (and hey, those server-side devs want to eat too!).

Of course there are other files too, like server push sender and client side HTML container for CanJS, but these are mostly static and sure can be easily hidden by plugin. So only part that is missing to make Grails MeteorJS-cool is plugin itself, which even if not for practical cases could be nice to have for WOW effect and MVPs.

Wednesday, April 2, 2014

Grails REST redirect after DELETE with jQuery

If you do delete from AJAX request (directly or via framework), sometimes Grails REST controller redirects response to index method, which when done with DELETE method leads to 405 HTTP error.
This happens because of incorrect content type in request. To fix it, contentType needs to be explicitly set in request, like:

$.ajax({
    url: '/todos/'+id,
    type: 'DELETE',
    contentType: 'application/json'
  })

Tuesday, February 11, 2014

Grails dies in the middle of Jenkins jobs after update

If you have upgraded recently and facing problem when job suddenly dies in the middle of test execution, like:

19:20:39  | Running 277 unit tests... 156 of 277
19:20:53  Build step 'Execute shell' marked build as failure
19:20:54  Description set: 

Most probably it is because since version 2.2 test-app, run-app, run-war runs in fork mode and Jenkins has some fancy zombie process detection that kills spawned processes it does not like.
Quick solution is to disable fork in test environment or you can refer my previous post about hiding such processes.

Monday, February 3, 2014

No such property error in Cucumber specs with Geb

It is common to write Geb specs directly referencing page elements like:
  to LoginPage
  loginField << login
  passwordField << password
  loginButton.click()

But if you try doing same with Cucumber step files, you will get exception, like:
No such property: loginField for class: steps.Login_steps
groovy.lang.MissingPropertyException: No such property: loginField for class: steps.Login_steps
 at steps.Login_steps$_run_closure2.doCall(Login_steps.groovy:42)
 at ✽.When user enters login and password(Login.feature:7)

This is because page object is not bound and you should reference it explicitly, like:
  to LoginPage
  page.loginField << login
  page.passwordField << password
  page.loginButton.click()


Friday, December 20, 2013

Access to services from gsp views in Grails

Accessing services from views is considered bad practice, so there is no easy way to do it. It defenitely should not be overused, as it complicates testing and couples logic with presentation. However it is not necessary crime and can be handy for some cases.

For example, if you need access to user parameters. Traditional way to do it, is by using taglibs. What is less known is that you can use taglibs not just to produce text output, but also inside snippets of code in views. For example, you can use it to select users preferred language without need to inject it into every controller:

Taglib:

class UserSettingsTagLib {
    def springSecurityService

    def myLanguage = { attrs, body ->
      out << springSecurityService.currentUser?.myLanguage?.id
    }

}


Gsp:

<g:select name="language" optionKey="id" optionValue="name" value="${g.myLanguage()}" from="${Language.list().sort{it.name}}"/>


Friday, November 1, 2013

Traffic redirection to https in Grails behind load balancer

Grails security plugin has nice feature that allows automatically redirect queries for specific pages to https. For example, you can put this code into Config.groovy to redirect all requests:


grails.plugins.springsecurity.secureChannel.definition = [
    '/**':         'REQUIRES_SECURE_CHANNEL'
]

Unfortunately this does not work when your Tomcat is behind load balancer that does all encryption. To do it requires a little more work.

First, it is needed to specify how to detect either connection is secure or not. Standard way to do it with load balancers is to use X-Forwarded-Proto header. So it needs to be specified in Config.groovy like:

grails.plugins.springsecurity.secureChannel.useHeaderCheckChannelSecurity = true
grails.plugins.springsecurity.portMapper.httpsPort = 443

Worst part, is that it requires Tomcat reconfiguration, so it is needed to update Connector element in server.xml, like:

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443"  proxyName="yourserver.com" proxyPort="443" secure="true" scheme="https"  />

Good part is that it works nicely locally and across multiple environments, no need for fake certificates or different builds.


Thursday, September 5, 2013

Adding error messages to domain object in Grails

Sometimes it is more convenient to do some validation outside of the domain object, on the other side it is still nice to use standard error reporting facilities. For these cases, you can inject errors into domain objects like:

    if (someError) {
      domainobject.errors.rejectValue('param', "hasErrors")
    }
    ...
    if (!domainobject.hasErrors() && domainobject.save(flush: true)) {
    ...


Wednesday, April 24, 2013

ChannelResolutionException in Spring Integration with Groovy

Recently, after launching Spring Integration beans I got weird exception:
ChannelResolutionException: no output-channel or replyChannel header available
After some googling I found out that this error means that Spring Integration tries to configure reply channel, which in my case meant that I am replying into channel-adapter, which is not possible. So basically, problem was that my service method was defined as:
def myServiceMethod()

which Spring understands as it returns something, even if it does not. So this should be told explicitly, like:
void myServiceMethod()

and this is it.

Wednesday, April 17, 2013

jQuery / Javascript method runs several times after single call

Recently, I was developing web page and attached click handler to button, which was loading some content into div element. What was unexpected, after first click - it loaded everything just fine, but each next click was increasing amount of method calls.
As I found out, problem was that after successful method execution it also loaded default page template with every new fragment, including JavaScript page initialization scripts, which was adding new handlers to all old buttons, and so on, and so on.
It was easy to fix by creating new empty template specifically for HTML fragments.
I had this problem with Grails, but any template engine with too many conventions and defaults can be vulnerable.

Thursday, March 21, 2013

How to kill Tomcat server running from standalone plugin

I have demo application which is running from Grails standalone plugin and wanted to automate deployment from Jenkins. Starting such application is well documented and easy, but there is nothing about stopping it.
After quick digging plugin's code, I found that it has undocumented feature to do it. It creates server on application server port + 1, and as soon as there is connection - shuts server. So if your server port is 8080, this command from same computer will kill server:

telnet localhost 8081

Friday, February 1, 2013

ActiveMQ pool logging

If you are using org.apache.activemq.pool.PooledConnectionFactory for ActiveMQ connection pooling, it is maybe frustrating to detect server connection problems as it does not log anything at INFO level. DEBUG level contains reconnection records, but also a lot of unnecessary, boring stuff, not needed for production. Fortunately, there is logger that can be used for connections monitoring, which is not nicest, but working solution, and definitely it is better than nothing:

    debug 'org.apache.activemq.util.ThreadPoolUtils'


Friday, January 25, 2013

grails-coffeescript-resources is not working after deploying war in production

There is great Grails plugin that allows to work with CoffeeScript very easily, compiles .coffee files on the fly and does all dirty work.
However, once I tried to deploy my application to test environment, all CoffeeScript files became available in browser as is, without compilation. After some investigation I found out that problem is that it does not supports applications deployed as packed WAR files (with unpackWARs="false" in server.xml), it was pretty easy to fix by modifying plugin script grails-app/resourceMappers/CoffeeScriptResourceMapper.groovy by changing:
 
      File input = grailsApplication.parentContext.getResource(resource.sourceUrl).file

to this

      File input
      try {
        input = grailsApplication.parentContext.getResource(resource.sourceUrl).file
      } catch (FileNotFoundException e) {
        input = new File(original.absolutePath)
      }


and it should work.
One problem is that this change is inside plugin, so you can't do change in your code, and should change plugin itself. I submitted fix with pull request on GitHub, hopefully it will be merged. Until then it is possible to compile your own version from here, or just replace this one line on build server.


Friday, January 18, 2013

Working around grails.serverURL redirect in Grails 2

The most annoying issue with Grails 2 migration is that it requires redirection to grails.serverURL when it is specified. This property is needed if there are absolute links in application (in emails, for example).
First problem that I had with it, was after deploying application to test environment. We deploy production version, so all redirects became redirects to production, this could be solved by externalizing Grails configuration.
Second problem was more severe. We have following setup: load balancer with two nodes behind it. Our deployment script takes first node down, deploys, runs smoke tests, releases first node, takes second node down, deploys, smoke tests, releases.
So basically, production URL is load balancer's entry point, and when smoke tests run on node which is down it is never redirected to tested server (because it is down and it is behind load balancer), so every redirect (after spring security login, for example), breaks tests flow.
After some digging around, I found the best option is to abandon grails.serverURL - which is totally unusable now, and add to email link generation my own parameter from externalized Grails configuration (for each environment). This is sad as createLink with absolute parameter was great function and it didn't required dragging custom parameters.
That is how it is now.
What I would love to see in the future is grails.serverURL is used ONLY in all links generated with absolute:true and nowhere else, but all redirects work as if grails.serverURL not specified at all.

Thursday, January 17, 2013

Fixing GORM UserType after migration to version 2

Grails allows to define custom UserType to properties like in regular Hibernate, by specifying them next to properties in domain objects, like:


  someproperty type: MyUserType

But after migrating to Grails 2.2, these stopped working and Grails started to treat them as plain objects (enumerations in my particular case). Fortunately, this was easy to fix by defining all custom user types in Config.groovy, like:


grails.gorm.default.mapping = {
  'myproperty-type'(type: my.org.MyUserType, class: my.org.MyEnum)
}

This also defines mapping for all properties of specific type, so no need to do it in every domain class.