Plugin module dependencies

I'd like to have plugin A depend on plugin B and essentially share the same class loader.  Is there a way to declare that level of cooperation between plugins?  I haven't found anything of the sort and can't configure the dependent plugin to share modules with its dependency.  Basically the problem is that plugin A depends on some of the same modules as plugin B.  Here's a simplified illustration:

img.png

It's vital that classes from Module 2 share the same loader regardless of the enclosing plugin. So, again, I'd like to somehow declare that Plugin A extend Plugin B, so that they live in the same loader. Note the unfortunate reality is that both Module 1 and Module 2 involve several modules in a gnarly dependency graph (read, they can't be factored out).

The only "solution" I've come up with, since we own both plugins, is to make Plugin A and Plugin B just regular modules and support only one plugin at a time.  As such the actual plugin modules are just wrappers where the wrapper for plugin A is a merge of the features of both plugins.  Sigh.

5 comments
Comment actions Permalink

Hello Scott,

There is no way to have two plugins use exactly the same classloader. If
you declare a dependency between plugins using the 'depends' tag in plugin.xml,
the classloader of Plugin B will use the classloader of Plugin A as a parent,
which will hopefully be good enough for you.

I'd like to have plugin A depend on plugin B and essentially share the
same class loader.  Is there a way to declare that level of
cooperation between plugins?  I haven't found anything of the sort and
can't configure the dependent plugin to share modules with its
dependency.  Basically the problem is that plugin A depends on some of
the same modules as plugin B.  Here's a simplified illustration:

Image:img.png It's vital that classes from Module 2 share the same
loader regardless of the enclosing plugin. So, again, I'd like to
somehow declare that Plugin A extend Plugin B, so that they live in
the same loader. Note the unfortunate reality is that both Module 1
and Module 2 involve several modules in a gnarly dependency graph
(read, they can't be factored out).

The only "solution" I've come up with, since we own both plugins, is
to make Plugin A and Plugin B just regular modules and support only
one plugin at a time.  As such the actual plugin modules are just
wrappers where the wrapper for plugin A is a merge of the features of
both plugins.  Sigh.


--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"


0
Comment actions Permalink

Thanks Dmitry.  Unfortunately it won't.  The fundemental problem is that both plugins have module dependencies in common, but the nature of plugin classloading (as I understand it) is such that if a module is reachable via the plugin's own loader it will load from there and not delegate to the parent loader.  It seems this behavior would have negative implications beyond my own use-case.  For instance, if Plugin A uses the API of Plugin B and both A and B use class Foo from Module 1, Plugin A could call B's API passing an instance of Foo that is from A's loader, not B's -- boom.

I'm thinking of playing with the module scope settings.  I may try using the Provided scope and manually modify the runtime packaging for diffierent use-cases.  Anything I should know about module scoping as it relates to module/plugin dependencies?  Failing that I suppose I'm forced to merge plugins etc.   Oh well, I'm happy to do that considering I'm not writing plugins for Eclipse :-)

0
Comment actions Permalink

Hello Scott,

I think it should work well enough if you specify Module 1 as a provided
dependency for Plugin B. I'm actually not sure if the plugin build process
in the IDE handles provided dependencies correctly (by not packaging them
into the plugin .zip), but if it doesn't, it's a bug.

Thanks Dmitry.  Unfortunately it won't.  The fundemental problem is
that both plugins have module dependencies in common, but the nature
of plugin classloading (as I understand it) is such that if a module
is reachable via the plugin's own loader it will load from there and
not delegate to the parent loader.  It seems this behavior would have
negative implications beyond my own use-case.  For instance, if Plugin
A uses the API of Plugin B and both A and B use class Foo from Module
1, Plugin A could call B's API passing an instance of Foo that is from
A's loader, not B's -- boom.

I'm thinking of playing with the module scope settings.  I may try
using the Provided scope and manually modify the runtime packaging for
diffierent use-cases.  Anything I should know about module scoping as
it relates to module/plugin dependencies?  Failing that I suppose I'm
forced to merge plugins etc.   Oh well, I'm happy to do that
considering I'm not writing plugins for Eclipse :)


--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"


0
Comment actions Permalink

Seems you were right in suspecting a bug in the plugin build process -- the classes from a Provided module are indeed packaged in the jar, which renders the Provided scope pretty much equivalent to the Compiled scope.  Back to square one for me.  Thanks for your help.

0
Comment actions Permalink

Hello Scott,

I've filed IDEA-71000 for this problem.

Seems you were right in suspecting a bug in the plugin build process
-- the classes from a Provided module are indeed packaged in the jar,
which renders the Provided scope pretty much equivalent to the
Compiled scope.  Back to square one for me.  Thanks for your help.

---
Original message URL:
http://devnet.jetbrains.net/message/5306420#5306420


--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"


0

Please sign in to leave a comment.