Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aspectj annotation is being ignored while using Spring and Cucumber v7.10.0 onwords #2886

Closed
Hakky54 opened this issue May 22, 2024 · 7 comments · Fixed by #2887
Closed

Aspectj annotation is being ignored while using Spring and Cucumber v7.10.0 onwords #2886

Hakky54 opened this issue May 22, 2024 · 7 comments · Fixed by #2887

Comments

@Hakky54
Copy link

Hakky54 commented May 22, 2024

👓 What did you see?

I am using Cucumber alongside with Spring ans Aspectj. This setup always worked. I was on version 7.2.3 of cucumber. I tried bumping it to 7.18.0 however some part of my tests failed. It was not picking up the aspectj annotations of the before and after step. I am not qure what is causing the issue. However If I downgrade to version 7.9.0 it still works. If I bump it to 7.10.0 it fails.

✅ What did you expect to see?

I would expect my existing test suite still be working

📦 Which tool/library version are you using?

JDK 17
Maven

🔬 How could we reproduce it?

  1. Git clone https://github.com/Hakky54/mutual-tls-ssl.git
  2. Adjust pom.xml in the root directory of the project. Change version of cucumber to 7.10.0
  3. run mvn clean verify it will throw nullpointer exception

The before and after call in LogExecutionTimeAspect.java is being ignored somehow while it is still working on version 7.9.0

📚 Any additional context?

No response

@mpkorstanje
Copy link
Contributor

Interesting. Haven't quite got the time to dig into a bug project like this, but could you put @CucumberContextConfiguration on a separate class?

@Hakky54
Copy link
Author

Hakky54 commented May 23, 2024

I have tried that, but then I end up getting the well known error messsage:

io.cucumber.core.backend.CucumberBackendException: Please annotate a glue class with some context configuration.

For example:

   @CucumberContextConfiguration
   @SpringBootTest(classes = TestConfig.class)
   public class CucumberSpringConfiguration { }
Or: 

   @CucumberContextConfiguration
   @ContextConfiguration( ... )
   public class CucumberSpringConfiguration { }

	at io.cucumber.spring.SpringFactory.start(SpringFactory.java:100)
	at io.cucumber.core.runner.Runner.buildBackendWorlds(Runner.java:134)
	at io.cucumber.core.runner.Runner.runPickle(Runner.java:70)
	at io.cucumber.junit.PickleRunners$NoStepDescriptions.lambda$run$0(PickleRunners.java:151)
	at io.cucumber.core.runtime.CucumberExecutionContext.lambda$runTestCase$5(CucumberExecutionContext.java:129)
	at io.cucumber.core.runtime.RethrowingThrowableCollector.executeAndThrow(RethrowingThrowableCollector.java:23)
	at io.cucumber.core.runtime.CucumberExecutionContext.runTestCase(CucumberExecutionContext.java:129)
	at io.cucumber.junit.PickleRunners$NoStepDescriptions.run(PickleRunners.java:148)
	at io.cucumber.junit.FeatureRunner.runChild(FeatureRunner.java:144)
	at io.cucumber.junit.FeatureRunner.runChild(FeatureRunner.java:28)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at io.cucumber.junit.FeatureRunner.run(FeatureRunner.java:137)
	at io.cucumber.junit.Cucumber.runChild(Cucumber.java:196)
	at io.cucumber.junit.Cucumber.runChild(Cucumber.java:89)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at io.cucumber.junit.Cucumber$RunBeforeAllHooks.evaluate(Cucumber.java:266)
	at io.cucumber.junit.Cucumber$RunAfterAllHooks.evaluate(Cucumber.java:281)
	at io.cucumber.junit.Cucumber$StartTestRun.evaluate(Cucumber.java:233)
	at io.cucumber.junit.Cucumber$FinishTestRun.evaluate(Cucumber.java:248)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
	at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)

      io.cucumber.core.backend.CucumberBackendException: Please annotate a glue class with some context configuration.

I was a bit hasty yesterday when creating the issue. I have added here a more detailed steps to reproduce it:

So if you are able to open this project in your IDEA, Eclipse or Visual Studio Code. Add a breakpoint here: LogExecutionTimeAspect.java
Start the server by running the main method: App.java
Start cucumber test in debug mode with the runner ClientRunnerIT.java and you will see it will stop at the breakpoint. Now if you update the version to 7.10.0 in pom.xml recompile the project with mvn clean compile and start the cucumber runner again it won't stop at the breakpoint in LogExecutionTimeAspect.java

I created this project to help others to understand ssl/tls. So it is a tutorial having spring boot as a server and the client module has over 40+ http clients as example to give others also code examples with actual working tests. And I use cucumber in the client module to test all of them. It contains a mixture of Java, Kotlin and Scala code which the project can build. It has worked so far, but I am not able to understand why bumping cucumber makes the AspectJ pointcut fail. So the workaround for me is to remove the following line in the feature file: Hello.feature#L9 and remove AspectJ and not logging execution time. So that won't be a big deal actually, but I am just curious what is causing in version 7.10.0 that it won't work anymore and maybe you know the answer 😄

