Wednesday, October 24, 2012

NullPointerException when saving Grails object

Recently I got very strange NPE while saving updated entity in Grails application:

java.lang.NullPointerException
 at com.test.MyController$_closure5.doCall(MyController.groovy:69)
 at com.test.MyController$_closure5.doCall(MyController.groovy)
 at net.bull.javamelody.JspWrapper.invoke(JspWrapper.java:149)
 at net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler.invoke(JdbcWrapper.java:259)
 at $Proxy49.forward(Unknown Source)
 at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:206)
 at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:179)
 at java.lang.Thread.run(Thread.java:662)

All I was doing on line 69 was just calling save() method, object obviously was not null, all fields and dependencies too. Even more - saving another object from same method was perfectly fine, but not one particular.
Finally, I got the reason - object had null in it's version field. Obviously migration was not done properly or it was manually created object in bad schema, but setting version solved my problem easily, but bad error reporting - didn't helped.

Thursday, October 4, 2012

Reusing methods from different hierarchies with Mixins

Grails application can be tested with many different tools: Geb, Selenium, Grails own integration testing framework, etc. To use them, you have to extend some basic test case class, like GebReportingSpec, GroovyTestCase, GrailsUnitTestCase.
Usually there is a lot of methods that are used from all these frameworks, for example for data initialization and manipulation outside of test scenario scope. So how it would be possible to reuse these methods without access to class hierarchy and avoid code duplication. One easy way is to use Groovy Mixins, that allow to add new methods to any class without affecting existing class hierarchy. For example:


@Mixin(GenericTestMethods)
class SpecificTests extends GroovyTestCase {
...


Monday, October 1, 2012

Groovy tricks: initializing map with array values by default

I feel a little Mr. Haki today, so will post Groovy recipe.
Very often, there is case when you want to aggregate some values by single key, but groupBy is not suitable or flexible enough. In this case, with every new key, you should initialize this new value with array, like:


Map values = [:]
[[key:'user1', val:123],[key:'user1', val:567],[key:'user2', val:999]].each {
  def var = values[it.key]
  if (!var) {
    var = []
    values[it.key] = var
  }
  var << it.val
}
println values

[user1:[123, 567], user2:[999]]

This is nice, but "if" statement looks redundant and ugly and complicates things. Fortunately, there is great Groovy method called "withDefault" which does pretty much same things, but in much groovier way: if there is no key, instead of null it assigns specified value to your key. So above example can be rewritten like:


Map values = [:].withDefault {k->[]}
[[key:'user1', val:123],[key:'user1', val:567],[key:'user2', val:999]].each {
  values[it.key] << it.val
}
println values
[user1:[123, 567], user2:[999]]

Friday, September 28, 2012

Using Spring Security with CXF in Grails

CXF plugin is super easy way to add SOAP web service to Grails application. It creates regular service class, with few specific parameters and voila - you have SOAP. But what if you want security?
REST web services are native citizens in Grails - they are just actions in controllers, so you can use Spring Security annotations to check permissions. But there is no annotations for services. There are two easy options.
First, you can restrict actions by defining static rules. This is very simple, but not very flexible as it does not allow to configure permissions on method level, you will have to create different services for different permissions. Also, old clients may not work if WSDL requires authentication.
Second method, is to check permissions manually. In practice this is similar to annotations, and can be converted to annotations easily. There is example:


  Secret secret(int id) {
    checkRights("VIEW_SECRET")
    return Secret.get(id)
  }

  void checkRights(String rights) {
    if (!SpringSecurityUtils.ifAllGranted(rights)) {
      throw new IllegalAccessException("You don't have permission")
    }
  }

Finding similar strings in Java

Finding equal strings in Java is very easy, as well as finding substrings. But what if you have strings that are almost similar (at least from human point of view). For example: "John Doe" and "Doo Jonh".
Recently, I had to do data migration for table with very poor data quality. There is a lot of theory and books on finding duplicates, but surprisingly, there is very little actual Java implementations that could help with such things. Fortunately, there is at least one good - Simmetrics, there is even example how to use it, but it is as simple as one can imagine:


import uk.ac.shef.wit.simmetrics.similaritymetrics.*;

AbstractStringMetric metric = new MongeElkan()
println ( ['John John', 'Doo Jonh', 'ddddddd', '7777777777'].max { metric.getSimilarity('John Doe', it) })

Doo Jonh

There is a bunch of different algorithms one can use, but I found MongeElkan to be best for my case.

Tuesday, September 18, 2012

Javamelody SQL monitoring with Grails plugin

Javamelody is amazing tool for live monitoring. It has great Grails plugin which makes it very easy to use. Only issue I had with it is SQL monitoring configuration.
According to documentation there are several ways to configure data sources:
  1. magic - you don't have to do anything, it just works
  2. javamelody.datasources property in GrailsMelodyConfig.groovy - you just specify datasources
  3. replacing JDBC driver with Javamelody proxy
  4. specifying java option - javamelody.datasources
Unfortunately, all internal configuration options (1, 2, 3) didn't worked. As I investigated (quickly) it looks like there is no dataSource bean available for BeanPostProcessor and it tries to proxy after all connections were already picked by application.
So only specifying java command line option worked for me. Otherwise - great tool. It is also possible to specify multiple data sources with command line like:


-Djavamelody.datasources=java:comp/env/ds1,java:comp/env/ds2

Monday, August 20, 2012

Getting object from calling method in Java

This is hardly production scenario, but at some point I wanted to find value of a variable from a caller class. Looks like this is not trivial task and is much more complicated than it should be (for some reason), however still possible.
Finding method and class name is easy via Thread class, but accessing real objects seems to be only possible with Java Debug Interface. For this purpose, application must be executed in debug mode (for grails it is with grails-debug command). There is no need for any additional library as everything is included into JDK and probably is used by JDK debugger.
General scenario is as folows:
  • connect with debugger provided with JDI via socket (there are other options, but sockets seems default for most tools)
  • spawn new thread where you will wait to do whatever you want to do with data on stack trace
  • suspend application at point where you want to do it
  • at the end of your work - continue application
There is example:


def att = com.sun.jdi.Bootstrap.virtualMachineManager().attachingConnectors().find{it instanceof com.sun.tools.jdi.SocketAttachingConnector}
Map arguments = att.defaultArguments()
com.sun.jdi.connect.Connector.Argument hostArg = arguments.get("hostname").setValue("localhost")
com.sun.jdi.connect.Connector.Argument portArg = arguments.get("port").setValue("5005")
com.sun.jdi.VirtualMachine vm = att.attach(arguments);
def thread = vm.allThreads().find {it.name()=='main'}
def runnable = new Runnable() {
  void run() {
 while (!thread.isSuspended() ) {
   Thread.sleep(100)
 }
 def frames = thread.frames().findAll {it.location().toString() =~ /grails.plugin.spock.test.listener.PerSpecRunListener:.*/}
 frames.each {frame->
   def res = frame.thisObject()
   def field = res.type().fieldByName("failureCount")
   if (field) {
       def countref = res.getValue(field).toString()
        ...
      }
   }
     thread.resume()
  }
}
new Thread(runnable).start()
thread.suspend()