Skip to content
New issue

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

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

Already on GitHub? # 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?

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants