Summary: | Plugins don't have access to the extension class loader | ||
---|---|---|---|
Product: | [Eclipse Project] Equinox | Reporter: | John Arthorne <john.arthorne> |
Component: | Incubator | Assignee: | User Unknown <unknown1> |
Status: | RESOLVED FIXED | QA Contact: | |
Severity: | enhancement | ||
Priority: | P3 | CC: | eclipse, francis, hiradha, jean-philippe.moresmau, jeffmcaffer, melm, pascal, rayellis, Richard_Wilson, selsemore, xavier.mehaut |
Version: | unspecified | ||
Target Milestone: | 3.0 M9 | ||
Hardware: | PC | ||
OS: | Windows 2000 | ||
Whiteboard: |
Description
John Arthorne
2003-02-04 18:08:38 EST
For now, closing bugs not planned for 2.1. Will reopen after 2.1 release. Reopening *** Bug 24837 has been marked as a duplicate of this bug. *** Closing. The Equinox runtime will supply its own classloaders, and we likely won't have control over whether "ext" is visible. I don't actually see a compelling reason to change this. Adding "ext" to the classpath would pollute the carefully controlled plugin namespace with extra global libraries. *** Bug 44470 has been marked as a duplicate of this bug. *** This is being discussed in the context of OSGi: bug 42531. picking up comments from pr#44470 and pr#42531 The compelling reason to address this issue is that some security packages need to be loaded either by the boot loader or the ext loader in order to work correctly. In order to develop an application with security in mind from top to bottom, we need to be able to do this. It seems to me a reasonable compromise would be to allow the choice to be made when launching the platform with a command-line option. The obvious choices for what the parent loader should be could easily be accounted for like so: * [default], set parent to 'null', equivalent to using boot loader as parent * -enablejreext , set parent to 'ClassLoader.getSystemClassLoader().getParent()' * -enablejreapp , set parent to 'ClassLoader.getSystemCLassLoader()' The default behavior would be unmodified, yet this would provide application assemblers who are in need of more control over the JRE used to do so. *** Bug 44470 has been marked as a duplicate of this bug. *** A command line switch sounds like a reasonable compromise. Is the classloader structure tightly spec'd somewhere? That is, are we guaranteed that ClassLoader.getSystemClassLoader().getParent() is the extension classloader? And do we think this will change in the future? That's a very good question, Jeff. My interpretation, after much pouring over what specs I can find and understand, is that 'no', there is not hard statement that the getSystemClassLoader().getParent() returns the extension classloader, although it probably is true 99.999% of the time. However, we can look at the following things that are spec'ed. According to spec: 1) getSystemClassLoader() ... [returns] "the default delegation parent for new ClassLoader instances, and is typically the class loader used to start the application" 2) loadClass() ... "If the class has already been loaded then just return it. Otherwise, try loading the class from the parent class loader (or virtual machine's built-in class loader, called the bootstrap class loader, if no parent was specified)." Key point here is that the 'null' classloader corresponds to the bootstrap loader. 3) "Classes for installed optional packages are shared by all code in the same virtual machine. Thus, installed optional packages are similar to the platform's core classes (in rt.jar), but with an associated class loader ..." These three statements tell us a) that installed Java extensions must be loaded by an associated classloader - NOT the bootstrap class loader. b) that installed java extension classes must be available to the entire virtual machine - for those two things to happen they must be loaded by the first non-null classloader child of the bootstrap loader. So, to my thinking, the more likely safe way to get the extensions loader is to walk the getParent() ladder and use the last non-null classloader found. Not planned for 2.1.2, but leaving open for now. Extending this topic a bit: Should the Context Classloader be left as the app (system) classloader? Current behavior is that plugin code executes in a thread who's context classloader (Thread.getCurrentThread().getContextClassLoader()) is the system (application) classloader. Is this expected / desired behavior? I would say yes to 'expected' since I'm not aware of any point where eclipse explicitly sets the context classloader. I'm not sure about 'desired'. This seems to run counter to the philosophy of isolating plugins from the application classloader. Or maybe not. Thoughts? It's a good point. The default context class loader should probably be either the primordial loader or the boot class loader. However, this isn't something we'll be likely to change in a service release and the 3.0 runtime has a different classloader implementation. Jeff, it would be worth checking if the Equinox runtime class loaders do anything with the context class loader. *** Bug 48808 has been marked as a duplicate of this bug. *** Very much a friend of bug 3074. Moving to Equinox *** Bug 54921 has been marked as a duplicate of this bug. *** *** Bug 3074 has been marked as a duplicate of this bug. *** *** Bug 45726 has been marked as a duplicate of this bug. *** This has been fixed a couple of days ago by the addition of a system property. Here is a repost of Tom's message: The following values are supported for the Java property osgi.parentClassloader: "app" - the application classloader "ext" - the extension classloader "boot" - the boot classloader "fwk" - the framework's classloader The default is to use the boot classloader. I specified a "fwk" option because as far as I know most all other implementations of the OSGi framework actually default to using the classloader of the framework as the parent of all the bundle classloaders. I wanted to at least give us the option to allow for this if needed. *** Bug 88467 has been marked as a duplicate of this bug. *** I realize this is a very old bug, but I think the answer to my problem might be here somewhere, if I understood OSGi class loading well enough figure out exactly where. In my plugin, I need to use a class (SunPKCS11) from the sun.security.pkcs11 package. Can anybody help? What is it that I have to do to apply this solution in order to get the class to load? Thanks! Steve |