Application.getComponent(Class) and multiple Class objects for the same class

I'm working on a plugin which has two components, a public API (Java module) and
a private implementation (Plugin module). The plugin module depends on the Java
module. I have a third plugin which uses the API, so it depends on the Java module.

The plugin module has an ApplicationComponent which has an interface-class which
is an interface in the Java module, and an implementation-class which is in the
plugin module.

When I call Application.getComponent(TheInterfaceClass.class), it returns null.
However, in the debugger, when I call Application.getComponentInterfaces(), I
see TheInterfaceClass in the list. Also, calling Application.getComponent("The
component name"), it returns the correct component.

It looks like the problem is that they're two different instantiations of the
same class. When I call getComponent(TheInterfaceClass.class), it doesn't find
anything because it's a different Class object than the one stored in Application.

My question is, is this desired behavior, or is there some workaround?

Thanks,
-Keith

4 comments

Did you have interface-class defined for both components in plugin.xml?

0

Keith, do I understand you correctly that you have one interface class and exactly one
implementation class in another plugin, or are there multiple implementation classes?

If there's only one implementation class, this sounds like a packaging problem. I suspect
your API classes (TheInterfaceClass, etc.) are packaged with both plugins, which is
incorrect because you'll indeed end up with two different versions of the interface class
as you already noticed. The interface from plugin-1 is not compatible with the one from
plugin-2 because they're loaded by different classloaders.

You should package the API classes only with plugin-1 - the classes are available to the
dependent plugin as well. Unfortunately, I don't know of a convenient way to set up the
DevKit in such a way. See my comment in http://www.jetbrains.net/jira/browse/IDEA-3692

Sascha

Keith Lea wrote:

I'm working on a plugin which has two components, a public API (Java
module) and a private implementation (Plugin module). The plugin module
depends on the Java module. I have a third plugin which uses the API, so
it depends on the Java module.

The plugin module has an ApplicationComponent which has an
interface-class which is an interface in the Java module, and an
implementation-class which is in the plugin module.

When I call Application.getComponent(TheInterfaceClass.class), it
returns null. However, in the debugger, when I call
Application.getComponentInterfaces(), I see TheInterfaceClass in the
list. Also, calling Application.getComponent("The component name"), it
returns the correct component.

It looks like the problem is that they're two different instantiations
of the same class. When I call getComponent(TheInterfaceClass.class), it
doesn't find anything because it's a different Class object than the one
stored in Application.

My question is, is this desired behavior, or is there some workaround?

Thanks,
-Keith

0

Sascha Weinreuter wrote:

Keith, do I understand you correctly that you have one interface class and exactly one
implementation class in another plugin, or are there multiple implementation classes?

If there's only one implementation class, this sounds like a packaging problem. I suspect
your API classes (TheInterfaceClass, etc.) are packaged with both plugins, which is
incorrect because you'll indeed end up with two different versions of the interface class
as you already noticed. The interface from plugin-1 is not compatible with the one from
plugin-2 because they're loaded by different classloaders.

You should package the API classes only with plugin-1 - the classes are available to the
dependent plugin as well. Unfortunately, I don't know of a convenient way to set up the
DevKit in such a way. See my comment in http://www.jetbrains.net/jira/browse/IDEA-3692


I don't know how to set the devkit that way at all. Do you mean I should delete
the API classes jar from plugin-2 when deploying? I'll try that.

0

Keith Lea wrote:

I don't know how to set the devkit that way at all. Do you mean I should
delete the API classes jar from plugin-2 when deploying? I'll try that.


Yep, that's what I'd suggest. I've never bothered to set up the devkit that way after I
realized that it's not simple. It may be well possible that there's no way at all.

Sascha

0

Please sign in to leave a comment.