I hope this detailed description is a bit more helpful compared to my initial issue description

@mpkorstanje
Copy link
Contributor

That is informative!

Could you try annotating the SpringBootHelper with @CucumberContextConfiguration instead and make sure its package is on the glue path? Additionally your BaseStepDefs definitions should not extend the SpringBootHelper.

@Hakky54
Copy link
Author

Hakky54 commented May 23, 2024

Thank you! That worked like a charm. Amazing that you found the issue that quickly! I did the adjustment here: Hakky54/mutual-tls-ssl@f8bb438 and the build is passing, see here: https://github.com/Hakky54/mutual-tls-ssl/actions/runs/9206458636 We can close this issue. Thank you for your help!

It seems like I wrongly configured cucumber and spring. But is cucumber more strict in the configuration setup from version 7.10.0 onwords? It seems that my existing setup was not an issue in the past, but maybe not the correct way to setup everything....

@mpkorstanje
Copy link
Contributor

mpkorstanje commented May 23, 2024

Oh, it was just a guess. But you're welcome!

I'll leave this open for now, ideally Cucumber would catch misconfiguration with a clear exception message. But I don't really understand why what you did here would be wrong - and that doesn't make for a good explanation / instruction.

mpkorstanje added a commit that referenced this issue May 24, 2024
Cucumber uses Spring Test Context Manager framework. This framework was
written for JUnit and assumes that there is a "test instance".
Cucumber however uses multiple step definition classes and so it has
multiple test instances.

Originally `@CucumberContextConfiguration` was added to signal to Spring
which class should be used to configure the application context from.
But as people also expected mock beans and other features provided by
Springs test execution listeners to work (#2661) the annotated instance
was only instantiated but never initialized by Spring.

This changed the semantics somewhat as now features that depend on the
bean being initialized stopped working (#2886). Unfortunately, there is
little that can be done here. Spring expects that the instance provided
to the Test Context Manager to be an uninitialized bean. The solution
for this is to put the context configuration and step definitions in
different classes.

Cleaning up the examples to follow this pattern should avoid this
problem somewhat in the future. Though I won't go as far as recommending
people do this. Putting everything in one class looks quite nice. And
generally still works.

Closes: #2886
mpkorstanje added a commit that referenced this issue May 24, 2024
Cucumber uses Spring Test Context Manager framework. This framework was
written for JUnit and assumes that there is a "test instance".
Cucumber however uses multiple step definition classes and so it has
multiple test instances.

Originally `@CucumberContextConfiguration` was added to signal to Spring
which class should be used to configure the application context from.
But as people also expected mock beans and other features provided by
Springs test execution listeners to work (#2661) the annotated instance
was only instantiated but never initialized by Spring.

This changed the semantics somewhat as now features that depend on the
bean being initialized stopped working (#2886). Unfortunately, there is
little that can be done here. Spring expects that the instance provided
to the Test Context Manager to be an uninitialized bean. The solution
for this is to put the context configuration and step definitions in
different classes.

Cleaning up the examples to follow this pattern should avoid this
problem somewhat in the future. Though I won't go as far as recommending
people do this. Putting everything in one class looks quite nice. And
generally still works.

Closes: #2886
@mpkorstanje
Copy link
Contributor

Okay. As it turns out, nothing is wrong here. Prior to #2661 cucumber instantiated and initialized the annotated classes. However Spring expected only an instantiated raw bean. As we stopped instantiating, things like AspectJ also stopped working.

@Hakky54
Copy link
Author

Hakky54 commented May 24, 2024

Ah, it makes sense now and the additional documentation for this topic in your PR is also helpful. Thank you for further investigating this

mpkorstanje added a commit that referenced this issue Sep 12, 2024
Cucumber uses Spring Test Context Manager framework. This framework was
written for JUnit and assumes that there is a "test instance".
Cucumber however uses multiple step definition classes and so it has
multiple test instances.

Originally `@CucumberContextConfiguration` was added to signal to Spring
which class should be used to configure the application context from.
But as people also expected mock beans and other features provided by
Springs test execution listeners to work (#2661) the annotated instance
was only instantiated but never initialized by Spring.

This changed the semantics somewhat as now features that depend on the
bean being initialized stopped working (#2886). Unfortunately, there is
little that can be done here. Spring expects that the instance provided
to the Test Context Manager to be an uninitialized bean. The solution
for this is to put the context configuration and step definitions in
different classes.

Cleaning up the examples to follow this pattern should avoid this
problem somewhat in the future. Though I won't go as far as recommending
people do this. Putting everything in one class looks quite nice. And
generally still works.

Closes: #2886
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants