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

Feature request: Hot swap #267

Open
dtrunk90 opened this issue Jan 1, 2019 · 6 comments
Open

Feature request: Hot swap #267

dtrunk90 opened this issue Jan 1, 2019 · 6 comments

Comments

@dtrunk90
Copy link

dtrunk90 commented Jan 1, 2019

As discussed in #65 and #182 it would be nice to have a hot swap feature in order to replace plugins and let pf4j automagically stop and start/restart them.

The only project I know of which already has this feature and could be helpful to take a look into is Keycloak.

@decebals
Copy link
Member

decebals commented Jan 1, 2019

@dtrunk90
Thanks that you created a separate issue with this subject (hot swap).
Someone explained in a comment a possible scenario for hot swap/deployment in PF4J.
I explained in a comment that the true hot swap is hard to achieve.
I implemented this concept in one of my project (Pippo a micro Java web framework). See here the issue and here the PR with some details about implementation. The bottom line is that the hot swap/deployment was implemented in Pippo restarting the web server (for example Jetty, Tomcat, Undertow, ...) when something was changed in the Java sources directories of the project.
Why do you think that Eclipse, IDEA IntelliJ, Jenkins and other big applications (in Java) that are massively based on a concept like plugin/module/bundle, with a lot of resources in the back
resources (developers, money), require you a restart after you installed or updated a plugin/module?
Furthermore, the Eclipse plugin system is based on OSGI, a more respectable, enterprise module system that somehow should solve this problem. The response is that these applications cannot install, update or delete a plugin without a restart because they can not otherwise. Maybe they can do something, that in theory works, probably in the majority of cases will work as expected BUT after multiple modifications (install, update or delete plugins) the system becomes unpredictable (one of the effects might be the appearance of memory leaks). The same problem is (or at least was) with application servers (JBoss for example) and servlet containers (Jetty, Tomcat for example).

Sure, we can try together to see if we can find a solution. A simple implementation (POC) is to create a background task that checks the plugins directory for new, modified or removed plugins (zip or jar files). When a modification is detected then PF4J, by default, will use methods from PluginManager like loadPlugin startPlugin, stopPlugin, unloadPlugin or deletePlugin to add, update or delete plugin.

Below links can be useful:

@decebals
Copy link
Member

decebals commented Jan 1, 2019

@dtrunk90

The only project I know of which already has this feature and could be helpful to take a look into is
Keycloak.

Do you talk about this Keycloak? Does this project come with a plugin system (embedded or not)? I will take a look if you point me to the right page.

@dtrunk90
Copy link
Author

dtrunk90 commented Jan 1, 2019

Do you talk about this Keycloak? Does this project come with a plugin system (embedded or not)? I will take a look if you point me to the right page.

Yes, I'm talking about that Keycloak. The SPI is well documented here: https://www.keycloak.org/docs/latest/server_development/index.html#_providers

From Section 6.2.1:

If you copy your provider jar to the Keycloak standalone/deployments/ directory, your provider will automatically be deployed. Hot deployment works too.

I don't know if it's a Keycloak or WildFly feature.

@decebals
Copy link
Member

decebals commented Jan 2, 2019

I don't know if it's a Keycloak or WildFly feature.

It's a WildFly feature. In PF4J the complexity is high because you have plugin with dependencies. We will see.

Like a detail, Jose (@jgomer2001) succeeded with this approach.

@slovdahl
Copy link
Contributor

slovdahl commented May 28, 2021

A simple implementation (POC) is to create a background task that checks the plugins directory for new, modified or removed plugins (zip or jar files). When a modification is detected then PF4J, by default, will use methods from PluginManager like loadPlugin startPlugin, stopPlugin, unloadPlugin or deletePlugin to add, update or delete plugin.

We have implemented something like this and used it for about 5 years already (using version 0.12.0). Until now we have not used dependencies between modules, but that has now become relevant.

When a plugin that is depended on by other plugins is reloaded, PF4J automatically stops and unloads the plugins that depend on the plugin being reloaded. This is all fine, but when the plugin is loaded and started again after that, we would like to automatically start the plugin that depend on the one being updated and that were loaded and running before the update. This is where I think PF4J could provide a little bit more help. It's possible to determine which plugins an update will unload and stop before it's done by using the protected DependencyResolver dependencyResolver field from AbstractPluginManager, and manually load and start those afterwards. I'm not sure how to do it though. In an ideal world, PF4J would be able to automagically handle it the same way it stops and unloads dependent plugins, but that would require it to keep track of intermediate state.

Has anyone else had or solved the same kind of problem?

@fendo8888
Copy link

https://github.com/dcevm/dcevm Based on whether this can be achieved?

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

No branches or pull requests

4 participants