Getting Grails Database Connections to Reconnect
August 19th, 2015
Getting Grails Database Connections to Reconnect
I was recently adding a parameter to a legacy method, and after updating all the callers of the method, I found that I was still getting a MethodMissingException. That was strange, since the old method took one required parameter, and the exception was being thrown on a line which called a method of the same name with no arguments. My first reaction was that it couldn’t possibly be the same method I was updating, but… I was wrong. Apparently Groovy will compile just fine in certain scenarios where no arguments are passed to a method that expects one.
For example, only the second call below throws a MissingMethodException:
void doSomething(def foo) {
println foo
}
void doSomethingElse(int bar) {
println bar
}
doSomething()
doSomethingElse() // Throws MissingMethodException
The first one will compile and run without issue, and will print “null” to the console. That’s unexpected, but it makes sense given that we accept an object (this works with any object, as far as I can tell). The second call fails because it expects a primitive, and I guess Groovy does not resolve to pass any “default” values to it. You can try this out in the Groovy web console, if you want to play around with it yourself.
Upon compilation, you may think that Groovy implicitly creates a zero-arg method similar to having an optional parameter, but examining the class’s methods proves otherwise; whereas the required parameter version only yields public void SomeClass.doSomething(java.lang.Object), the optional one really does compile to two methods: public void SomeClass.doSomething(java.lang.Object) and public void SomeClass.doSomething().
The fact that there is no zero-arg method means that this is a special case, rather than a rule of passing n-1 arguments to a method. This is clearly demonstrated if we try to add another parameter to our method, and call it with only one argument. This is true even if the new parameter is optional with a default value:
void doSomething(def foo, def newParam = null) {
println foo
}
void doSomethingAgain(def baz, def newParam) {
println baz
}
doSomething() // Throws MethodSelectionException
doSomethingAgain('Test') // Throws MissingMethodException
The first call above will throw a MethodSelectionException, while the second will throw a MissingMethodException but we are mostly back in the realm of “expected” Java behavior.
This may be common knowledge to some, but other developers I spoke to were not aware of this behavior. It’s certainly interesting, but I wouldn’t advocate it as best practice. It seems clearer and more maintainable to simply make a parameter optional, rather than relying on Groovy to pass the null value. However, if you’re refactoring a method signature and find yourself getting some unexpected behavior, hopefully this post can shed some light.
Igor Shults
Getting Grails Database Connections to Reconnect
Details a method to share Grails object marshallers across XML, JSON and HAL flavors of web services.
A quick introduction to Retrofit. Well cover the basics for how to convert any API into a type-safe Java interface using @GET, @POST, @QUERY, and @PARAM.
Igor is a self-driven developer with a desire to apply and expand his current skill set. He has experience working with companies of all sizes on the whole application stack, from the database to the front-end. He enjoys working in collaborative environments involving discussion and planning around data modeling and product development.