1 Reply Latest reply on Mar 6, 2008 11:26 AM by Adrian Brock

    DeploymentClassLoader as a bean

    Adrian Brock Master

      The way this was implemented was completely wrong:

      <deployment>
       <classloader><bean ...></classloader>
      </deployment>
      


      I spent forever trying to figure out how it worked at all,
      looking through all the metadata visitor stuff. It turned out it wasn't there
      at all!

      It was in the xml parsing which means manual deployment doesn't have the feature!!!!

      Besides that:

      ClassLoaderMetaData had been made into a BeanMetaDataFactory
      which is meaningless. How can a classloader be made up of multiple beans
      which one do you use as the classloader? :-)

      I've implemented this "properly", but it is a bit hacky
      (mainly to automagically avoid common mistakes ;-)

      When the deployer asks the deployment for the beans it now adds
      the classloader. And also makes sure it can't use itself as its own classloader
       public List<BeanMetaData> getBeans()
       {
       List<BeanMetaData> result = new ArrayList<BeanMetaData>();
      
       // Include the classloader if it is a bean
       ClassLoaderMetaData classLoaderMetaData = getClassLoader();
       if (classLoaderMetaData != null)
       {
       ValueMetaData classLoader = classLoaderMetaData.getClassLoader();
       if (classLoader instanceof BeanMetaData)
       {
       // Hack, if it doesn't have a classloader use the "null" classloader
       // we don't want it to gain itself as the classloader
       BeanMetaData classLoaderBean = (BeanMetaData) classLoader;
       if (classLoaderBean.getClassLoader() == null)
       classLoaderBean.setClassLoader(new AbstractClassLoaderMetaData(new AbstractValueMetaData()));
       result.add((BeanMetaData) classLoader);
       }
       }
      
       List<BeanMetaDataFactory> factories = getBeanFactories();
      
       if (factories != null && factories.isEmpty() == false)
      


      Then in the part where the deployment/bean are checked for classloader
      AbstractKernelDeployer::deploybean()
      I replace the bean with an injection if it is coming from a deployment classloader
      confiigured as a bean.
       ClassLoaderMetaData deploymentClassLoader = deployment.getClassLoader();
       if (deploymentClassLoader != null)
       {
       // If the deployment classloader is a bean, replace it with an injection
       ValueMetaData classLoader = deploymentClassLoader.getClassLoader();
       if (classLoader instanceof BeanMetaData)
       {
       classLoader = new AbstractDependencyValueMetaData(((BeanMetaData) classLoader).getName());
       beanClassLoader = new AbstractClassLoaderMetaData(classLoader);
       }
       else
       {
       beanClassLoader = deploymentClassLoader;
       }
       bean.setClassLoader(beanClassLoader);
       }
      


      AbstractClassLoaderMetaData is no longer a BeanMetaDataFactory
      (implying multiple beans) and xml parsing no longer contains
      logic that should never have been there.

        • 1. Re: DeploymentClassLoader as a bean
          Adrian Brock Master

           

          "adrian@jboss.org" wrote:

          Then in the part where the deployment/bean are checked for classloader
          AbstractKernelDeployer::deploybean()


          While I am on this subject.

          I originally put all the deployment defaults in this method, but other
          defaults have been added in the AbstractKernelDeployment::getBeans().

          I think the AbstractKernelDeployment is the correct place for this code,
          so we should look at moving all the logic that is AbstractKernelDeployer::deployBean()
          into there.

          Especially since the AbstractKernelDeployer is not always used,
          e.g. the BeanMetaDeployer in the deployers project.