4 Replies Latest reply on Jun 10, 2008 12:09 PM by sguilhen

    Register dynamic class loading with a domain

    sguilhen

      We've been facing test failures in the CTS interop web vehicles related to loading the stub classes used in the tests.

      The ejb container succeeds at loading the stub classes because it uses the WebCL that generates these stubs on the fly. So, we've considered using a similar approach in the web container to get the stubs loaded - this logic is already available in the WebAppClassLoader but the logs show that this class loader is not being used in the tests scenarios.

      I first wanted to just enforce the use of this class loader again, but Scott thinks a more general solution is needed:


      The ejb container to dynamic class loader behavior is very specific to the class loader in use. We should come up with a more general solution based on the new class loading domains so that any component can register its dynamic class loading with a domain.


      As Adrian said, we can always include the stub classes in the vehicles war deployments to have the tests passing, but it would be good to have a more general solution in place.

        • 1. Re: Register dynamic class loading with a domain

          There's some issues with this proposal.

          1) The domain wouldn't be a very easy place (administratively) to register this behavour.
          ClassLoading Domains are created dynamically as required.
          A better place to register a "ClassNotFoundHandler" would be on the ClassLoading System.
          This is where AOP registers its Transformer when running in its old legacy mode.

          2) The way the IIOP WebCL processing is done now is incorrect in my opinion.
          If you are going to generate a stub then it should be defined against the same
          classloader as the interface. Otherwise you'll get memory leaks.
          This will effectively require a double lookup, once to determine there
          is no stub class and a second one to find the interface.

          e.g. with the current ejb stub generation, each ejb jar gets its own
          WebCL and each will generate its own copy of the stub (not visible to
          other applications and potentially leaking the interface reference
          if things don't get redeployed properly).

          3) The way the classloaders currently work is that they first check
          for the class resource existing.
          i.e. It effectively does a
          ClassLoader.getResource("com/acme/Whatever_Stub.class")
          before going onto the other classloading processing (which requires a lot of
          complicated dancing around because of the Sun classloader problems).
          If the resource doesn't exist, the classloader is not considered/used.

          • 2. Re: Register dynamic class loading with a domain

             

            "sguilhen@redhat.com" wrote:

            As Adrian said, we can always include the stub classes in the vehicles war deployments to have the tests passing, but it would be good to have a more general solution in place.


            Another solution would be to write a new stub deployer that either

            * Takes a list of interfaces to generate stubs for
            (could be the interfaces defined on the ejb-refs in the ejb-jar/web.xml)
            * Scans the deployment for Remote classes and generates them automatically.

            The generated bytecode could then be placed in the in memory vfs that is available
            for each classloader used by aop.
            http://viewvc.jboss.org/cgi-bin/viewvc.cgi/jbossas/projects/jboss-deployers/trunk/deployers-vfs/src/main/org/jboss/deployers/vfs/plugins/classloader/InMemoryClassesDeployer.java?revision=72346&view=markup

            This doesn't require any change to the classloader, such as the complicated
            multiple pass, and the resource does exist in the in-memory vfs context.

            • 3. Re: Register dynamic class loading with a domain

               

              "adrian@jboss.org" wrote:

              2) The way the IIOP WebCL processing is done now is incorrect in my opinion.
              ...
              3) The way the classloaders currently work is that they first check
              for the class resource existing.


              The simplest way to do this (similar to how it works now) is pretty ugly.
              i.e. Something like:
              public Class<?> loadClass(...)
              {
               Class<?> result = current classloading code
               if (result == null)
               result = runClassNotFoundHandlers(this, ...);
               if (result == null)
               throw ClassNotFoundException(...);
               return result;
              }
              


              It's ugly in that you've got to allow the ClassNotFoundHandler
              to say, I'm defining this class against a different classloader so don't invoke
              defineClass() yourself.

              The protocol/api that lets it do that, would potentially be a major security hole,
              it would certainly be open to abuse. :-)

              The alternative is a lot more complicated since the ClassNotFoundHandler
              would probably have to take part in the class search and caching algorithms
              (general solution).

              • 4. Re: Register dynamic class loading with a domain
                sguilhen

                The more we discuss about this the more convinced I become that we should just include the stubs in the war deployments.

                First because if you want your component to be a client of an IIOP application you should provide the stubs that will allow your component to make the IIOP calls. I don't see why you would rely on the app server runtime to provide those for you.

                Second because of the possibility of abuse that you have just described. I don't think we should include a hack to allow the generation of stubs when someone forgets to add those stubs to the deployments.

                When we act as a client, stubs should either be pre-compiled and inserted in the deployment war file or downloaded from a location specified in the IOR (when the server makes such mechanism available). As the RI doesn't make stubs available for download, the only other way left for us is to include the pre-compiled stubs in the vehicles war files. At least this is what I think.

                If this makes sense, we should review the way stubs are generated in the ejb container.