14 Replies Latest reply on Jul 16, 2010 6:14 AM by alesj

    Is it possible to add classloader root with wildcard pattern?

    saltnlight5

      Hi there,

       

      When writing deployment <classloader>, is it possible to specify a wildcard parttern like "<lib>/myapp/lib/*.jar</lib>" instead of single entry at time with <root>?

       

      Thanks,

      /Z

        • 1. Re: Is it possible to add classloader root with wildcard pattern?
          alesj
          When writing deployment <classloader>, is it possible to specify a wildcard parttern like "<lib>/myapp/lib/*.jar</lib>" instead of single entry at time with <root>?

          Again, not out of the box, but it's only two classes that you need to extend.

           

          New module class (X), so you have your own determineVFSRoots() impl -- which understands wildcard:

          * override VFSClassLoaderPolicyModule

           

          And new XML mapped VFSClassLoaderFactory to override the getModuleClass -- returning X.

          * custom <classloader> element

          • 2. Re: Is it possible to add classloader root with wildcard pattern?
            saltnlight5

            Hello Ales,

             

            Sorry to resurrect this old post, but can you help give little more help on the second item you've mentioned?

             

            I have extended VFSClassLoaderPolicyModule and VFSClassLoaderFactory. Do you have some examples on how to extend  XML mapping and create custom <classloader> element?

             

            Thanks.

            Zemian

            • 3. Re: Is it possible to add classloader root with wildcard pattern?
              saltnlight5

              BTW, the vfsRoots field in VFSClassLoaderPolicyModule is private, and it's been used in reset(). This makes it hard to extend from.

              • 4. Re: Is it possible to add classloader root with wildcard pattern?
                alesj

                This makes it hard to extend from.

                You can simply copy/paste and fix the piece that doesn't fit -- it's not a lot of code.

                • 5. Re: Is it possible to add classloader root with wildcard pattern?
                  saltnlight5

                  Thanks for replying,

                   

                  I said "hard", I don't mean there a lot of code I need to handle. I meant that if the class would provide a setter method for vfsRoots, then subcass won't need to cut/paste to repeat code. It not a big deal, and I get that part.

                   

                   

                  What I still not clear on is what is the proper way for me to extend n provide a new classloader element that will take my wildcard expression for a depoyment xml. For example if I created

                   

                  PatternCLModule extends VFSClassLoaderPolicyModule 

                   

                  and

                   

                  @XmlRootElement(name="pattern-classloader")
                  PatternCLFactory extends VFSClassLoaderFactory

                   

                  how do I map/tie the following in deployment to instantiate PatternCLModule?

                   

                  <pattern-classloader xmlns="urn:my:pattern-classloader:1.0" name="my-cl">
                       <root filename-re-pattern=".*\.jar">file:///opt/mylib</root>
                  </pattern-classloader>
                  

                   

                  I tried adding

                   

                  @JBossXmlSchema(namespace="urn:my:pattern-classloader:1.0", elementFormDefault=XmlNsForm.QUALIFIED)

                  to
                  PatternCLFactory

                   

                  but doesn't seem to work. Do I need to write a custom deployer to do this?

                  • 6. Re: Is it possible to add classloader root with wildcard pattern?
                    alesj

                    What about if we, instead of trying to hack this,

                    make this requirement as part of core code in VFSClassLoaderPolicyModule::determineVFSRoots? ;-)

                     

                    Feel free to suggest a proper patch which would handle this wildcard matching.

                    Or perhaps we could go even more generic, any reg-exp would do -- if it's not too big of an impact on non-reg-exp usage.

                    • 7. Re: Is it possible to add classloader root with wildcard pattern?
                      alesj
                      Feel free to suggest a proper patch which would handle this wildcard matching.
                      List<VirtualFile> vfsRoots = new ArrayList<VirtualFile>();
                               for (String root : roots)
                               {
                                  int wc = root.lastIndexOf("*"); // is it wildcard
                                  if (wc >= 0)
                                  {
                                     final String wcString = root.substring(wc + 1);
                                     VirtualFile start;
                                     if (wc > 0) // some more path before
                                     {
                                        start = VFS.getChild(root.substring(0, wc));
                                     }
                                     else
                                     {
                                        start = VFS.getRootVirtualFile();
                                     }
                                     try
                                     {
                                        List<VirtualFile> children = start.getChildren(new VirtualFileFilter()
                                        {
                                           public boolean accepts(VirtualFile file)
                                           {
                                              String name = file.getName();
                                              return name.endsWith(wcString);
                                           }
                                        });
                                        vfsRoots.addAll(children);
                                     }
                                     catch (IOException e)
                                     {
                                        throw new RuntimeException("Error creating VFS files for " + root, e);
                                     }
                                  }
                                  else
                                  {
                                     try
                                     {
                                        URI uri = new URI(root);
                                        vfsRoots.add(VFS.getChild(uri));
                                     }
                                     catch (URISyntaxException e)
                                     {
                                        throw new RuntimeException("Error creating VFS file for " + root, e);
                                     }
                                  }
                               }
                               this.vfsRoots = vfsRoots.toArray(new VirtualFile[vfsRoots.size()]);

                       

                      This would do it for wildcard.

                      • 8. Re: Is it possible to add classloader root with wildcard pattern?
                        alesj
                        but doesn't seem to work. Do I need to write a custom deployer to do this?

                        You need to register the schema to XB resolver singleton.

                        • 9. Re: Is it possible to add classloader root with wildcard pattern?
                          alesj
                          This would do it for wildcard.

                          This is commited to the trunk, along with a simple test.

                          * https://jira.jboss.org/browse/JBCL-173

                          • 10. Re: Is it possible to add classloader root with wildcard pattern?
                            saltnlight5

                            In the trunk already... Ah, very cool! You are too fast!

                             

                            BTW, thanks for the above hint. I do see examples of registering resolver in deployers/metadata-deployer-jboss-beans.xml now.

                             

                            My only comment to your solution is that it is unclear to user that this wildcard "*" is not file GLOB nor RegularExpression. User needs to konw that it works only for anything that ends with ".../*<match_this_suffix>". I think these test case would fail

                             

                            <root>file:///opt/lib/myapp-*.jar</root>
                            
                            <root>file:///opt/lib/myapp-*system*.jar</root>
                            
                            What happen if user enter non file URL? Should we validate these?
                            <root>http://www.foo.com/lib/*.jar</root> 
                            
                            
                            
                            
                            
                            • 11. Re: Is it possible to add classloader root with wildcard pattern?
                              saltnlight5

                              Just a suggestion, would these usage be more intuiative to the user (using full regular expression pattern for matches)?

                               

                              Use URL query parameter:
                              <root>file:///opt/lib?file-re-pattern=.*jar</root>
                              
                              Or extend root element with attribute:
                              <root file-re-pattern=".*jar">file:///opt/lib</root>
                              
                              
                              
                              
                              • 12. Re: Is it possible to add classloader root with wildcard pattern?
                                alesj
                                Just a suggestion, would these usage be more intuiative to the user (using full regular expression pattern for matches)?

                                 

                                Use URL query parameter:
                                <root>file:///opt/lib?file-re-pattern=.*jar</root>
                                
                                Or extend root element with attribute:
                                <root file-re-pattern=".*jar">file:///opt/lib</root>
                                
                                
                                
                                
                                
                                
                                

                                The 2nd one would require a change to the api, since root is currently directly mapped to String,

                                and would have to be changed to some custom attribute handling class.

                                 

                                I'll use the 1st approach. Perhaps some other (shorter) key word suggestion?

                                * root-re-pattern perhaps?

                                • 13. Re: Is it possible to add classloader root with wildcard pattern?
                                  saltnlight5

                                  "root-re-pattern" is same length as "file-re-pattern"

                                   

                                  If you want it short, just use "pattern" is reasonable because most people would try RegExp for that.

                                   

                                  When I have some free momement this weekend, I can help contribute some code.

                                  • 14. Re: Is it possible to add classloader root with wildcard pattern?
                                    alesj
                                    "root-re-pattern" is same length as "file-re-pattern"

                                    Yeah, but that's why I asked if we can think of something shorter.

                                    But I think we can just leave it, as it's not so important - X vs X-7 makes no difference. :-)

                                    When I have some free momement this weekend, I can help contribute some code.

                                    I already changed the trunk to use reg-exp.

                                    But you're welcome to add a few more tests or some other ideas / features.