1 2 3 Previous Next 40 Replies Latest reply on Jan 21, 2006 7:25 AM by adrian.brock

    Change DomainClassLoader getPackages signature

    starksm64

      The current org.jboss.classloading.spi.DomainClassLoader defines a Set getPackages() method that conflicts with the Package[] getPackages() defined by java.lang.ClassLoader. Can this be renamed to getPackageNames() to allow DomainClassLoader implementations to subclass java.lang.ClassLoader?

        • 1. Re: Change DomainClassLoader getPackages signature

          This whole package was a prototype that should be redone elsewhere.
          http://docs.jboss.org/nightly/microkernel/docs/reference/en/html/classloading.html
          The only thing that uses it are the tests.

          • 2. Re: Change DomainClassLoader getPackages signature
            starksm64

            Ok, I'm tyring to integrate a vfs prototype into a head snapshot to validate what is required in terms of an interface/abstraction and will update the current signatures.

            Where should the class loading and vfs layer live in terms of modules/kernel level?

            • 3. Re: Change DomainClassLoader getPackages signature

              All the kernel needs is a mechanism for a bean to depend on the package
              after the describe stage.

              I prototyped it with the a simple

              <demand>
              with the classloading domain
              being a kernel registry plugin supplying package names. (See demand/supply in the docs/schema).
              class AbstractClassLoadingDomain extends JBossObject implements ClassLoadingDomain, KernelRegistryPlugin
              

              This prototype doesn't really work if there are two domains with the same package
              names, since the metadata has no notion of classloading context.

              I plan to improve it to automatically retrieve package names from the configuration
              and allow for better control of the classloading context and installation.

              NOTE: This is probably off-topic for this discussion since these are more
              about better control and refinement than a real requirement for the classloading
              implementation per se.

              1) Create a more abstract notion of "install" phase of the controller lifecycle
              rather than assuming it just means add to the kernel registry.

              I don't have a task for this in the JIRA roadmap but it is in the discussions
              and on the original design document.
              This generalises to "relationship" type installation
              <bean name="ClassLoader">
               <install bean="ClassLoaderDomain" install="add" uninstall="remove"/>
              </bean>
              


              2) ClassLoader injection into the metadata
              http://jira.jboss.com/jira/browse/JBMICROCONT-27
              <bean name="Bean">
               <constructor classloader="ClassLoader"/>
              </bean>
              

              which gives it the necessary context for more complicated deployment topologies.
              Currently it just uses whatever is the context classloader of the installer, e.g.
              inside JBoss4 it is the bean deployment's classloader.

              • 4. Re: Change DomainClassLoader getPackages signature

                Now that that part of the roadmap is out of the way, all the classloading impl
                needs to do is supply what packages are available.
                The KernelRegistryPlugin will do for now.

                Another thing on my road map is to create a better abstraction of DependencyItem
                such that people can "write their own dependencies".
                Once this is done, the classloading dependency would obviously be better done
                using a specifically targetted DependencyItem implementation.

                • 5. Re: Change DomainClassLoader getPackages signature

                   

                  "adrian@jboss.org" wrote:
                  Another thing on my road map is to create a better abstraction of DependencyItem
                  such that people can "write their own dependencies".
                  Once this is done, the classloading dependency would obviously be better done
                  using a specifically targetted DependencyItem implementation.


                  Which can still be done without the abstraction, but requires changes to the internal
                  PreprocessMetaDataVisitor

                  • 6. Re: Change DomainClassLoader getPackages signature
                    starksm64

                    Ok, I'll go through that, but a question that comes up is replacement of the existing class loader and URL/File usage in the system module which is where I was starting. Do we want to be expanding the mc functionality and then replacing the existing system functionality with mc based versions or are we expecting to update the system to use mc features as they come on line?

                    • 7. Re: Change DomainClassLoader getPackages signature

                      The plan is to integrate the ServiceController/KernelController.
                      http://jira.jboss.com/jira/browse/JBAS-1841

                      There is already a prototype and test of cross model dependency in the "dependency"
                      cvs module with each model having its own ControllerContext. (e.g. KernelControllerContext, MBeanControllerContext).
                      http://anoncvs.forge.jboss.com/viewrep/JBoss/jboss-dependency/src/tests/org/jboss/test/dependency/controller/test/CrossContextDependencyTestCase.java

                      Besides giving a single dependency space, the old SAR/MBean deployments
                      will gain Microcontainer features like classloading/instantiation dependency, on-demand, pojo/property injection, etc.

                      The eventual plan is to phase out the old MBean deployments to replace them
                      with POJO deployments annotated to be registered as MBeans - the decorators
                      I mentioned on the other thread.
                      But this obviously can't be done immediately with so much user code depending
                      on the MBean deployments.

                      • 8. Re: Change DomainClassLoader getPackages signature
                        starksm64

                        Ok, I'm going to work with the kernel module to move the vfs/class loading prototype forward then.

                        • 9. Re: Change DomainClassLoader getPackages signature

                          Don't implement the VFSClassLoader in the kernel module. :-)

                          I want the kernel thirdparty dependencies to be a light as possible.
                          e.g. The kernel could just use URLClassLoaders.

                          I don't even allow AOP dependency in there!

                          If there needs to be some contract for adding the package dependencies
                          this should be done through an optional interface
                          (probably defined in the increasingly misnamed container module? :-)
                          with the implementation elsewhere.

                          • 10. Re: Change DomainClassLoader getPackages signature
                            starksm64

                            Well, URLClassLoader is too heavy of a dependency as I don't want a requirement to have to subclass this. I don't see that there is any actual use of this api currently in kernel.

                            I'll start with the container module then and once I get to the point of actually deploying something loaded from a vfs mount point come back with issues.

                            • 11. Re: Change DomainClassLoader getPackages signature

                               

                              "scott.stark@jboss.org" wrote:
                              Well, URLClassLoader is too heavy of a dependency


                              I'm not saying you should use it or that the microcontainer should use URLClassLoader.
                              The MC just wants a ClassLoader that *might* implement the contract.

                              I meant somebody else could adapt the URLClassLoader or some other classloader
                              for their own use of the Microcontainer.

                              • 12. Re: Change DomainClassLoader getPackages signature
                                starksm64

                                So after going through how the class loader could be added to the ConstructorMetaData, it seems that this is too low a level for this info in general. A class loader is needed when the BeanInfo is created from BeanMetaData, and for this bean/deployment from a vfs test, its the KernelDeployment or BeanMetaData that have to have the class loader info depending on whether the entire deployment or just beans have to be loaded from the vfs.

                                In terms of a testcase showing the object model construction of two beans VFSBean1, VFSBean2 that are loaded via a VFSClassLoader visible to the kernel class loader this looks like:

                                 public void constructorClassLoader() throws Throwable
                                 {
                                 AbstractBeanMetaData metaData0 = new AbstractBeanMetaData("VFSClassLoader",
                                 "org.jboss.test.classloading.vfs.VFSClassLoader");
                                 AbstractConstructorMetaData clCMD = new AbstractConstructorMetaData();
                                 URL[] arg = {new URL("file:/cvs/JBossHead/jboss-head/kernel/output/classes-tests")};
                                 AbstractParameterMetaData urls = new AbstractParameterMetaData(
                                 arg.getClass().getName(), arg);
                                 ArrayList constructor0 = new ArrayList();
                                 constructor0.add(urls);
                                 clCMD.setParameters(constructor0);
                                 clCMD.setFactoryClass("org.jboss.test.classloading.vfs.VFSClassLoaderFactory");
                                 clCMD.setFactoryMethod("newClassLoader");
                                 metaData0.setConstructor(clCMD);
                                
                                 AbstractDependencyValueMetaData vfsCL = new AbstractDependencyValueMetaData("VFSClassLoader");
                                
                                 String bean1Type = "org.jboss.test.kernel.dependency.classloader.SimpleBeanImpl";
                                 AbstractBeanMetaData metaData1 = new AbstractBeanMetaData("VFSBean1", bean1Type);
                                 HashSet attributes1 = new HashSet();
                                 attributes1.add(new AbstractPropertyMetaData("string", "String1"));
                                 metaData1.setProperties(attributes1);
                                 metaData1.setClassLoader(vfsCL);
                                
                                 AbstractBeanMetaData metaData2 = new AbstractBeanMetaData("VFSBean2",
                                 "org.jboss.test.kernel.dependency.classloader.SimpleBeanWithConstructorClassLoaderImpl");
                                 HashSet attributes2 = new HashSet();
                                 attributes2.add(new AbstractPropertyMetaData("string", "String2"));
                                 metaData2.setProperties(attributes2);
                                 metaData2.setClassLoader(vfsCL);
                                 ArrayList constructor2 = new ArrayList();
                                 String bean1Iface = "org.jboss.test.kernel.dependency.classloader.SimpleBean";
                                 AbstractDependencyValueMetaData bean2Depends = new AbstractDependencyValueMetaData("VFSBean1");
                                 AbstractParameterMetaData param = new AbstractParameterMetaData(bean1Iface, bean2Depends);
                                 constructor2.add(param);
                                 AbstractConstructorMetaData cmd = new AbstractConstructorMetaData();
                                 metaData2.setConstructor(cmd);
                                 cmd.setParameters(constructor2);
                                
                                 setBeanMetaDatas(new BeanMetaData[] { metaData0, metaData1, metaData2 });
                                 }
                                


                                In terms of updating the xml deployment layer, is this something that should wait for the schema driven version or are we keeping the BeanSchemaBinding around?


                                • 13. Re: Change DomainClassLoader getPackages signature
                                  starksm64

                                  Changes for the addition of the class loader metadata to the BeanMetaData have been committed to head and the testcase is org.jboss.test.kernel.dependency.test.ConstructorClassLoaderTestCase.

                                  I have not made any changes to the xml deployment layer.

                                  • 14. Re: Change DomainClassLoader getPackages signature

                                    Ok.

                                    INTUITION:

                                    The classloader obviously belongs to the bean, but the constructor
                                    seemed the most intuitve place to express it?

                                    Possibility 1:

                                    <bean classloader="blah"/>
                                    


                                    Possiblity 2:
                                    <bean>
                                     <classloader bean="blah"/>
                                    </bean>
                                    


                                    Possiblity 3:
                                    <bean>
                                     <contructor classloader="blah"/>
                                    </bean>
                                    


                                    Possiblity 4:
                                    <bean>
                                     <contructor>
                                     <classloader bean="blah"/>
                                     </constructor>
                                    </bean>
                                    


                                    DEPENDENCY EXPRESSIONS:

                                    I don't like (1) and (3) because it doesn't allow POJO classloaders. e.g.
                                    <bean>
                                     <classloader>
                                     <!-- Construct pojo classloader from a different namespace
                                     inserted into ValueMetaData here as an object -->
                                     <cl:urlcl url="xxx:///some/url"/>
                                     </classloader>
                                    </bean>
                                    

                                    or using "property injection"
                                    <bean>
                                     <classloader bean="blah" property="classLoader"/>
                                    </bean>
                                    classloader = "blah".getClassLoader();
                                    


                                    ADDITIONAL METADATA:

                                    There is a small impedence between using ValueMetaData directly on the BeanMetaData
                                    and having a ClassLoaderMetaData that contains a ValueMetaData - (2) and (4) above.
                                    e.g. If we want to add extra metadata to the classloader in future.
                                    <bean>
                                     <classloader someFutureConfig="true"><inject bean="blah"/></classloader>
                                    </bean>
                                    


                                    EASE OF USE:

                                    I also wouldn't rule out having one at the deployment level either, rather than
                                    defining it for all the beans individually in the deployment.

                                    <deployment>
                                     <classloader/> <!-- Applies to all beans in the deployment without explicity classloader -->
                                     <bean/> <!-- Applies here -->
                                     <bean><classloader/></bean> <!-- But not here -->
                                    </deployment>
                                    



                                    1 2 3 Previous Next