BootstrappingEquinox

From APIDesign

(Difference between revisions)
Jump to: navigation, search
Current revision (14:54, 29 January 2011) (edit) (undo)
 
(4 intermediate revisions not shown.)
Line 1: Line 1:
-
Those of you who watch [[User:JaroslavTulach|my]] experiments with [[OSGi]], know that I [[NetbinoxPerformance|tweaked Equinox]] to create the fastest [[OSGi]] container - [[Netbinox]]. Things are looking good and [[Netbinox]] will work smoothly with [[NetBeans]] 6.9. There is however [https://netbeans.org/bugzilla/show_bug.cgi?id=180819 one issue] which revealed surprising truth: [[Equinox]] is not ready for modular environment!
+
Those of you who watch [[User:JaroslavTulach|my]] experiments with [[OSGi]], know that I [[NetbinoxPerformance|tweaked Equinox]] to create the fastest [[OSGi]] container - [[Netbinox]]. Things are looking good and [[Netbinox]] will work smoothly with [[NetBeans]] 6.9. There is however [https://netbeans.org/bugzilla/show_bug.cgi?id=180819 one issue] which revealed surprising truth: [[Equinox]] is not ready for modular environment! Unless you combine it with additional [[NetbinoxHook]]s.
-
The full story is available in [https://netbeans.org/bugzilla/show_bug.cgi?id=180819 the issue itself], but to make the long story short, here is a summary: The [[Equinox]] offers hooks for various extensions. For example for weaving the loaded classes via [[AspectJ]]. However (in spite [[OSGi]] being designed in modular way - e.g. everything loaded by separate class loaders), [[Equinox]] does not seem to be able to load the hook classes from other classloader than own! The problem seems to be in ''HookRegistry.java'':
+
The full story is available in [https://netbeans.org/bugzilla/show_bug.cgi?id=180819 the issue itself], but to make the long story short, here is a summary: The [[Equinox]] offers [[NetbinoxHook|hooks]] for various extensions. For example one can weave the loaded classes via [[AspectJ]]. However (in spite [[OSGi]] being designed in modular way - e.g. everything loaded by separate class loaders), [[Equinox]] does not seem to be able to load the hook classes from other [[ClassLoader]] than own! The problem seems to be in ''HookRegistry.java'':
<source lang="java">
<source lang="java">
Line 10: Line 10:
</source>
</source>
-
The use of Class.forName is the main blocker. It means only classes directly visible by the ''equinox.jar'' are accessible. This is not really suitable for [[modular system]] and implies that you basically need to load ''equinox.jar'' and [[AspectJ]] weaving [[JAR]] by the same classloader.
+
The use of Class.forName is the main blocker. It means only classes directly visible by the ''equinox.jar'' are accessible. This is not really suitable for [[modular system]] and implies that you basically need to load ''equinox.jar'' and [[AspectJ]] weaving [[JAR]] by the same [[ClassLoader]].
If the above code used classical
If the above code used classical
Line 17: Line 17:
clazz = Class.forName(hookName, true, l);
clazz = Class.forName(hookName, true, l);
</source>
</source>
-
then the loading succeeded even in case the [[AspectJ]] weaving module would be in its own [[JAR]] with dependency on the module providing ''equinox.jar''.
+
then the loading succeeded even in case the [[AspectJ]] weaving code would be in its own [[ClassLoader]] just with a [[dependency]] on the [[ClassLoader]] providing ''equinox.jar''.
-
Oh those [[BootstrappingEquinox|boostraping problems]]! Some core part of the system just can't be modular! At least it might seem they can't be modular, until somebody puts another bootstrapping code (in this case [[Netbinox]]) around your bootstrapping code (old good [[Equinox]]). Then all the modularity rules that you were used to apply to libraries loaded by your framework are suddenly being applied to your framework as well.
+
Oh those [[BootstrappingEquinox|boostraping problems]]! Some core part of the system just can't be modular! At least it might seem the code can't be modular, until somebody puts another bootstrapping code (in this case [[Netbinox]]) around your bootstrapping code (old good [[Equinox]]). Then all the modularity rules that you used to apply to libraries loaded by your framework are suddenly being applied to your framework as well.
I know the [[Equinox]] guys are well aware of the problem of adopting plain [[Java]] libraries to modular environment (I've noticed their [http://wiki.eclipse.org/Context_Class_Loader_Enhancements buddy classloading policy]). Such [[Java]] libraries usually assume flat classpath - e.g. they believe it is possible to load any class just by knowing its name. Only later, when somebody tries to use such libraries in a [[modular system]], the flaws of this approach appear. The fix is as simple as shown above. But the organizational issues! Someone has to apply the patch, then everyone has to wait for new release of the broken library. To make things even worse, sometimes one gets into long and useless discussions with authors of the libraries in question. They usually don't experienced modularity yet and don't understand what is wrong with their code.
I know the [[Equinox]] guys are well aware of the problem of adopting plain [[Java]] libraries to modular environment (I've noticed their [http://wiki.eclipse.org/Context_Class_Loader_Enhancements buddy classloading policy]). Such [[Java]] libraries usually assume flat classpath - e.g. they believe it is possible to load any class just by knowing its name. Only later, when somebody tries to use such libraries in a [[modular system]], the flaws of this approach appear. The fix is as simple as shown above. But the organizational issues! Someone has to apply the patch, then everyone has to wait for new release of the broken library. To make things even worse, sometimes one gets into long and useless discussions with authors of the libraries in question. They usually don't experienced modularity yet and don't understand what is wrong with their code.

Current revision

Those of you who watch my experiments with OSGi, know that I tweaked Equinox to create the fastest OSGi container - Netbinox. Things are looking good and Netbinox will work smoothly with NetBeans 6.9. There is however one issue which revealed surprising truth: Equinox is not ready for modular environment! Unless you combine it with additional NetbinoxHooks.

The full story is available in the issue itself, but to make the long story short, here is a summary: The Equinox offers hooks for various extensions. For example one can weave the loaded classes via AspectJ. However (in spite OSGi being designed in modular way - e.g. everything loaded by separate class loaders), Equinox does not seem to be able to load the hook classes from other ClassLoader than own! The problem seems to be in HookRegistry.java:

private void loadConfigurators(ArrayList configurators, ArrayList errors) {
  for (Iterator iHooks = configurators.iterator();iHooks.hasNext();) {
    String hookName = (String) iHooks.next();
    Class clazz = Class.forName(hookName);

The use of Class.forName is the main blocker. It means only classes directly visible by the equinox.jar are accessible. This is not really suitable for modular system and implies that you basically need to load equinox.jar and AspectJ weaving JAR by the same ClassLoader.

If the above code used classical

ClassLoader l = Thread.currentThread().getContextClassLoader();
clazz = Class.forName(hookName, true, l);

then the loading succeeded even in case the AspectJ weaving code would be in its own ClassLoader just with a dependency on the ClassLoader providing equinox.jar.

Oh those boostraping problems! Some core part of the system just can't be modular! At least it might seem the code can't be modular, until somebody puts another bootstrapping code (in this case Netbinox) around your bootstrapping code (old good Equinox). Then all the modularity rules that you used to apply to libraries loaded by your framework are suddenly being applied to your framework as well.

I know the Equinox guys are well aware of the problem of adopting plain Java libraries to modular environment (I've noticed their buddy classloading policy). Such Java libraries usually assume flat classpath - e.g. they believe it is possible to load any class just by knowing its name. Only later, when somebody tries to use such libraries in a modular system, the flaws of this approach appear. The fix is as simple as shown above. But the organizational issues! Someone has to apply the patch, then everyone has to wait for new release of the broken library. To make things even worse, sometimes one gets into long and useless discussions with authors of the libraries in question. They usually don't experienced modularity yet and don't understand what is wrong with their code.

I hope that no such social issues will happen in case of Equinox. I am sure Equinox maintainers understand modularity and will be willing to fix their code soon. The only thing surprises me: how could a modular framework make such mistake and be so unsuitable for modular execution?

<comments/>

Personal tools
buy