Groovy gotcha: Passing zero arguments to a method that expects one

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:

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:

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

About the Author

Object Partners profile.

One thought on “Groovy gotcha: Passing zero arguments to a method that expects one

  1. Joe says:

    Makes sense…kinda. If null is nothing, then foo(null) would be equivalent to foo(); in both cases, we’re calling the method and passing in “nothing.” But this doesn’t work other way around: I cannot define an argument-less method and invoke it with a single null argument. So I suppose the takeaway is: nothing is null but null isn’t nothing.

    1. Igor Shults says:

      Yeah what got me though is that it only works for single-argument methods, even when the method takes a second optional parameter. It just seems a little inconsistent and I couldn’t find it documented anywhere.

      This is almost JavaScript-y behavior, but only in a limited case.

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Blog Posts
Using Conftest to Validate Configuration Files
Conftest is a utility within the Open Policy Agent ecosystem that helps simplify writing validation tests against configuration files. In a previous blog post, I wrote about using the Open Policy Agent utility directly to […]
SwiftGen with Image & Color Asset Catalogs
You might remember back in 2015 when iOS 9 was introduced, and we were finally given a way to manage all of our assets in one place with Asset Catalogs. A few years later, support […]
Tracking Original URL Through Authentication
If you read my other post about refreshing AWS tokens, then you probably have a use case for keeping track of the original requested resource while the user goes through authentication so you can route […]
Using Spring Beans in a Kafka Streams ExceptionHandler
There are many things to know before diving into Kafka Streams. If you haven’t already, check out these 5 things as a starting point. Bullet 2 mentions designing for exceptions. Ironically, this seems to be […]