cucumber/cucumber-jvm — Issue #93: Groovy Backend, NullPointerException in stepDefLocation()
Author: hauner
Created: 2011-11-16 21:45:10+00:00
State: open

I have 3 test features for my grails plugin, and when cucumber-jvm is adding the steps to the GroovyBackend on my
third feature file I get a NullPointerException in GroovyBackend.stepDefLocation ().

Issue is, that at the third feature file, the Stacktrace is different for the failing step (I have all step in a single file).

Below you will see two stacktraces I get for the same step when running different features. It changed at [3].
In the second case it looks like as if the jvm has replaced the two reflection calls (3&4) with a single generated method,
which does not have a filename.

GroovyBackend.stepDefLocation () does not handle this.

Adding a null check for the filename will fix it.

private static StackTraceElement stepDefLocation() {
Throwable t = new Throwable();
StackTraceElement[] stackTraceElements = t.getStackTrace();
for (StackTraceElement stackTraceElement : stackTraceElements) {
String fileName = stackTraceElement.getFileName ();
if (fileName != null && fileName.endsWith(".groovy")) {
return stackTraceElement;
}
}
throw new RuntimeException("Couldn't find location for step definition");
}

Stacktrace when adding the steps for the first feature:

static = cucumber.runtime.groovy.GroovyBackend
t = {java.lang.Throwable@3772}"java.lang.Throwable"
stackTraceElements = {java.lang.StackTraceElement[419]@3773}
[0] = {java.lang.StackTraceElement@3778}"cucumber.runtime.groovy.GroovyBackend.stepDefLocation(GroovyBackend.java:80)"
[1] = {java.lang.StackTraceElement@3779}"cucumber.runtime.groovy.GroovyBackend.addStepDefinition(GroovyBackend.java:52)"
[2] = {java.lang.StackTraceElement@3780}"cucumber.runtime.groovy.EN.Then(EN.java:17)"
[3] = {java.lang.StackTraceElement@3781}"sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)"
[4] = {java.lang.StackTraceElement@3782}"sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)"
[5] = {java.lang.StackTraceElement@3783}"sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)"
[6] = {java.lang.StackTraceElement@3784}"java.lang.reflect.Method.invoke(Method.java:597)"
[7] = {java.lang.StackTraceElement@3785}"org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)"

Stacktrace when adding the steps for the third feature:

static = cucumber.runtime.groovy.GroovyBackend
t = {java.lang.Throwable@5098}"java.lang.Throwable"
stackTraceElements = {java.lang.StackTraceElement[418]@5520}
[0] = {java.lang.StackTraceElement@5101}"cucumber.runtime.groovy.GroovyBackend.stepDefLocation(GroovyBackend.java:80)"
[1] = {java.lang.StackTraceElement@5102}"cucumber.runtime.groovy.GroovyBackend.addStepDefinition(GroovyBackend.java:52)"
[2] = {java.lang.StackTraceElement@5103}"cucumber.runtime.groovy.EN.Then(EN.java:17)"
[3] = {java.lang.StackTraceElement@5104}"sun.reflect.GeneratedMethodAccessor90.invoke(Unknown Source)"
declaringClass = {java.lang.String@5539}"sun.reflect.GeneratedMethodAccessor90"
methodName = {java.lang.String@5540}"invoke"
fileName = null
lineNumber = -1
[4] = {java.lang.StackTraceElement@5105}"sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)"
[5] = {java.lang.StackTraceElement@5106}"java.lang.reflect.Method.invoke(Method.java:597)"
[6] = {java.lang.StackTraceElement@5107}"org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)"
[7] = {java.lang.StackTraceElement@5108}"org.codehaus.groovy.runtime.metaclass.MixinInstanceMetaMethod.invoke(MixinInstanceMetaMethod.java:53)"