5 Replies Latest reply on Sep 15, 2010 5:50 PM by alesj Branched from an earlier discussion.

    Scanning classes with VFS

    grossetieg

      Hi,

       

      What is the right way to scan classes in a package with VFS ?

      I've tried something like :

      List<Class<? extends Enum<?>>> result = new ArrayList<Class<? extends Enum<?>>>();
      ClassLoader cld = Thread.currentThread().getContextClassLoader();
      if (null != cld) {
           final String pkgPath = packageName.replace('.', '/');
           URL resource = cld.getResource(pkgPath);
           VirtualFile file = VFS.getChild(resource);
      
           List<VirtualFile> children = file.getChildrenRecursively();
           for (VirtualFile child : children) {
                if (child.isFile()) {
                     Class<?> clazz = Class.forName(packageName.concat(".").concat(child.getName().split("\\.")[0]));
                     if (clazz.isEnum()) {
                          result.add((Class<Enum<?>>) clazz);
                     }
                }
           }
      }
      

       

      But the package isn't a directory and getChildrenRecursively() return an empty list. We, previously in JBoss 4.2.3, used :

      List<Class<? extends Enum<?>>> result = new ArrayList<Class<? extends Enum<?>>>();
      ClassLoader cld = Thread.currentThread().getContextClassLoader();
      if (null != cld) {
           String pkgPath = packageName.replace('.', '/');
           URL resource = cld.getResource(pkgPath);
           if (null != resource) {
                if (resource.getProtocol().equals("jar")) {
                     int index = resource.getPath().indexOf('!');
                     // on extrait le chemin du jar
                     String fullJarPathWithName = resource.getPath().substring(5, index);
                     List<Class<? extends Enum<?>>> classes = getEnumClassesFromJar(fullJarPathWithName, packageName, pkgPath);
                     if (null != classes) {
                          result.addAll(classes);
                     }
                }
           }
      }
      

       

      But with VFS the path doesn't contain ! anymore.

       

      We also tried with a visitor pattern but without success. I've read the article at dzone but some classes doesn't exist anymore (SuffixVisitor in jboss-vfs.3.0.0.CR5.jar).

       

      Thanks in advance.

       

      Guillaume.

        • 1. Re: Scanning classes with VFS
          alesj

          In which env (AS version) are you trying to run this?

           

          In AS6_M4 there is a new scanning lib already present: http://java.dzone.com/articles/jboss-microcontainer-scanning

          Perhaps it would be easier to use that.

           

          Did you try debugging? As I don't see why your approach wouldn't work.

          • 2. Re: Scanning classes with VFS
            grossetieg

            Hi,

             

            Thanks for the quick reply. I'm running JBoss 6.0.0.M3.

            I will migrate to JBoss 6.0.0.M4 today to try the new scanning lib. I tried debugging :

            URL resource = cld.getResource(pkgPath);

            With pkgPath = mypackage.etc.enumeration.action, give me URL :

             

            vfs:/home/g.grossetie/business/profiles/jboss-6.0.0.20100429-m3/server/default/deploy/deploy/1-calliope.ear/lib/framework-ejbimpl-2.0-SNAPSHOT-common.jar/mypackage/etc/enumeration/action/

             

            I guess that my VirtualFile is created correctly. Then when I call :

             

            file.getChildrenRecursively() 

             

             

                /**
                 * Get all the children recursively<p>
                 * <p/>
                 * This always uses {@link VisitorAttributes#RECURSE}
                 *
                 * @return the children
                 *
                 * @throws IOException for any problem accessing the virtual file system
                 * @throws IllegalStateException if the file is closed
                 */
                public List<VirtualFile> getChildrenRecursively() throws IOException {
                    return getChildrenRecursively(null);
                }
            
                /**
                 * Get all the children recursively<p>
                 * <p/>
                 * This always uses {@link VisitorAttributes#RECURSE}
                 *
                 * @param filter to filter the children
                 *
                 * @return the children
                 *
                 * @throws IOException for any problem accessing the virtual file system
                 * @throws IllegalStateException if the file is closed or it is a leaf node
                 */
                public List<VirtualFile> getChildrenRecursively(VirtualFileFilter filter) throws IOException {
                    if (!isDirectory())
                        return Collections.emptyList();
                    if (filter == null)
                        filter = MatchAllVirtualFileFilter.INSTANCE;
                    FilterVirtualFileVisitor visitor = new FilterVirtualFileVisitor(filter, VisitorAttributes.RECURSE);
                    visit(visitor);
                    return visitor.getMatched();
                }
            

             

            the method return Collections.emptyList();

             

             

             if (!isDirectory())
                        return Collections.emptyList();
            

             

             

            So I can't interact with my classes because my package isn't a directory ?

             

             

            Guillaume.

            /**
                 * Get all the children recursively<p>
                 * <p/>
                 * This always uses {@link VisitorAttributes#RECURSE}
                 *
                 * @return the children
                 *
                 * @throws IOException for any problem accessing the virtual file system
                 * @throws IllegalStateException if the file is closed
                 */
                public List<VirtualFile> getChildrenRecursively() throws IOException {
                    return getChildrenRecursively(null);
                }
                /**
                 * Get all the children recursively<p>
                 * <p/>
                 * This always uses {@link VisitorAttributes#RECURSE}
                 *
                 * @param filter to filter the children
                 *
                 * @return the children
                 *
                 * @throws IOException for any problem accessing the virtual file system
                 * @throws IllegalStateException if the file is closed or it is a leaf node
                 */
                public List<VirtualFile> getChildrenRecursively(VirtualFileFilter filter) throws IOException {
                    if (!isDirectory())
                        return Collections.emptyList();
                    if (filter == null)
                        filter = MatchAllVirtualFileFilter.INSTANCE;
                    FilterVirtualFileVisitor visitor = new FilterVirtualFileVisitor(filter, VisitorAttributes.RECURSE);
                    visit(visitor);
                    return visitor.getMatched();
                }
            • 3. Re: Scanning classes with VFS
              alesj
              So I can't interact with my classes because my package isn't a directory ?

              Hmmm, I would expect it to return true on the isDirectory().

               

              Can you debug it a bit further, so that we see which VFS's FileSystem instance / impl is used.

              e.g. step into VirtualFile::isDirectory and see which mount.getFileSystem() gets used

               

              At which point you are using your code?

              If the VFS didn't yet properly mount the zip/jar files, then this might be the root of the problem.

              e.g. zip/jar files need to be explicitly mounted in order for VFS to understand zip/jar structure

              • 4. Re: Scanning classes with VFS
                grossetieg

                Working on Saturday morning

                 

                My code is running when JBoss is started. It's a module in my application that use this code.

                Alright, so I need to mount my jar using http://community.jboss.org/wiki/VFS3UserGuide#Example_Mount_Archive_VirtualFile and then call getChildrenRecursively().

                 

                I will try these tomorrow to see which VFS's FileSsystem impl is used and test this solution.

                 

                Thank for the advise,

                 

                Guillaume.

                • 5. Re: Scanning classes with VFS
                  alesj
                  My code is running when JBoss is started. It's a module in my application that use this code.

                  If this is part of your app, it should already be mounted.

                  Unless you're accessing it too early, e.g. in some deployer with pre-Describe stage.

                  But yeah, debug it a bit further and we'll know a lot more. ;-)