10 Replies Latest reply on Mar 3, 2010 8:11 AM by gcompienne

    Classloaders & Domains: Some questions & a suggestion

      Having played with the MC classloading mechanism and its notion of domain, there is something I don't understand.

       

      The notion of domains seems to be there to allow visibility of classes without having to declare any specific dependencies (requirements/capabilities declarations).

       

      Now, if I declare the requirements/capabilities of a module, I would have expected this to work accross domains. But, as far as I can tell, this is not the case (for example, if I load an implementation into a specific domain that uses a different parent, then that implementation cannot access anything that would have been loaded in the DefaultDomain even if the requirements/capabilities declaration were to match).

       

      But then I wonder: What's the point of declaring requirement/capabilities if I can see all of the domain's classes as soon as they are in the same domain? (especially as it seems they will never be visible unless they are part of the same domain/parent domain hierarchy)

       

      I also wonder what is the role of the 'import-all="false"' attribute. I was thinking that would mean I would not see the classes of my domain (and parent domain) unless I declare my dependency via the requirement element. But to be honest I can't see its effects.

       

      I feel that the domain concept is a good idea as it allows a transition to a more OSGi like solution (allowing to put things in common without having to declare anything).

       

      However, I feel it would be more powerful, if the requirement/capabilties information was used to fill dependencies accross domains. It would also be more powerfull if the import-all (which I currently see as some kind of OSGi / non-OSGi mode toggle) was really working (I mean for the scenario where we look at things inside a specific domain).

       

      At the moment, the requirement/capability mechanism seems to be only a sanity check. But if it was really used by the classloading mechanism to know how to link things, then I feel it would be a lot more useful (and powerful).

       

      I was even wondering if allowing something like follows would be an idea:

      <requirements>
           <package name="my.isolated.infinispan.instance" domain="The_Domain_Where_It_Has_Been_Isolated/>  
      </requirements>

       

      But I suspect this could well be going too far: Matching the requirements/capabilities should be enough. And even if something is available in multiple domains it should not matter (we already can specify which version we depend on, which should probably be enough).

       

      WDYT?

       

      Or have I misunderstood the whole mechanism?

        • 1. Re: Classloaders & Domains: Some questions & a suggestion
          alesj

          Requirements are resolved in hierarchy, see Domain::doResolveModule.

          • 2. Re: Classloaders & Domains: Some questions & a suggestion
            alesj

            But then I wonder: What's the point of declaring requirement/capabilities if I can see all of the domain's classes as soon as they are in the same domain? (especially as it seems they will never be visible unless they are part of the same domain/parent domain hierarchy)

            This should not be the case if you declare explicit requirements.

            At the moment, the requirement/capability mechanism seems to be only a sanity check. But if it was really used by the classloading mechanism to know how to link things, then I feel it would be a lot more useful (and powerful).

            They are used to link things together -- that's what RequirementDependencyItem is all about.

            • 3. Re: Classloaders & Domains: Some questions & a suggestion

              That's strange then. I am using the following jboss-classloader.xml file:

               

              <?xml version="1.0" encoding="UTF-8"?>

              <classloading domain="InfinispanCacheDomain" xmlns="urn:jboss:classloading:1.0"
                            import-all="false" parent-first="false" parent-domain="DefaultDomain" top-level-classloader="true">
                  
              <requirements>
                <package name="test.cluster.datacache.api"/>  
              </requirements>
              <capabilities>
                <package name="test.cluster.datacache.infinispan_impl"/>
              </capabilities>
                
              </classloading>

               

              The file clearly specify a requirement (and also uses "import-all=false"), but the module can still use Log4j (which is should not as it is not declared).

               

              I also went to the JMX Console, and, on the classloader assigned to the application, I was able to load jgroup and other similar classes, which I should not have been able to.

               

              Now, this test was done on JBoss AS 5.1. So is it something that changed recently in the MC trunk?

               

              Thanks.

               

              Gilles.

              • 4. Re: Classloaders & Domains: Some questions & a suggestion
                alesj

                Now, this test was done on JBoss AS 5.1. So is it something that changed recently in the MC trunk?

                Nope. I'll have a closer look.

                • 5. Re: Classloaders & Domains: Some questions & a suggestion
                  alesj

                  Nope. I'll have a closer look.

                  OK, I hacked a small test for this -- which proves my right. ;-)

                   

                  See attached zip:

                  * dummy -- placed into default domain

                  * transl -- simple translator/hello service

                  * starter -- uses translator + tries to load Dummy from dummy

                   

                  Since starter explicitly declares its requirements:

                   

                  <classloading xmlns="urn:jboss:classloading:1.0">
                     <requirements>
                        <package name="com.alesj.spi"/>
                     </requirements>
                  </classloading>
                  

                   

                  it doesn't see Dummy in start()

                   

                     public void start() throws Exception
                     {
                        Class<?> aClass = getClass().getClassLoader().loadClass("net.dummy.test.Dummy");
                        System.out.println("aClass = " + aClass);
                     }
                  

                   

                  as shown here:

                   

                  java.lang.ClassNotFoundException: net.dummy.test.Dummy from BaseClassLoader@2dd59d3c{vfszip:/Users/alesj/projects/demos/mc/sandbox/starter.jar/}
                      at org.jboss.classloader.spi.base.BaseClassLoader.loadClass(BaseClassLoader.java:498)
                      at java.lang.ClassLoader.loadClass(ClassLoader.java:250)
                      at org.acme.services.Startup.start(Startup.java:42)
                  

                   

                  If I remove jb-cl.xml in starter.jar, all is fine, as we can see the default domin and its dummy.jar/Dummy.class.

                  1 of 1 people found this helpful
                  • 6. Re: Classloaders & Domains: Some questions & a suggestion

                    Ok, I am going to have a look at your sample tonight and compare it with what I have done so far. Then, once I have found where is my mistake I will post the info.

                     

                    Thanks for your help :-)

                     

                    Gilles.

                    • 7. Re: Classloaders & Domains: Some questions & a suggestion

                      Sorry for the delay in responding. As expected your code works but I finally found the difference with my tests:

                       

                      If I move transl and Services into their own domain, i.e. by adding a domain attribute as the example below:

                       

                      <Services>/jboss-classoading.xml:

                      <classloading xmlns="urn:jboss:classloading:1.0" domain="InfinispanCacheDomain">
                         <requirements>
                            <package name="com.alesj.spi"/>
                         </requirements>
                      </classloading>

                       

                      <transl>/jboss-classloading.xml:

                      <classloading xmlns="urn:jboss:classloading:1.0" domain="InfinispanCacheDomain">
                         <capabilities>
                            <package name="com.alesj.spi"/>
                         </capabilities>
                      </classloading>

                       

                      Then it does not work anymore and Services suddenly starts seeing the Dummy class, even though I didn't declare any dependencies onto it...

                       

                      To me this is wrong, especially as I agree with you that, if I start declaring explicitely the <requirements> then I should not see anything else...

                       

                      Or I am missing something else?

                       

                      Thanks again for your help.

                       

                      Gilles.

                      • 8. Re: Classloaders & Domains: Some questions & a suggestion
                        alesj

                        Then it does not work anymore and Services suddenly starts seeing the Dummy class, even though I didn't declare any dependencies onto it...

                         

                        To me this is wrong, especially as I agree with you that, if I start declaring explicitely the <requirements> then I should not see anything else...

                        Looks like filtering is only applied per domain in which this is defined.

                        I would also expect this to be carried to any parent domain as well.

                        I'll check where this kicks in, or actually, where it doesn't. :-)

                        • 9. Re: Classloaders & Domains: Some questions & a suggestion
                          alesj
                          Looks like filtering is only applied per domain in which this is defined.

                          I would also expect this to be carried to any parent domain as well.

                          This is by design:

                          * http://community.jboss.org/message/528588#528588

                           

                          As is stated in the dev forum thread, you need to properly apply filtering on the domain itself.

                          Once DefaultDomain is properly OSGi-zed this will be a lot easier to handle. ;-)

                          • 10. Re: Classloaders & Domains: Some questions & a suggestion

                            Ok, Thanks for the info.

                             

                            In terms of my suggestion I suspect it probably means it would have to wait for the proper OSGied version of the default domain to see if it is still useful or not.

                             

                            Thanks.

                             

                            Gilles.