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

Problems with Extension and Scopes #4

Closed
hnrkdmsk opened this issue Dec 5, 2017 · 13 comments
Closed

Problems with Extension and Scopes #4

hnrkdmsk opened this issue Dec 5, 2017 · 13 comments

Comments

@hnrkdmsk
Copy link

hnrkdmsk commented Dec 5, 2017

Hey,
I want to extend an class that needs a other scope then the singleton. How can I specify the bean scope for the @Extension annotated class?

I want to use your library with Spring and Vaadin 8. All works fine! But now I want to test to get SpringView annotated classes loaded out of the plugin. And there I have problems with the scopes of the bean that will be created by your library. The SpringView cannot be a singleton.

Is there any option to set the singleton explicitly?

Greetings!

@decebals
Copy link
Member

decebals commented Dec 5, 2017

I don't use Spring in my projects so I don't use this PF4J's extension (pf4j-spring).
This project is very tiny and easy to hack. All the business is available in two classes: SpringExtensionFactory and ExtensionsInjector.
My idea is to add a new annotation (for example @SpringScope) on class annotated with @extension. In this mode if you have the class (name) of extension you can read the value from @SpringScope.
All you need to do is to modify SpringExtensionFactory or ExtensionsInjector and to use the scope value when register the extension as Spring's bean.

Make sense for you?

@hnrkdmsk
Copy link
Author

hnrkdmsk commented Dec 5, 2017

You mean something like this?

protected void registerExtension(Object extension, BeanDefinitionRegistry beanDefinitionRegistry) {
        BeanDefinitionBuilder definitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(extension.getClass())
            .setScope(extension.getClass().getAnnotation(SomeSpringScopeAnnotation.class).value()) // here make use of the new added annotation e.g. @springscope
            .addPropertyReference("propertyName", extension.getClass().getName())
            .addPropertyValue("propertyValue", extension);
        beanDefinitionRegistry.registerBeanDefinition(extension.getClass().getName(), definitionBuilder.getBeanDefinition());
}

There I have edit the ExtensionsInjector. I don't tested it yet and don't know if this work, but it can be an idea for it. The biggest change would be the switch from the SingleBeanRegistry to BeanDefinitionRegistry.

@PostConstruct
public void injectExtensions(BeanDefinitionRegistry beanDefinitionRegistry) {
...
}

@decebals
Copy link
Member

decebals commented Dec 5, 2017

Yes. Something like this.

@decebals
Copy link
Member

decebals commented Dec 5, 2017

What it's not clear for me is the comment from 1139d13#comments that says that

PostConstruct cannot work with parameters of the method

Can you validate this affirmation. Did you able to run the demo without problem?

The modification with ExtensionsInjector.injectExtensions(SingletonBeanRegistry beanRegistry) is an attempt to solve #3.

Thanks!

@decebals
Copy link
Member

decebals commented Dec 5, 2017

I see that exists org.springframework.context.annotation.Scope. It's an idea to use this annotation.

@hnrkdmsk
Copy link
Author

hnrkdmsk commented Dec 5, 2017

org.springframework.context.annotation.Scope would be great for this!

I can get it running, but not fully. The application context of the plugin is not resolved anymore. But with my fix, the scope will be set right.

protected void registerExtension(Object extension, BeanDefinitionRegistry beanDefinitionRegistry) {
        BeanDefinitionBuilder definitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(extension.getClass())
            .addPropertyReference("propertyName", extension.getClass().getName())
            .addPropertyValue("propertyValue", extension);

        if (extension.getClass().isAnnotationPresent(ExtensionSpringScope.class)) {
            String scope = extension.getClass().getAnnotation(ExtensionSpringScope.class).value();
            log.info("Registering {} with scope: {}", extension.getClass().getName(), scope);
            definitionBuilder.setScope(scope);
        }

        beanDefinitionRegistry.registerBeanDefinition(extension.getClass().getName(), definitionBuilder.getBeanDefinition());
    }

What I had to change was the @PostConstruct method.

@Autowired
    private ApplicationContext applicationContext;

    public ExtensionsInjector(PluginManager pluginManager) {
        this.pluginManager = pluginManager;
    }

    @PostConstruct
    public void injectExtensions() {
      BeanDefinitionRegistry beanDefinitionRegistry = (BeanDefinitionRegistry) applicationContext.getAutowireCapableBeanFactory();
...}

The post construct method don't allow parameters anymore. I don't checked if this has a relation to my changes. But now I don't get my beans from the plugin loaded... Can you check it?

@decebals
Copy link
Member

decebals commented Dec 5, 2017

Can you fork the project (via GitHub), add your modifications to pippo-spring and give me the link?

@hnrkdmsk
Copy link
Author

hnrkdmsk commented Dec 5, 2017

@decebals
Copy link
Member

decebals commented Dec 6, 2017

@loefflefarn
I made some modifications on master to organize better the code and to prepare things for Scope implementation.
I created a new branch "scope" that contains all modifications. I added scope "prototype" on one of extension from demo and it works. I will create a PR to have the possibility to review the code and add comments.

@hnrkdmsk
Copy link
Author

hnrkdmsk commented Dec 6, 2017

Nice, okay. I will check it tomorow in my application and will give you feedback! Thanks a lot for you help.

@hnrkdmsk
Copy link
Author

hnrkdmsk commented Dec 7, 2017

The scopes are now setted right but they cannot resolve there beans from the plugin. You can test it, if you set the scope to prototype in the demo application-plugin2.

@decebals
Copy link
Member

decebals commented Dec 7, 2017

@loefflefarn
I explained yesterday in some comments of PR #6 why this problem appear.

@hnrkdmsk
Copy link
Author

hnrkdmsk commented Dec 7, 2017

Ah, yes. Okay, I will look around for a possible solution to help you with it. I've tested around with this, but nothing has work fine.

@hnrkdmsk hnrkdmsk closed this as completed Feb 7, 2022
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

No branches or pull requests

2 participants