Community
Participate
Working Groups
One problem we have discovered with the Eclipse 2.1 classloader structure is that it creates the root of the classloader tree with a parent of 'null' so that the plugin class loaders will not look in the application class loader (who's namespace is defined by -cp ) when it is mostly looking for plugin classes. This, I understand, is a performance optimization. Unfortunately, there is a rather bad side effect of this. Because the way this is done simply 'preempts' the parent search right before it would go to the application class loader, they also end up preempting search of the _extensions_ class loader! This has turned into a major problem for us because this disables the Java 1.2+ standard extensions behavior. The java extensions spec : http://java.sun.com/j2se/1.3/docs/guide/extensions/index.html requires that jars placed into the jre/lib/ext/ directory be treated as part of the JRE. This is important because this allows one to drop in 'javax' packages into, say a 1.3.1 JRE and bring up the APIs to match 1.4.1 in an incremental way. In particular some of the java security features (SSE, JAAS & crypto, for example) are not part of the standard 1.3.1 distribution. In order for these features to be added - and this is a requirement for our team - we need to be able to use the Java Extension mechanism. Personally, I am not convinced that the performance gain from skipping a search of the application class loader is really all that significant. Parents should only be searched the first time a class is located and the search domain for the application class loader is tiny (normally it only contains startup.jar). Normally, the proper thing to do before applying a spec changing optimization (which is what this is) is to do measurements. Has anybody actually done measurements? Giving the benefit of the doubt to this optimization of ignoring the application class loader, nevertheless it is incorrect behavior to skip the extensions class loader. In the current eclipse 2.1 code, the offending line of code that causes the problem is in org.eclipse.platform/src/org/eclipse/core/launcher/Main.java : public Class getBootLoader(URL[] path) throws Exception { URLClassLoader loader = new URLClassLoader(path, null); return loader.loadClass(BOOTLOADER); } The correct thing to do is change that to assign the extensions class loader (which is the parent of the app class loader) as the parent. A simple-minded fix would be to change it to: public Class getBootLoader(URL[] path) throws Exception { URLClassLoader loader = new URLClassLoader(path, ClassLoader.getSystemClassLoader().getParent()); return loader.loadClass(BOOTLOADER); } This fixes the behavior so far, from what we can tell so far. However, I suspect that a more rigorous thing to do would be to walk the chain and assign the last non-null class loader as the parent: public Class getBootLoader(URL[] path) throws Exception { ClassLoader cl = ClassLoader.getSystemClassLoader(); ClassLoader parent = cl.getParent(); while(parent!=null){ cl=parent; parent=cl.getParent(); } //last non-null classloader should be the java ExtLoader URLClassLoader loader = new URLClassLoader(path, cl); return loader.loadClass(BOOTLOADER); } This should protect against the case where a particular JRE implementation returns a grandchild rather than a direct child of the EXT loader for the getSystemClassLoader() call. While my comments here address the Eclipse 2.1 codebase in hopes that this can be fixed in Eclipse 2.1.2, I believe ths problem persists in the Eclipse HEAD branch today as well and needs to be addressed in Eclipse 3.0.
This has been considered before: bug 30919.
This is a duplicate. Note that this wasn't done as an optimization. Plugins/Bundles in Eclipse define their namespaces individually using a manifest file. A "global" namespace mechanism like the extension mechanism can be very problematic in a system built on a loosely-coupled federation of independent plugins/bundles. A JAR added to "ext" to support plugin "A" can break plugin "B" that has conflicting namespace requirements. You can add the libraries you need by bundling them in a plugin and adding them to your plug-ins "requires" list. *** This bug has been marked as a duplicate of 30919 ***
This actually is not so much of a performance issue as on of maintaining the Eclipse component model. Eclipse works because the various plugins have to identify the other function on which they rely. Relying on function which may or may not be there in the JVM or on the classpath is problematic. This kind of code is not version managed, is not updatable and, when loaded this way, does not support multiple implementations concurrently. The choice to use null parentage in Eclipse has been there since the beginning in an attempt to support the above characteristics. An example of where the suggested approach would go wrong can be seen in our current problems with the JDK 1.4 support for endorsed libraries. Endorsed libs are basically part of the boot classpath (not sure if there is another classloader for them). As such, classloaders with null parents still see endorsed libs from the VM. The major endorsed lib currently is the JAXP XML parser stuff. This directly conflicts with the Eclipse Xerces plugin function. Further, some VMs include Xerces as their implementation but that version is different from the one provided with Eclipse. It would be fine if the one in the VM was a complete cover for the one in the Xerces plugin but that is not the case and you end up with non-functioning XML parsing. So currently Elcipse works on some 1.4 VMs and not others. Alternaitves for extensions are to add plugins containing the relevant function and then setup the plugin requirements accordingly. Alternatives for endorsed libs have been considered and basically amount to allowing plugins to state a preference to override/replace classes found in the system classloader. This is techically possible but needs to be worked through. Side note: OSGi RFP44 contains an item which deals with this.
I would like to disagree with the resolution of WONTFIX for bug#30919 and advocate that this bug be reopened and addressed for Eclipse 2.1.2. I think the vulnerability to classpath polution from someone dropping a jar like Xerces into the ext/ directory is overstated. An eclipse-based application deployment simply shouldn't make such an obvious mistake in general. It is important to note that technically one can STILL perform such a corruption even now by using -XBootClasspath. In a sense, this is analogous to the problem you say is arrising on use of some 1.4 VMs and not others. It is not the purpose in general of the Java Extension mechanism to add such application-layer jars such as xerces. The main purpose of the Ext mechanism is to provide for modifications at the JRE level. This mechanism is necessary in order to add certain behavior to the JRE, especially in the security area. Ultimately, I guess this comes down to whether one is going to design away a whole major realm of functionality in order to avoid the possibility of someone dropping an incompatible xml jar in. If you make the change I advocate, I predict that the impact on existing deployments should be negligible because, given the current behavior, it is unlikely any existing deployments are even including extension jars in their jre/lib/ext/. And if they are, it is unlikely that they are including one that actually going to be in conflict with a jar included in a plugin downstream. This bug is a critical block for work that our team is doing. We would like to see it addressed for 2.1.2, even if with a switch at the command-line such as '-enablejreext'.
It seems like a switch would be useful and could be added without effecting existing users. In general, I concur with Pascal, that isolating plugins from random files in the extension's directory is a good thing. This is especially true if the required .jar files could have been included in a plugin. However, there are use cases, where .jar files are required to be on the system classpath and can not be provided in a plugin. One of the cases Mel is worried about is using a 1.3 JRE and JAAS. His only alternative is to use - Xboothclasspath with a long list of jar files.
*** This bug has been marked as a duplicate of 30919 ***