1 2 3 4 5 6 Previous Next 77 Replies Latest reply on Oct 21, 2010 6:45 AM by alesj Go to original post
      • 45. Re: Implementing a non-flat deployment for Weld Integration
        alesj
        Ales, why should I add it to bootstrap?

        I mean, can't I just scan the lib dirs as part of the first weld deployment instead of doing it on bootstrap? What are the advantages of doing otherwise?

        Exactly for the reason you have a 2nd question. :-)

        Another question: once I determine that a specific jar in lib has the META-INF/beans.xml file, what is the cleanest way of retrieving the corresponding lib ClassLoader?

        Adding some "listener" service at bootstrap would mean we could somehow

        add a mechanism that would, for every lib added to cl domain, check if there is some beans.xml.

         

        I can look into it what would be the best way to do this.

        Unless you wanna do it yourself.

        • 46. Re: Implementing a non-flat deployment for Weld Integration
          flavia.rainone

          Pete Muir wrote:

           

          Looks like the problem is that the services have got a bit out of control in JBoss AS, and that JBossEjbServices has ended up being dual purposed as an EJB discovery mechanism, and as an impl of EjbInjectionServices. So when you copy it, you end up copying the discovered ejbs as well.

           

          I think the best course of action is to split the two bits of JBossEjbServices into it's two parts  - discovery and injection.

          That makes a lot of sense and explains why I wasn't able to get rid of the problem.

          I'll try that!

          • 47. Re: Implementing a non-flat deployment for Weld Integration
            flavia.rainone

            Ales Justin wrote:

             

            Ales, why should I add it to bootstrap?

            I mean, can't I just scan the lib dirs as part of the first weld deployment instead of doing it on bootstrap? What are the advantages of doing otherwise?

            Exactly for the reason you have a 2nd question. :-)


            Indeed, currently I'm invoking DefaultDomain.loadClass so I can figure out the ClassLoader, which is awful. I also thought on applying some rule to determine the module name, but I wanted to hear from you what would be a good way of retriveing the CL.

             

            Ales Justin wrote:

             

            Another question: once I determine that a specific jar in lib has the META-INF/beans.xml file, what is the cleanest way of retrieving the corresponding lib ClassLoader?

            Adding some "listener" service at bootstrap would mean we could somehow

            add a mechanism that would, for every lib added to cl domain, check if there is some beans.xml.


            Cool. That would easily give access to the ClassLoader/module that corresponds to the lib IIUC.

             

             

            Ales Justin wrote:

             

             

            I can look into it what would be the best way to do this.

            Unless you wanna do it yourself.

            Thanks! You can go ahead. :-) In the meantime, I'll try Pete's suggestion to fix the duplicate ejb descriptor issue.

            • 48. Re: Implementing a non-flat deployment for Weld Integration
              flavia.rainone

              Flavia Rainone wrote:

               

              Pete Muir wrote:

               

              Looks like the problem is that the services have got a bit out of control in JBoss AS, and that JBossEjbServices has ended up being dual purposed as an EJB discovery mechanism, and as an impl of EjbInjectionServices. So when you copy it, you end up copying the discovered ejbs as well.

               

              I think the best course of action is to split the two bits of JBossEjbServices into it's two parts  - discovery and injection.

              That makes a lot of sense and explains why I wasn't able to get rid of the problem.

              I'll try that!

              That worked.

               

              For now, I'll attach a patch to Jira with everything I did to have WELDINT-1 working in AS trunk.

               

              We need a fix for the BeanManager JNDI binding issue before that is committed. Any news on that?

              • 49. Re: Implementing a non-flat deployment for Weld Integration
                marius.bogoevici

                I'll add a fix sometime this week. I plan on reviving the unique name JNDI binder for this.

                 

                Message was edited by: Marius Bogoevici. was "next week" which is an unusual portmanteau for "next days, this week".

                • 50. Re: Implementing a non-flat deployment for Weld Integration
                  flavia.rainone

                  Marius Bogoevici wrote:

                   

                  I'll add a fix sometime this week. I plan on reviving the unique name JNDI binder for this.

                   

                  Great! Thanks for the feedback

                  • 51. Re: Implementing a non-flat deployment for Weld Integration
                    alesj

                    I can look into it what would be the best way to do this.

                    Unless you wanna do it yourself.

                    Thanks! You can go ahead. :-)

                    OK, I have a few things ready, but now I need to know what do you need to make this work.

                     

                    Currently I have this in place:

                    public synchronized Set<BeanDeploymentArchive> getLibraries() throws Exception
                       {
                          if (libs == null || checked.get() == false)
                          {
                             List<VirtualFile> excludedFiles = null;
                    
                             Map<Module, Set<URL>> modules = provider.getMatchingModules();
                             for (Map.Entry<Module, Set<URL>> entry : modules.entrySet())
                             {
                                Set<URL> urls = entry.getValue();
                                if (excludedUrls != null && excludedFiles == null)
                                {
                                   excludedFiles = new ArrayList<VirtualFile>();
                                   for (URL eu : excludedUrls)
                                      excludedFiles.add(VFS.getChild(eu));
                                }
                                Set<VirtualFile> files = new HashSet<VirtualFile>();
                                for (URL u : urls)
                                {
                                   VirtualFile vf = VFS.getChild(u);
                                   boolean include = true;
                                   if (excludedFiles != null)
                                   {
                                      for (VirtualFile ef : excludedFiles)
                                      {
                                         if (vf.getParentFileList().contains(ef))
                                         {
                                            include = false;
                                            break;
                                         }
                                      }
                                   }
                                   if (include)
                                      files.add(vf);
                                }
                                if (files.isEmpty() == false)
                                {
                                   ClassLoader cl = ClassLoading.getClassLoaderForModule(entry.getKey());
                                   // is this module already installed; past CL stage -- should be
                                   if (cl != null)
                                   {
                                      // TODO  <----- your input needed here                   
                                   }
                                }
                             }
                             checked.set(true);
                          }
                          return libs;
                       }
                    

                     

                    I can now return a set of matching modules, which have beans.xml as part of its resources.

                    This is mostly aimed at system deployments, though it can serve all deployments.

                    (it will be disabled once get past PS' DEPLOYERS phase)

                     

                    Each module is mapped to beans.xml' owners; e.g. some-cdi-lib.jar.

                     

                    Will this info be enough for you?

                    Or at which example / use case / code should I look for more info?

                    • 52. Re: Implementing a non-flat deployment for Weld Integration
                      flavia.rainone

                      Ales Justin wrote:

                       

                      Will this info be enough for you?

                      Great! Yes, this is enough. We need both the class loader and the module, plus the URL of the beansXML file, which can be easily retrieved.

                      Roughly speaking, this is how we would fill in the gaps of the TODO mark you added in your getLibraries method:

                       

                      // create an ArchiveInfo with the ClassLoader
                      ArchiveInfo archiveInfo = new ArchiveInfo(classLoader);
                      
                      // set the WeldXmlURL
                      WeldDiscoveryEnvironment environment = archiveInfo.getEnvironment();
                      beansXmlURL = // the beansXml URL
                      environment.addWeldXmlURL(beansXmlURL);
                      
                      // fill in the Weld classes
                      // the WBDiscoveryVisitor from ArchiveDiscoveryDeployer... needs to be moved to another placee
                      WBDiscoveryVisitor visitor = new WBDiscoveryVisitor(environment);
                      Module module = entry.getKey();
                      module.visit(visitor, ClassFilter.INSTANCE, null, new URL[]{child.toURL()});
                      
                      // finally create the Archive
                      Archive archive = ArchiveFactory.createArchive(archiveInfo, new ArrayList<EjbDescriptor<?>>());
                      
                      // ... and the corresponding BDA
                      ServiceRegistry serviceRegistry = new SimpleServiceRegistry();
                      // TODO: fill in serviceRegistry? With which services?
                      libs.add(archive.createBeanDeploymentArchive(serviceRegistry));
                      
                      
                      

                       

                      Given most of this classes above is package protected, I'll refactor those and write a method that does this internally as part of the API. I'll post back when I'm done.

                       

                      The other piece of code that we are missing is the part that invokes this, right? At some point we need to fill in the DefaultDomain Classpath (take a look at ClasspathFactory for more details) with the lib BDAs created by your getLibraries method. As we agreed before, this should be done ideally at the first weld deployment. So, I would simply add a piece of code to ClasspathFactory that calls getLibraries, unless you prefer this call to be performed somewhere else.

                       

                      Ales Justin wrote:


                      Or at which example / use case / code should I look for more info?

                      I think that the best way to check everything is working ok is adding a Weld jar to jboss lib prior to start up and make sure that a BDA is being created for it. Other than that, I don't have any use cases :-).

                      • 53. Re: Implementing a non-flat deployment for Weld Integration
                        alesj
                        Given most of this classes above is package protected, I'll refactor those and write a method that does this internally as part of the API. I'll post back when I'm done.

                        No need for this, as I can simply move this service into that package.

                        And if there is really a need, I can hide its impl details later on.

                        • 54. Re: Implementing a non-flat deployment for Weld Integration
                          alesj
                          Roughly speaking, this is how we would fill in the gaps of the TODO mark you added in your getLibraries method:

                          OK, refactored things a bit, I now have this:

                           

                                            // create an ArchiveInfo with the ClassLoader
                                            ArchiveInfo archiveInfo = new ArchiveInfo(cl);
                                            // finally create the Archive
                                            Archive archive = ArchiveFactory.createArchive(archiveInfo, new ArrayList<EjbDescriptor<?>>());   
                                            // ... and the corresponding BDA
                                            ServiceRegistry serviceRegistry = new SimpleServiceRegistry();
                                            // TODO: fill in serviceRegistry? With which services?
                             
                                            libs.add(archive.createBeanDeploymentArchive(serviceRegistry));
                          
                                            // the env
                                            WeldDiscoveryEnvironment environment = archiveInfo.getEnvironment();
                                            // fill in the Weld classes
                                            // the WBDiscoveryVisitor from ArchiveDiscoveryDeployer... 
                                            ResourceVisitor visitor = environment.visitor();   
                                            Module module = entry.getKey();
                                            
                                            for (VirtualFile child : files)
                                            {
                                               URL beansXmlURL = child.getChild(provider.getResourceName()).toURL();   
                                               environment.addWeldXmlURL(beansXmlURL);
                             
                                               module.visit(visitor, ClassFilter.INSTANCE, null, child.toURL());   
                                            }
                          

                           

                          It all compiles. :-)

                           

                          The other piece of code that we are missing is the part that invokes this, right? At some point we need to fill in the DefaultDomain Classpath (take a look at ClasspathFactory for more details) with the lib BDAs created by your getLibraries method. As we agreed before, this should be done ideally at the first weld deployment. So, I would simply add a piece of code to ClasspathFactory that calls getLibraries, unless you prefer this call to be performed somewhere else.

                          OK, I still need to think about this one a bit.

                           

                          I think that the best way to check everything is working ok is adding a Weld jar to jboss lib prior to start up and make sure that a BDA is being created for it. Other than that, I don't have any use cases :-).

                          Yup, I'll create a simple test for this -- probably (until we do have a *real* CDI lib present) I'll have to create a new server config for it.

                          • 55. Re: Implementing a non-flat deployment for Weld Integration
                            flavia.rainone

                            To keep you posted, Marius provided a fix for JBAS-8170 (the BeanManager JNDI issue) and now the weld deployers tests are finally passing for me (with the WELDINT-1 stuff enabled).

                             

                            Unfortunately, though, if I run those tests several times in a row, I get an OutOfMemoryError. I'm trying to figure out where is the memory leak.

                            • 56. Re: Implementing a non-flat deployment for Weld Integration
                              flavia.rainone

                              I'm attaching an updated patch to Jira. This patch can be applied against JBoss AS trunk to enable the new non-flat Deployment in the server.

                              • 57. Re: Implementing a non-flat deployment for Weld Integration
                                flavia.rainone

                                I have just committed the rest of JBAS-8250 to trunk.

                                 

                                As far as I can see, the non-flat DeploymentImpl is not causing the OutOfMemoryError. Comparing DeploymentImpl vs FlatDeployment, I had to run the deployers/weld tests the same number of times (16 times) to get a OutOfMemoryError.

                                 

                                Anyway, I profiled JBoss AS memory usage with those tests. A very high number of HashMap$Entry instances called my attention, and most of them couldnt' be garbage collected. JProfiler showed them as being held by org.jboss.logmanager.LogContext, so I don't think I got to any useful results.

                                 

                                Going back to JBAS-8250, I see 4 pending issues:

                                - the library scanning that Ales is working on

                                - we need also a mechanism to scan for libs referenced from manifest files, creating BDAs for any lib that contains META-INF/beans.xml

                                - a FIXME that I added to DeploymentImpl (regarding the undeployment of loaded BDAs)

                                - replace the slow Classpath implementation by the NoDuplicatesClasspath

                                 

                                The last two are pretty simple to do. The second one concerns me most. Any ideas on how should we tackle that one?

                                • 58. Re: Implementing a non-flat deployment for Weld Integration
                                  alesj
                                  - we need also a mechanism to scan for libs referenced from manifest files, creating BDAs for any lib that contains META-INF/beans.xml

                                  How is this different from what we're already doing?

                                  Or, I think we're already covering this use case. Or not?

                                  • 59. Re: Implementing a non-flat deployment for Weld Integration
                                    alesj
                                    - the library scanning that Ales is working on

                                    Let me know when you're done, as I'm mostly done, but I have a few changes to your code,

                                    to make this integration easier / nicer.