question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

misleading message when SpringFactory doesn't start correctly

See original GitHub issue

👓 What did you see?

Using Cucumber BOM 7.4.1 on a Spring Boot 2.7 project, I am launching my cucumber test. I see the Spring Context loading, but then the test fails and I get a long stacktrace :

io.cucumber.core.backend.CucumberBackendException: No test instance
	at app//io.cucumber.spring.TestContextAdaptor.notifyTestContextManagerAboutAfterTestMethod(TestContextAdaptor.java:129)
	at app//io.cucumber.spring.TestContextAdaptor.stop(TestContextAdaptor.java:109)
	at app//io.cucumber.spring.SpringFactory.stop(SpringFactory.java:159)
	at app//io.cucumber.core.runner.Runner.disposeBackendWorlds(Runner.java:156)
	at app//io.cucumber.core.runner.Runner.runPickle(Runner.java:78)
	at app//io.cucumber.junit.platform.engine.CucumberEngineExecutionContext.lambda$runTestCase$4(CucumberEngineExecutionContext.java:112)
	at app//io.cucumber.core.runtime.CucumberExecutionContext.lambda$runTestCase$5(CucumberExecutionContext.java:129)

After investigating in debug mode, I realized my scenario is found, and I am entering in the glue-code, but failing immediately :

  public DwhStepDef(TestRestTemplate restTemplate, DwhDao dwhDao) {

    DataTableType(
        (Map<String, String> row) -> Dwh.builder().code(Long.parseLong(row.get("code")))
            .description(row.get("description")).build());
    DataTableType(
        (Map<String, String> row) -> DwhEntity.builder().code(Long.parseLong(row.get("code")))
            .description(row.get("description"))
            .build());
.....

using DataTableType here actually throws an InvocationTargetException :

java.lang.NullPointerException: Cannot invoke “io.cucumber.java8.LambdaGlueRegistry.addDataTableType(io.cucumber.core.backend.DataTableTypeDefinition)” because the return value of “java.lang.ThreadLocal.get()” is null

This code used to work with previous versions, and that’s fine, I will change it.

But the message we are getting by default is really misleading (and I just spent 2h to understand what was wrong)

✅ What did you expect to see?

The exception that is thrown should be seen in the logs, but it’s not : the system is in an inconsistent state, and this is caught at the end, providing an error message that is totally unrelated with the actual issue.

📦 Which tool/library version are you using?

in io.cucumber.core.runner.Runner 7.4.1 , I see :

public void runPickle(Pickle pickle) {
    try {
        StepTypeRegistry stepTypeRegistry = createTypeRegistryForPickle(pickle);
        snippetGenerators = createSnippetGeneratorsForPickle(stepTypeRegistry);

        // Java8 step definitions will be added to the glue here
        buildBackendWorlds();

        glue.prepareGlue(stepTypeRegistry);

        TestCase testCase = createTestCaseForPickle(pickle);
        testCase.run(bus);
    } finally {
        glue.removeScenarioScopedGlue();
        disposeBackendWorlds();
    }
}

The exception is thrown by the call to buildBackendWorlds . Is it normal that there’s no catch block and that we directly go to the finally block ? I would say that having a catch block would enable to log the original exception, and lead the developer directly in the right direction.

🔬 How could we reproduce it?

I guess with any glue code that throws some Exception at instantiation time…

📚 Any additional context?

with v7.3.4 or v7.2.3 , my test also fails, but I get a proper error message that tells me what is wrong :

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [my.project.dwh.cucumber.DwhStepDef]: Constructor threw exception; nested exception is java.lang.NullPointerException: Cannot invoke “io.cucumber.java8.LambdaGlueRegistry.addBeforeHookDefinition(io.cucumber.core.backend.HookDefinition)” because the return value of “java.lang.ThreadLocal.get()” is null at app//org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:224) at app//org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:117) at app//org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:311) … 105 more Caused by: java.lang.NullPointerException: Cannot invoke “io.cucumber.java8.LambdaGlueRegistry.addBeforeHookDefinition(io.cucumber.core.backend.HookDefinition)” because the return value of “java.lang.ThreadLocal.get()” is null at io.cucumber.java8.LambdaGlue.Before(LambdaGlue.java:69) at my.project.dwh.cucumber.DwhStepDef.<init>(DwhStepDef.java:45) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480) at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:211) … 107 more

Issue Analytics

  • State:closed
  • Created a year ago
  • Reactions:2
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
mpkorstanjecommented, Jul 7, 2022
SpringBootTest(classes = DwhE2EApplication.class, webEnvironment = RANDOM_PORT)
@CucumberContextConfiguration
@ActiveProfiles("test")
public class DwhStepDef implements En {

Thanks for the reproducer. That made things easy.

You’ve annotated a lambda step definitions with a context configuration. Cucumber uses this class to start the spring application.

Cucumber also has to create an instance of this class to provide to springs test context manager framework. This instance must be created before the Java8Backend starts. So steps can’t be registered yet.

This is partially due to the impedance mismatch but also yet another reason for https://github.com/cucumber/cucumber-jvm/issues/2279. Registering steps at runtime causes all sorts of problemens.

As a workaround consider putting the context configuration on it’s own class.

0reactions
vincent-fuchscommented, Jul 8, 2022

Thanks a lot for the pointer to the workaround !

Read more comments on GitHub >

github_iconTop Results From Across the Web

java - Factory method isn't getting called correctly in Spring - Stack ...
withMessage(message). ... I know the problem is that the sns client has the wrong region, because if i do ... factory-method="build"/> just doesn't...
Read more >
[JVM] AbstractMethodError from SpringFactory.start
I want to use cucumber-spring so I can use configuration properties in a way that will be intuitive to my coworkers. However, after...
Read more >
Chapter 3. Beans, BeanFactory and the ApplicationContext
The basic principle is that beans define their dependencies (i.e. the other objects they work with) only through constructor arguments, arguments to a...
Read more >
Fix Your PC did not start correctly message in Windows 11/10
Have you ever encountered a problem where your Windows PC does not start properly after booting it? It may happen after a sudden...
Read more >
Can't create new contexts after factory is closed (java.lang ...
Please correct me if I am wrong. check this out: Consider having 1 million records to place in a queue for a 3...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found