<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body text="#000000" bgcolor="#ffffff">
    On 04/12/2010 20:37, Michael Anstis wrote:
    <blockquote
      cite="mid:AANLkTi=T+7AbLs6YwKf+y9rsrk0+F9ATTd35_W00z-DE@mail.gmail.com"
      type="cite">It'd be great to learn a little more about Drools'
      class loading strategy; where it's come from and where it is now.<br>
      <br>
      Can anyone explain more about Drools class loading? I can guess
      the RETE network needs to know how to load classes declared in
      rules; however this no doubt is the tip of an iceberg.<br>
    </blockquote>
    Initially the user would pass a classloader which would be the
    "parent" classloader that Drools would use for any classloaders it
    created. Drools would create a classloader to be able to dynamically
    load byte[] classes at runtime and we would have one of those per
    package namespace:<br>
    &nbsp;&nbsp;&nbsp; public static class ByteArrayClassLoader extends ClassLoader {<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public ByteArrayClassLoader(final ClassLoader parent) {<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super( parent );<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
    <br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Class&lt; ? &gt; defineClass(final String name,<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; final byte[] bytes,<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; final ProtectionDomain domain)
    {<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return defineClass( name,<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bytes,<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0,<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bytes.length,<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; domain );<br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
    &nbsp;&nbsp;&nbsp; }<br>
    <br>
    This way the user could also have custom classloaders with classes
    not in the classpath.<br>
    <br>
    The problem then came that there was not resolving across packages,
    a type declaration or function in one package could not be resolved
    in another package. Thats because the current classloader, as shown
    above would only resolve against itself and the parent.<br>
    <br>
    We then changed to a Composite ClassLoader. In this we subvert
    normal classloader behaviour by over-riding the loadClass method.
    ALL classloading should be via this "root" composite classloader.
    The composite has an array ClassLoaders and any class loading now
    resolves across the entire array. This means that one package can
    now resolve against another. It also means we can add multiple
    external classloaders, as needed by OSGi. Notice we pass null to the
    super() now, as we never search the parent.<br>
    <br>
    We further added some classloader caching to help address
    performance issues for people tha have particularly large class
    paths.<br>
    <br>
<a class="moz-txt-link-freetext" href="http://fisheye.jboss.org/browse/JBossRules/trunk/drools-api/src/main/java/org/drools/util/CompositeClassLoader.java?r=HEAD">http://fisheye.jboss.org/browse/JBossRules/trunk/drools-api/src/main/java/org/drools/util/CompositeClassLoader.java?r=HEAD</a><br>
    <br>
    There is a ClassLoaderUtils class that is used to construct the
    composite classloaders and this dictates the ordering, notice it's
    in reverse order as it's LIFO priority.<br>
    <br>
<a class="moz-txt-link-freetext" href="http://fisheye.jboss.org/browse/JBossRules/trunk/drools-api/src/main/java/org/drools/util/ClassLoaderUtil.java?r=HEAD">http://fisheye.jboss.org/browse/JBossRules/trunk/drools-api/src/main/java/org/drools/util/ClassLoaderUtil.java?r=HEAD</a><br>
    <br>
    There's a bit more history to it than that, but it gives you the
    gist. For a while we ended up having two parallel composite
    implementations, one for the root and one for the internal dynamic
    stuff, so it was a it messy for a while.<br>
    <br>
    Mark<br>
    <blockquote
      cite="mid:AANLkTi=T+7AbLs6YwKf+y9rsrk0+F9ATTd35_W00z-DE@mail.gmail.com"
      type="cite">
      <br>
      Thanks,<br>
      <br>
      Mike<br>
      <br>
      <div class="gmail_quote">On 4 December 2010 04:53, Mark Proctor <span
          dir="ltr">&lt;<a moz-do-not-send="true"
            href="mailto:mproctor@codehaus.org">mproctor@codehaus.org</a>&gt;</span>
        wrote:<br>
        <blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt
          0.8ex; border-left: 1px solid rgb(204, 204, 204);
          padding-left: 1ex;">
          I have done more cleaning up in the ClassLoader stuff.<br>
          <br>
          While we added a root CompositeClassLoader recently there was
          still<br>
          another alternative composite ClassLoader implementation that
          was used<br>
          by the Packages. So we ended up with a composite CL being
          added to<br>
          another CL. Both composites had their own caching etc.<br>
          <br>
          So now we have &nbsp;single CompositeClassLoader, with a single
          point of<br>
          caching and slightly improve coding at detecting Drools
          specific CLs. My<br>
          hope is that the code is also more efficient.<br>
          <br>
          This work was done due to another OSGi requirement where each
          module<br>
          needs to add itself to the root classloader. But sometimes it
          was<br>
          returning the root CL, or sometimes the package level
          composite CL. So<br>
          now there is only one and that should no longer happen.<br>
          <br>
          What this means is that any module that will have it's classes
          resolved<br>
          via reflection from other modules should in their constructor
          or other<br>
          initialisation of the code do something like<br>
          getRootClassLoader().addClassLoader(
          getClass().getClassLoader() ). In<br>
          situations where it's a single container all modules have the
          same<br>
          classloader and the call gets ignored, as it won't re-added an
          existing<br>
          CL. In the OSGi case it'll add the classloader and now classes
          from that<br>
          module can be resolved in an OSGi environment.<br>
          <br>
          Mark<br>
          <br>
          _______________________________________________<br>
          rules-dev mailing list<br>
          <a moz-do-not-send="true"
            href="mailto:rules-dev@lists.jboss.org">rules-dev@lists.jboss.org</a><br>
          <a moz-do-not-send="true"
            href="https://lists.jboss.org/mailman/listinfo/rules-dev"
            target="_blank">https://lists.jboss.org/mailman/listinfo/rules-dev</a><br>
        </blockquote>
      </div>
      <br>
      <pre wrap="">
<fieldset class="mimeAttachmentHeader"></fieldset>
_______________________________________________
rules-dev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:rules-dev@lists.jboss.org">rules-dev@lists.jboss.org</a>
<a class="moz-txt-link-freetext" href="https://lists.jboss.org/mailman/listinfo/rules-dev">https://lists.jboss.org/mailman/listinfo/rules-dev</a>
</pre>
    </blockquote>
    <br>
  </body>
</html>