-
-
Notifications
You must be signed in to change notification settings - Fork 2k
[Spring] Scope 'cucumber-glue' is not allowed for standard (not glue) Spring Bean during context loading #1970
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
Comments
Could you explain how to reproduce this problem and what you are trying to achieve?
This may be a documentation issue. I'm not aware of any use-case where you might want to access a glue scoped bean outside the context of a running scenario. |
Sorry I should did it in advance. I think few people can face it, but
|
Makes sense. Cheers. If I understand this correctly, you're trying to stub out some behaviour of your application? |
Neither of these things work the way you think it does. Scoped beans require a proxy, this proxy will initalize the been as needed when invoked in a particular scope. For this to work however you have to set the proxyMode.
|
I know about proxies, I just missed this point in the example. I created it to demonstrate the specific situation with the scope registration, but it does not matter, because the error is reproduced with a proxy. |
The For example: class Issue1970 {
@Test
public void issue1970() {
ObjectFactory factory = new SpringFactory();
factory.addClass(GlueClass.class); // Add glue with Spring configuration
factory.start();
GlueClass instance = factory.getInstance(GlueClass.class);
String response = instance.service.get();
factory.stop();
factory.start();
GlueClass instance2 = factory.getInstance(GlueClass.class);
String response2 = instance2.service.get();
factory.stop();
assertNotEquals(response, response2);
}
@CucumberContextConfiguration
@ContextConfiguration(classes = TestApplicationConfiguration.class)
public static class GlueClass {
@Autowired
ExampleService service;
}
@Configuration
public static class TestApplicationConfiguration {
@Bean
public BeanFactoryPostProcessor beanFactoryPostProcessor(){
return factory -> factory.registerScope(SCOPE_CUCUMBER_GLUE, new GlueCodeScope());
}
@Bean
public ExampleService service(ScenarioScopedApi api) {
return new ExampleService(api);
}
@Bean
@Scope(value = SCOPE_CUCUMBER_GLUE)
public ScenarioScopedApi api() {
return new ScenarioScopedApi();
}
}
public static class ExampleService {
final ScenarioScopedApi api;
public ExampleService(ScenarioScopedApi api) {
this.api = api;
}
String get(){
return "Api response: " + api.get();
}
}
public static class ScenarioScopedApi {
private static final AtomicInteger globalCounter = new AtomicInteger(0);
private final int instanceId = globalCounter.getAndIncrement();
public String get() {
return "instance " + instanceId;
}
}
} Will fail with: This happens because the
So if we follow these instructions and use the @Configuration
public static class TestApplicationConfiguration {
@Bean
public ExampleService service(ScenarioScopedApi api) {
return new ExampleService(api);
}
@Bean
@Scope(value = SCOPE_CUCUMBER_GLUE, proxyMode = ScopedProxyMode.TARGET_CLASS)
public ScenarioScopedApi api() {
return new ScenarioScopedApi();
}
} So I don't see why you'd need have to have access to the |
The glue code context does not require an active scenario. As a result it was possible to create scenario scoped beans that would be shared (leak) between scenarios. An example of this is illustrated below. Because this does require access to the `GlueCodeScope` it is not possible to do this in practice. ```java @configuration public static class TestApplicationConfiguration { @bean public BeanFactoryPostProcessor beanFactoryPostProcessor(){ return factory -> factory.registerScope(SCOPE_CUCUMBER_GLUE, new GlueCodeScope()); } @bean public ExampleService service(ScenarioScopedApi api) { return new ExampleService(api); } @bean @scope(value = SCOPE_CUCUMBER_GLUE) public ScenarioScopedApi api() { return new ScenarioScopedApi(); } } ``` However without registering the the `GlueCodeScope` at start up Spring will complain about missing the cucumber-glue scope rather then complain about scope not having started or the missing proxy mode. So to avoid further confusion: 1. GlueCodeContext will check if the context has been started. 2. Add a `@ScenarioScope` annotation that sets the correct proxy mode. 3. Do some renaming of internal classes 4. Use a global counter for conversation ids Related - #1970 - #1667
The glue code context does not require an active scenario. As a result it was possible to create scenario scoped beans that would be shared (leak) between scenarios. An example of this is illustrated below. Because this does require access to the `GlueCodeScope` it is not possible to do this in practice. ```java @configuration public static class TestApplicationConfiguration { @bean public BeanFactoryPostProcessor beanFactoryPostProcessor(){ return factory -> factory.registerScope(SCOPE_CUCUMBER_GLUE, new GlueCodeScope()); } @bean public ExampleService service(ScenarioScopedApi api) { return new ExampleService(api); } @bean @scope(value = SCOPE_CUCUMBER_GLUE) public ScenarioScopedApi api() { return new ScenarioScopedApi(); } } ``` However without registering the the `GlueCodeScope` at start up Spring will complain about missing the cucumber-glue scope rather then complain about scope not having started or the missing proxy mode. So to avoid further confusion: 1. GlueCodeContext will check if the context has been started. 2. Add a `@ScenarioScope` annotation that sets the correct proxy mode. 3. Do some renaming of internal classes 4. Use a global counter for conversation ids Related - #1970 - #1667
The glue code context does not require an active scenario. As a result it was possible to create scenario scoped beans that would be shared (leak) between scenarios. An example of this is illustrated below. Because this does require access to the `GlueCodeScope` it is not possible to do this in practice. ```java @configuration public static class TestApplicationConfiguration { @bean public BeanFactoryPostProcessor beanFactoryPostProcessor(){ return factory -> factory.registerScope(SCOPE_CUCUMBER_GLUE, new GlueCodeScope()); } @bean public ExampleService service(ScenarioScopedApi api) { return new ExampleService(api); } @bean @scope(value = SCOPE_CUCUMBER_GLUE) public ScenarioScopedApi api() { return new ScenarioScopedApi(); } } ``` However without registering the the `GlueCodeScope` at start up Spring will complain about missing the cucumber-glue scope rather then complain about scope not having started or the missing proxy mode. So to avoid further confusion: 1. GlueCodeContext will check if the context has been started. 2. Add a `@ScenarioScope` annotation that sets the correct proxy mode. 3. Do some renaming of internal classes 4. Use a global counter for conversation ids Related - #1970 - #1667
The glue code context does not require an active scenario. As a result it was possible to create scenario scoped beans that would be shared (leak) between scenarios. An example of this is illustrated below. Because this does require access to the `GlueCodeScope` it is not possible to do this in practice. ```java @configuration public static class TestApplicationConfiguration { @bean public BeanFactoryPostProcessor beanFactoryPostProcessor(){ return factory -> factory.registerScope(SCOPE_CUCUMBER_GLUE, new GlueCodeScope()); } @bean public ExampleService service(ScenarioScopedApi api) { return new ExampleService(api); } @bean @scope(value = SCOPE_CUCUMBER_GLUE) public ScenarioScopedApi api() { return new ScenarioScopedApi(); } } ``` However without registering the the `GlueCodeScope` at start up Spring will complain about missing the cucumber-glue scope rather then complain about scope not having started or the missing proxy mode. So to avoid further confusion: 1. GlueCodeContext will check if the context has been started. 2. Add a `@ScenarioScope` annotation that sets the correct proxy mode. 3. Do some renaming of internal classes 4. Use a global counter for conversation ids Related - #1970 - #1667
The glue code context does not require an active scenario. As a result it was possible to create scenario scoped beans that would be shared (leak) between scenarios. An example of this is illustrated below. Because this does require access to the `GlueCodeScope` it is not possible to do this in practice. ```java @configuration public static class TestApplicationConfiguration { @bean public BeanFactoryPostProcessor beanFactoryPostProcessor(){ return factory -> factory.registerScope(SCOPE_CUCUMBER_GLUE, new GlueCodeScope()); } @bean public ExampleService service(ScenarioScopedApi api) { return new ExampleService(api); } @bean @scope(value = SCOPE_CUCUMBER_GLUE) public ScenarioScopedApi api() { return new ScenarioScopedApi(); } } ``` However without registering the the `GlueCodeScope` at start up Spring will complain about missing the cucumber-glue scope rather then complain about scope not having started or the missing proxy mode. So to avoid further confusion: 1. GlueCodeContext will check if the context has been started. 2. Add a `@ScenarioScope` annotation that sets the correct proxy mode. 3. Do some renaming of internal classes 4. Use a global counter for conversation ids Related - #1970 - #1667
The glue code context does not require an active scenario. As a result it was possible to create scenario scoped beans that would be shared (leak) between scenarios. An example of this is illustrated below. Because this does require access to the `GlueCodeScope` it is not possible to do this in practice. ```java @configuration public static class TestApplicationConfiguration { @bean public BeanFactoryPostProcessor beanFactoryPostProcessor(){ return factory -> factory.registerScope(SCOPE_CUCUMBER_GLUE, new GlueCodeScope()); } @bean public ExampleService service(ScenarioScopedApi api) { return new ExampleService(api); } @bean @scope(value = SCOPE_CUCUMBER_GLUE) public ScenarioScopedApi api() { return new ScenarioScopedApi(); } } ``` However without registering the the `GlueCodeScope` at start up Spring will complain about missing the cucumber-glue scope rather then complain about scope not having started or the missing proxy mode. So to avoid further confusion: 1. GlueCodeContext will check if the context has been started. 2. Add a `@ScenarioScope` annotation that sets the correct proxy mode. 3. Do some renaming of internal classes 4. Use a global counter for conversation ids Related - #1970 - #1667
I use glue scope to save scenario vars
Then inject it to hook
And
|
Can you try this with #1974. It should correctly complain about 'cucumber-glue' scope not being active. |
The glue code context does not require an active scenario. As a result it was possible to create scenario scoped beans that would be shared (leak) between scenarios. An example of this is illustrated below. Because this does require access to the `GlueCodeScope` it is not possible to do this in practice. ```java @configuration public static class TestApplicationConfiguration { @bean public BeanFactoryPostProcessor beanFactoryPostProcessor(){ return factory -> factory.registerScope(SCOPE_CUCUMBER_GLUE, new GlueCodeScope()); } @bean public ExampleService service(ScenarioScopedApi api) { return new ExampleService(api); } @bean @scope(value = SCOPE_CUCUMBER_GLUE) public ScenarioScopedApi api() { return new ScenarioScopedApi(); } } ``` However without registering the the `GlueCodeScope` at start up Spring will complain about missing the cucumber-glue scope rather then complain about scope not having started or the missing proxy mode. So to avoid further confusion: 1. GlueCodeContext will check if the context has been started. 2. Add a `@ScenarioScope` annotation that sets the correct proxy mode. 3. Do some renaming of internal classes 4. Use a global counter for conversation ids Related - #1970 - #1667
The glue code context does not require an active scenario. As a result it was possible to create scenario scoped beans that would be shared (leak) between scenarios. An example of this is illustrated below. Because this does require access to the `GlueCodeScope` it is not possible to do this in practice. ```java @configuration public static class TestApplicationConfiguration { @bean public BeanFactoryPostProcessor beanFactoryPostProcessor(){ return factory -> factory.registerScope(SCOPE_CUCUMBER_GLUE, new GlueCodeScope()); } @bean public ExampleService service(ScenarioScopedApi api) { return new ExampleService(api); } @bean @scope(value = SCOPE_CUCUMBER_GLUE) public ScenarioScopedApi api() { return new ScenarioScopedApi(); } } ``` However without registering the the `GlueCodeScope` at start up Spring will complain about missing the cucumber-glue scope rather then complain about scope not having started or the missing proxy mode. So to avoid further confusion: 1. GlueCodeContext will check if the context has been started. 2. Add a `@ScenarioScope` annotation that sets the correct proxy mode. 3. Do some renaming of internal classes 4. Use a global counter for conversation ids Related - #1970 - #1667
Environmet:
io.cucumber:cucumber-spring:5.7.0
Actual: In my Spring Configuration I use Scope 'cucumber-glue' before its registration by
TestContextAdaptor#registerGlueCodeScope(org.springframework.context.ConfigurableApplicationContext)
.This scope registers after Spring Context loading on glue loading stage.
But I want use this Scope for my Spring-beans because this scope is allowed for me in
CucumberTestContext
And I cannot (in right way) register it manually because
GlueCodeScope
class has package-default visibility.Expected: Register this scope erlier
Caused by: java.lang.IllegalStateException: No Scope registered for scope name 'cucumber-glue'
The text was updated successfully, but these errors were encountered: