Repository navigation
support optional plugin dependencies #266
Description
Under certain situations it might be very helpful to support optional dependencies between plugins. For example the following scenario is currently pretty difficult to realize with pf4j:
One plugin adds contact management and the other plugin adds calendar functionality to an application. Both plugins provide a form to modify contacts / calendar entries, that can be extended by other plugins through the ContactsFormExtensionPoint / CalendarFormExtensionPoint.
Let's assume, that the contacts plugin adds a panel to the calendar form, that shows assigned contacts for a certain calendar entry. On the other hand the calendar plugin adds a panel to the contacts form, that shows assigned calendar entries for a certain contact.
In this case, both plugins would depend on each other. I would have to define these dependencies in their META-INF/MANIFEST.MF accordingly.
But what happens, if one of the plugins is missing, because the application user might not have installed it? - Currently pf4j wouldn't load the contacts plugin, if the calendar plugin is missing and vice versa (due to the defined dependencies in META-INF/MANIFEST.MF). But in this case, the contacts plugin should still be usable - even if the calendar plugin is not present.
With the current version of pf4j I only see one solution for this problem. I would have to remove the dependencies between the plugins and have to create a separate plugin, that provides the com.example.plugins.contacts.addons package. This additional plugin would only be loaded, if contacts and calendar plugin are present.
This might be an acceptable solution for small application. But if we think a little bit bigger, this approach might lead to a huge number of plugins only to reflect those inner plugin dependencies.
- Four application plugins would require six additional plugins to reflect all possible inner plugin dependencies.
- Six application plugins would require fifteen additional plugins to reflect all possible inner plugin dependencies.
- Or in general: A number of n application plugins would require n * (n-1) / 2 additional plugins to reflect all possible inner plugin dependencies.
I hope my math is right. ;) - But even if the formula is wrong, it should show, that this possible workaround can lead to a big mess on more complex applications with a bigger number of plugins.
But how did others solve this problem? - For example JPF solved this problem by allowing optional plugin dependencies. I think, this would also be the most elegant solution for pf4j.
According to the example above: The contacts plugin could define an optional dependency to the calendar plugin (and vice versa). If the calendar plugin is not present, the contacts plugin is still available for the application - only the CalendarContactsFormExtension is not loaded (because it requires the calendar plugin to be available).
What do you think about all this? - Do you also see this as a problem or am I missing something?
From my point of view the suggested feature would be a big improvement for pf4j, that could also be helpful for others. I'm currently implementing these optional dependencies. There is still some testing and fixing to do, therefore I can't provide source code yet. But are you generally interested in a pull request for this feature?
If not, I would have to fork the project and maintain the modified source code for myself because my application heavily relies on this. I'm hoping to get a positive response, because I would rather support your project instead of forking and maintaining it for myself.

Activity
decebals commentedon Dec 28, 2018
The feature seems to be valuable, so we can add it.
As hints to implementation this geature:
isOptionalin PluginDescriptor.We can use sign
?to the end of string to specify that a dependency is optional, likeMaybe is necessary extra work, we can discuss.
pinhead84 commentedon Dec 28, 2018
Thanks for your quick and positive response.
I was thinking the same and already did that in my local / testing implementation. But currently I put the question mark behind the plugin name instead of the version number, like
But if you prefer
over
I will change my implementation accordingly.
I also did that in my local / testing implementation.
The modifications are basically working quite well within my application. But there are still some class loading issues to solve.
According to my example above, there is currently a
NoClassDefFoundErrorthrown for theContactsCalendarFormExtension, if the calendar plugin is not available. I was thinking about this problem for the last few days. I believe, that I found a good solution for it. But it needs some more testing on my side before I can provide a pull request. You will hear from me about it in the next few days.decebals commentedon Dec 28, 2018
I think that is a detail where to put
?sign. Maybe as first character is better 😄.pinhead84 commentedon Jan 3, 2019
As basis for discussion I've published pull request #270 with my current implementation of optional plugin dependencies.
pinhead84 commentedon Jan 5, 2019
@decebals
In one of our current discussions you've asked, how other plugin frameworks have solved this issue. I've already referred to JPF, which uses a similar solution to my pull request #270.
But out of curiosity I took a look into the documentation of IntelliJ, Netbeans & OSGi about how they are approaching this issue:
IntelliJ
According to this XML configuration plugins can have optional dependencies on each other:
Also an extension may explicitly define, on which other plugin it depends:
It looks to me, that IntelliJ goes similar ways like JPF or as it is proposed in my pull request.
Netbeans
It seems, that the Netbeans module framework does not support optional plugin dependencies. According to their documentation, they are solving this issue by separate plugins to reflect inner plugin dependencies:
This approach leads to the problems, I've pointed out earlier:
Therefore I don't really like the Netbeans approach to this problem. But maybe I've missed something...
OSGi / Eclipse
As far as I know, the Eclipse plugin framework is more or less based on OSGi. Therefore I'm looking at OSGi instead.
According to this tutorial optional plugin dependencies are support by OSGi:
Something similar is documented for Eclipse plugins and other OSGi based solutions.
OSGi is quite complex and I did not fully understand all of their concepts. But it looks to me, that it also provides solutions to check plugin requirements of certain extension - e.g. with a custom
BundleActivatoror by overridingBundle#loadClass(java.lang.String).As far as I understand, OSGi also wouldn't force the developer to create separate plugins to reflect inner plugin dependencies (like Netbeans or PF4J currently does).
My personal conclusion about this: Two of three comparable solutions to PF4J are addressing optional plugin dependencies. I guess those requirements are not as rare, as one might think. ;)
decebals commentedon Jan 5, 2019
@pinhead84
Thanks for your excellent research work!
pinhead84 commentedon Jan 11, 2019
Thank you for merging the pull request. I believe, this is a quite a big improvement and makes PF4J even greater.
If you like, I would provide a documentation for #265 and #270. I guess, that I can create a pull request in your pf4j.github.io repository for that?
decebals commentedon Jan 11, 2019
Even please. Optional plugins is your nice contribution, so you must close the circle :) Thanks!
decebals commentedon Jan 11, 2019
I uploaded a new SNAPSHOT version that is up to date.
pinhead84 commentedon Jan 13, 2019
I'll send you some pull requests for the pf4j.github.io repository in the next one or two weeks. Currently I'm quite busy with the migration of my application to Java 11. Therefore documentation may take some time.
That's good to know. Do you have any plans about a new release in the next few weeks? - Or do you prefer to wait until the documentation was updated?
decebals commentedon Jan 14, 2019
It would be nice to have a minimum documentation (maybe copy/paste from PR) until you have time to add a more complete documentation.
decebals commentedon Jan 14, 2019
I updated SNAPSHOT version again. Please use this version in your project until release a new version. The idea is to test as much as possible, in a real environment, the new version.
pinhead84 commentedon Jan 30, 2019
You should find a pull request with the some additions to the manual.
I've still not released my application with the modifications on PF4J to the public. I guess it will take 1-2 weeks until the changes can be tested on a wider user base. But up to know I did not find any problems during my local tests.
decebals commentedon Jan 31, 2019
@pinhead84
Now that documentation was improved (thanks for your contribution), and the new concepts are documented, I think that we can release a new version. If something is wrong (you isolated well enough the new features, to not impact the old features if the new features are not used) we can release instantly a new bug fix version.
pinhead84 commentedon Feb 1, 2019
Thank you for being open about my proposals. I appreciate the effort you've put into PF4J and that my pull requests are critically questioned. From my point of view PF4J is well designed, easy to learn and deserves more attention. It's a great and straightforward alternative to bloated solutions like OSGI. Keep up the great work!
With the last changes PF4J is more or less feature complete for my personal use case. Therefore I guess you won't get any bigger proposals by me in the future. But of course I'll continue to look out for bugs and possible bugfixes. ;)
decebals commentedon Feb 1, 2019
Thank you for your contribution and for your patience!
PF4J is a community driven project so if anybody has a great idea (easy or difficult to implement) I will accept that idea with pleasure.
decebals commentedon Feb 2, 2019
New version (2.6.0) released.
Can we close this issue?
pinhead84 commentedon Feb 2, 2019
I'm happy to see the new version being released.
Yes. I'll close this issue if you don't mind.