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

pf4j-spring compatibility with Spring Boot #37

Open
Vikcen opened this issue Oct 10, 2019 · 13 comments
Open

pf4j-spring compatibility with Spring Boot #37

Vikcen opened this issue Oct 10, 2019 · 13 comments

Comments

@Vikcen
Copy link

Vikcen commented Oct 10, 2019

Hello, i hope i can get some help.

I have tested successfully in my Spring Boot web application, loading plugins and getting my extensions from the plugin packaged in a jar like in your documentation shows in this way:

FileSystem sistemaFicheros = FileSystems.getDefault();
	   
PluginManager pluginManager = new SpringPluginManager(sistemaFicheros.getPath("/home/vbravo/Escritorio/plugins"));
pluginManager.loadPlugins();
	
List<Converter> converters = pluginManager.getExtensions(Converter.class);
for (Converter zipToPdfConversion : converters) {
    zipToPdfConversion.getConversionType();
}

But i don't see any example of loading this plugin via @Autowired (in Spring Boot) like you say in the documentation:

Ready, your extension is available in your application via PluginManager or Spring Autowire.

I don't understand very well what you mean exactly with Autowired, Do you mean i could load the plugin in this way as attribute of a class in a Spring Boot context?

@Autowired
Converter zipToPdfConversion;

Where Converter zipToPdfConversion is implemented in the same form of your documentation:

public class HelloPlugin extends SpringPlugin {

    public HelloPlugin(PluginWrapper wrapper) {
        super(wrapper);
    }

    @Override
    public void start() {
        System.out.println("HelloPlugin.start()");
    }

    @Override
    public void stop() {
        System.out.println("HelloPlugin.stop()");
        super.stop(); // to close applicationContext
    }

    @Override
    protected ApplicationContext createApplicationContext() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.setClassLoader(getWrapper().getPluginClassLoader());
        applicationContext.register(SpringConfiguration.class);
        applicationContext.refresh();

        return applicationContext;
    }

    @Extension
    public static class HelloGreeting implements Greeting {

        @Autowired
        private MessageProvider messageProvider;

        @Override
        public String getGreeting() {
//            return "Hello";
            // complicate a little bit the code
           return messageProvider.getMessage();
        }

    }

}

Can you show me some example to see how to do that Autowired of a plugin class (extending SpringPlugin) thru Spring Boot?

The idea is to load the plugin without package the plugin in a jar, i have just the plugin in the source code. I want the two ways, load from a jar and load without packaged in jar (is this possible?).

Thank you, greetings.

@decebals
Copy link
Member

But i don't see any example of loading this plugin via @Autowired (in Spring Boot) like you say in the documentation

https://github.com/pf4j/pf4j-spring/blob/master/demo/app/src/main/java/org/pf4j/demo/Greetings.java#L30

@Vikcen
Copy link
Author

Vikcen commented Oct 14, 2019

Hello, thanks for answering.

I mean an example of use of this structure public class HelloPlugin extends SpringPlugin written in your example.

How/where i should obtain/instantiate the SpringPlugin in the spring boot application? (i dont see it in the demo)

Greetings.

@decebals
Copy link
Member

I don't understand your question, and what you are looking for. Take a look at demo application to see a concrete example. They are some examples/projects available on internet.

How/where i should obtain/instantiate the SpringPlugin in the spring boot application? (i dont see it in the demo)

You don't need to obtain/instantiate the SpringPlugin. You need to obtain only the extensions in your application. A concrete (Spring) plugin is instantiated internally by PF4J. PF4J-Spring is a simple adapter of PF4J for Spring applications.

@Vikcen
Copy link
Author

Vikcen commented Oct 14, 2019

So, if i do something like this, i will obtain that HelloPlugin implementation?

PluginManager pluginManager = new SpringPluginManager();
List<PluginWrapper> helloplugins = pluginManager.getPlugins();

Or how can i access to this HelloPlugin?

@decebals
Copy link
Member

decebals commented Oct 15, 2019

So, if i do something like this, i will obtain that HelloPlugin implementation?

SpringPlugin plugin = (SpringPlugin) pluginManager.whichPlugin(MyService.class);

where MyService is a class from your plugin.

You can also try with PluginManager#getPlugin(String pluginId) or PluginManager#getStartedPlugins. The result is a PluginWrapper, but you can continue with PluginWrapper#getPlugin to retrieve the concrete plugin instance.

@decebals
Copy link
Member

After I read again the description of the issue I want too add more clarifications:

Can you show me some example to see how to do that Autowired of a plugin class (extending SpringPlugin) thru Spring Boot?

You cannot. In documentation Autowired is used only to inject extensions.

The idea is to load the plugin without package the plugin in a jar, i have just the plugin in the source code. I want the two ways, load from a jar and load without packaged in jar (is this possible?).

Yes. I use this approach in my projects (but I don't use Spring). I run my application in development from my IDE (IntelliJ). In this mode (development) my application together with all the plugins looks like a regular multi module application.
In production (deployment mode in PF4J - it's the default) I packages the plugins in JARs.

@Vikcen
Copy link
Author

Vikcen commented Oct 15, 2019

So, if i do something like this, i will obtain that HelloPlugin implementation?

SpringPlugin plugin = (SpringPlugin) pluginManager.whichPlugin(MyService.class);

where MyService is a class from your plugin.

You can also try with PluginManager#getPlugin(String pluginId) or PluginManager#getStartedPlugins. The result is a PluginWrapper, but you can continue with PluginWrapper#getPlugin to retrieve the concrete plugin instance.

That is not correct, it is:

PluginWrapper plugin = pluginManager.whichPlugin(HelloPlugin.class);

But that doesn't work, it returns null (or with getPlugin also returns null). Debugging it, within the class AbstractPluginManager the map plugins is always empty:

/**
     * A map of plugins this manager is responsible for (the key is the 'pluginId').
     */
    protected Map<String, PluginWrapper> plugins;

So, it is returning always null.

Remember, im testing it without package it in a jar, the plugin (that HelloPlugin referenced in your documetantion) is just in source code of my main app.

@decebals
Copy link
Member

Debugging it, within the class AbstractPluginManager the map plugins is always empty

My advice for you is to start with quickstart or/and Spring demo.
Did you started your application in development mode? Are you sure?

I'm sorry but I cannot help you with more information.

@Vikcen
Copy link
Author

Vikcen commented Oct 16, 2019

I have the project in GitLab, could i share with you? and then you can test it and see what things are wrong or not compatible? the main app is Spring boot (last version)

@decebals
Copy link
Member

OK. Please share the project maybe I have some time to take a look.

@Vikcen
Copy link
Author

Vikcen commented Oct 17, 2019

Could you give me permissions to push a new branch (issue/37) , i have cloned this:
https://github.com/pf4j/pf4j-spring.git

Vikcen pushed a commit to Vikcen/pf4j-spring that referenced this issue Oct 18, 2019
@Vikcen
Copy link
Author

Vikcen commented Oct 23, 2019

I did a push to master. For running the test:

  • For building project pf4j-spring-boot-demo:
    - 1) mvn clean install -Pmain-build
    - 2) mvn clean install -Pjar-client-build
    Then build project pf4j-spring-boot-demo-jar-plugins:
    - 3) mvn clean install

  • For running the demo test, run the spring boot app: org.pf4j.demo.boot.MainApp in pf4j-spring-boot-demo project.

I hope this can help.

@decebals
Copy link
Member

@Vikcen What is the status of this issue? Can we close it?

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