How to avoid class.forName() in OSGi?
I am relatively new to OSGi and our dept. is shifting to OSGi framework. I have two bundles A and B. B depends on A so I have included it in B's manifest file as Import-Package:A.
Also, I have a certain class in A which uses reflection to access a certain class from B. Class in A uses class.forName(class in B). I want to get rid of this reflection as thi开发者_JAVA百科s might cause problems when I shift to OSGi framework. How can I get rid of this class.forName()?
Thanks!!
In OSGi you will want to stay away from reflection, for reasons outlined in a lot of other places.
So, your situation is that bundle A
needs some instance of a class which resides in bundle B
. For A
to make sense of this instance, I will assume it has some interface that it will use to talk to the instance. Let's make this a little more concrete.
/Bundle A
/ThingyInterface.class
/Bundle B
/ThingyImplementation.class (implements ThingyInterface.class)
This is a regular pattern: one bundle provides an interface, the other provides the implemenatation. There are now two possible situations,
A
needs exactly one copy of the implementation. In that case, register theThingy
as a service.A
needs several instances of the implementation. In that case, introduce aThingyFactory
inA
, and create an implementation of that factory inB
, which you then register as a service.
In either case, you let B
do the actual instantiation, you have no dependency from A
to B
, and B
doesn't need reflection to instantiate the objects.
In short, services are your friend.
In my opinion, two ways to create objects in Java
- Call constructer by new
- use reflection
So if u want to avoid reflection, you can only import class in bundle A,then new() instance(In order to do this, u need imprt B in bundle A). But as bundle B alreadys depends on A, this will cause cross-dependence which isn't allowed in OSGi. So I suggest u refactor you class to extract such code from bundle A and move to bundle B.
I don't know your exact use case, but it sounds like you have some spaghetti in the making. You said that Bundle B depends on A, and yet A has to load a class from B via reflection. This means that A depends on B as well. Since you cannot have B -> A -> B, you need to remove one of the dependencies.
Or perhaps you need another bundle C, which contains whatever classes are common to both A and B. Remember that OSGi is there to help you create modules with clean interfaces. If you find you are having trouble making something work with OSGi, it is probably because some abstraction is leaking or some dependency has not been well designed.
精彩评论