3 Replies Latest reply on May 29, 2008 11:09 AM by Adrian Brock

    ClassLoader for a subdeployment

    Adrian Brock Master

      One of the things left to do is the managed classloader for a subdeployment.

      This is so we can use the new classloader framework for the war classloader
      which would include having OSGi style imports for the isolated wars.

      The way I'm planning to do it, is that if a subdeployment has a ClassLoadingMetaData
      then it will trigger this processing.

      The subdeployment will become a classloading "Module" in its right,
      capable of importing dependencies that are different to the main classloader
      of the deployment.

      Also, its ClassPath will NOT be included in the main classloader classpath.

      For the war classloader I expect this to be triggered by a specific deployer
      that decides that wars should get their own classloader
      and what the default policy should be, e.g. excluded classes, parent first, etc.

      The are some gotchas:

      OLD LOADER REPOSITORY CONFIG

      Previously we only checked for subdeployment classloader config
      for a war (and then only if the useJBossClassloade was configured).
      e.g. a loader repository config in a jboss.xml of a nested ejb jar
      would be ignored.

      With this new feature, it wouldn't be ignored anymore and
      the nested ejb would get its own subclassloader.

      We can probably fix this in the "hack" that ignores it for non-wars
      or at least add a warning?

      PARENTS

      There are two ways to implement it, both have issues.

      1) Just create a classloader with the main deployment classloader as the parent.

      This may run into the circularity issue in the Sun Classloader,
      although, I haven't seen it myself with the Tomcat classloader doing this?

      2) With the new classloader we can create an hierarchical domain
      with the main deployment classloader as parent. This would allow us
      to "schedule" the classloading like we do for other hierarchical domains.

      But this means creating a domain for the subdeployment classloader (not a big issue),
      it's more ugly that the "parentDomain" in the metadata would be ignored since the parent
      is already defined to be the main deployment classloader.

      PROPOSAL

      I'm going to try to implement it as (2), since having a domain
      would also allow multiple copies of a dependency.

      e.g. two wars with servlet style classloading could OSGi style
      import apache clogging and we could let them have their own
      singletons/versions of the classes.

      i.e. for isolated classloading, the import would be a peer clasloader in the
      sub-deployment's constructed domain not visible to others.

      JOKE:

      WAR developers like to have their own singletons and other junk.
      Admins don't trust them and so like to give them their own sandbox. ;-)

        • 1. Re: ClassLoader for a subdeployment
          Adrian Brock Master

          I've implemented this, just like I described above.

          To make this useful as a Tomcat classloader, the current code that
          adds a ClassLoaderFactory would instead need to create ClassLoadingMetaData
          for the war subdeployments.
          This would also be the same deployer where we specify the default
          classloading rules for wars.

          • 2. Re: ClassLoader for a subdeployment
            Adrian Brock Master

            One usecase that came up is to able to explicitly create a top level
            classloader for a subdeployment rather than an isolated classloader
            hanging off the main deployment classloader.

            This could for example be signaled by the user explicitly specifying the
            classloader domain.

            We currently ignore the user specified domain when it is a subdeployment,
            since we have to construct a synthetic domain with the main
            deployment's classloader as parent.

            In this case, instead of constructing a synthetic domain
            we would just respect the user's decision and make
            the subdeployment classloader a top level classloader.

            e.g.
            top-level.jar/sub-deployment.jar/META-INF/jboss-classloading.xml

            <classloading domain="MyDomain" xmlns="urn:jboss:classloading:1.0"
             import-all="true" export-all="ALL">
            </classloading>
            


            This will currently create a classloader for top-level.jar
            (minus the classes in sub-deployment.jar) in the default domain
            then construct a synthetic "top-level.jar/sub-deployment.jar" domain.

            DefaultDomain <- top-level.jar <- synthetic domain <- sub-deployment.jar

            With the proposed change (explicit domain) it would instead look like this:

            DefaultDomain <- top-level.jar
            MyDomain <- sub-deployment.jar (now a top level classloader)

            NOTE: Ironically this would actually take us back to allowing something
            simiar to early jboss-3.0.x classloading rules where every subdeployment
            had its own classloader ;-)

            • 3. Re: ClassLoader for a subdeployment
              Adrian Brock Master

              I've done this change. It will need a jboss-deployers release to make it work.
              See the JIRA issue for how this works.

              It's a bit ugly though if you want to add your subdeployment classloader
              to the default domain since you've got to specify something like:

              <classloading domain="DefaultDomain" parentDomain="DefaultDomain"/>
              


              But if you're doing that I don't see why you would need a subdeployment classloader
              anyway ;-)