8 Replies Latest reply on Nov 19, 2009 11:23 AM by adrian.brock

    New features in classloading

      I've started committing some work on adding the missing OSGi features to jboss-cl.

      The first couple are complete:

      JBCL-127 - adds a notion of ClassNotFoundHandler. This allows a handler to intercept
      a dynamic classloading request and resolve (or even install - see below) the missing classes.

      JBCL-128 - adds some notifications. The most important of these is the class found
      notification used in the "lazy start" - see below.

      The others are still prototypes and need to properly integrated with the deployers/osgi
      As part of this, I've introduced the notion of a LifeCycle to the classloading Module.

      This allows us to invoke callbacks (when requested) on the Deployment or whatever
      is the component model for the classloader.

      JBCL-130 - lazy start - is a generalisation of lazy activation from osgi
      where a deployment can be left in the classloader stage until somebody loads
      a class from it

      JBCL-131 - lazy resolve - implements the osgi feature where a classloader is not
      even constructed unless someone "imports" one of its packages

      JBCL-132 - resolver - this is a general api that will allow things like OBR to be
      hooked it. But it could also be used to for example to download dependencies from
      a maven repository when they are requested.

      Part of the LifeCycle includes notification of ClassLoader create/destroy
      which was something missing in our OSGi Bundle resolve notifications.

        • 1. Re: New features in classloading

          I'm aware of a few other missing features in the classloading which I haven't yet
          raised JIRA issues for, although JIRA already exist for some.

          1) Allow optional imports on wildcards
          2) Allow dynamic imports on wildcards
          3) Permission checks to use Capabilities
          4) Allow fragments - i.e. additions to the "classpath" of a classloader
          5) Extension bundles - i.e. hot deployment (but not undeployment) into the "bootstrap classpath"
          6) Circular dependencies
          7) Split packages

          I think (4) would be better implemented in the deployers by allowing one deployment
          to dynamically become a subdeployment of another one. But this still requires
          a mechanism to augment the classpath roots in the VFSClassLoaderPolicy.

          • 2. Re: New features in classloading
            dmlloyd

            Do any of these changes have negative performance implications? For example it looked like the changes for JBCL-128 might introduce some significant overhead. Might be worth doing some before/after profiling just in case?

            • 3. Re: New features in classloading

               

              "david.lloyd@jboss.com" wrote:
              Do any of these changes have negative performance implications? For example it looked like the changes for JBCL-128 might introduce some significant overhead. Might be worth doing some before/after profiling just in case?


              It's only got extra overhead if you install a handler and then it depends upon what
              the handler does.

              I assume the one you are talking about is the ClassFoundHandler.

              The only additional processing for no handlers are a few list == null checks
              at the policy, domain and system levels.

              The use case we are going to implement is for the Lazy Activation feature in OSGi.

              In that case, you install a handler when you create the classloader, but then remove
              it once the first class is loaded. So there is only overhead for one classloading request
              and that is to implement the desired feature - i.e. start the services associated with
              deployment.

              • 4. Re: New features in classloading

                I should also note that the ClassFoundHandler is only invoked when it does
                defineClass()

                It is not invoked when you do loadClass() for a class that is already loaded.
                The latter being by far the bigger volume of requests.

                • 5. Re: New features in classloading
                  alesj

                   

                  "adrian@jboss.org" wrote:
                  I should also note that the ClassFoundHandler is only invoked when it does
                  defineClass()

                  Is the "// Missing?" piece intentional?
                  Or is this trying to get best match?

                  ClassLoaderDomain
                   public void classFound(ClassFoundEvent event)
                   {
                   ClassFoundHandler parent = null;
                   Loader parentLoader = getParent();
                   if (parentLoader instanceof ClassFoundHandler)
                   parent = (ClassFoundHandler) parentLoader;
                  
                   // Missing? Should there be some call to parent's classFound method?
                  
                   ClassLoaderPolicy parentPolicy = getClassLoaderPolicy(parentLoader);
                   if (parentPolicy != null)
                   parent = parentPolicy;
                  
                   if (parent != null)
                   parent.classFound(event);
                  


                  • 6. Re: New features in classloading

                    No, actually there's an else missing :-)
                    In all three routines.

                     if (parentLoader instanceof ClassNotFoundHandler)
                     parent = (ClassNotFoundHandler) parentLoader;
                    + else
                    + {
                     ClassLoaderPolicy parentPolicy = getClassLoaderPolicy(parentLoader);
                     if (parentPolicy != null)
                     parent = parentPolicy;
                    + }
                    


                    If we know the parent implements Class*Handler then the second part is
                    redundant.

                    The second part is there for if you put a ClassLoaderToLoaderAdapter as the parent
                    rather than a Domain, like it does for web-apps. Then you've got to do a bit of a dance
                    to get the parent's ClassNotFoundHandler.

                    adapter -> BaseClassLoader -> ClassLoaderPolicy

                    In practice it will always return null into the parentPolicy for a ClassLoaderDomain
                    which is why I didn't spot it in the testing.

                    • 7. Re: New features in classloading
                      alesj

                       

                      "adrian@jboss.org" wrote:

                      In all three routines.

                      I only found two - found and not-found.
                      Where's the third?

                      • 8. Re: New features in classloading

                         

                        "alesj" wrote:
                        "adrian@jboss.org" wrote:

                        In all three routines.

                        I only found two - found and not-found.
                        Where's the third?


                        No that's right. The ClassLoaderHandler only notifies the domain to which the
                        classloader was added/removed.