glm*_*ndr 13 java reflection classpath
有没有办法迭代类路径中的所有类?
我想对实现某个接口的某些类进行一些反思性检查,但我想完全动态地完成它,而不需要检查哪些类,只需浏览类路径.
你不能优雅地做到这一点.
基本上可以要求类加载器加载特定的类名,但不能要求它加载所有类.(如果在Web上加载类,则可能无法这样做 - 您无法可靠地要求Web服务器告诉您特定目录下的所有文件.)
如果你的类路径只处理文件系统,你可能会痛苦地找到扩展目录中的所有jar文件,递归正常的类路径目录,并查看所有明确指定的jar文件 - 但它会很棘手,也可能很脆弱.
我已经为单个类加载器解决了这个问题.我需要反思来编写代码来检查JUnit测试并报告被忽略的测试.
       /**
       * Attempts to list all the classes in the specified package as determined
       * by the context class loader
       * 
       * @param pckgname
       *            the package name to search
       * @return a list of classes that exist within that package
       * @throws ClassNotFoundException
       *             if something went wrong
       */
      private static List<Class> getClassesForPackage(String pckgname) throws ClassNotFoundException {
          // This will hold a list of directories matching the pckgname. There may be more than one if a package is split over multiple jars/paths
          ArrayList<File> directories = new ArrayList<File>();
          try {
              ClassLoader cld = Thread.currentThread().getContextClassLoader();
              if (cld == null) {
                  throw new ClassNotFoundException("Can't get class loader.");
              }
              String path = pckgname.replace('.', '/');
              // Ask for all resources for the path
              Enumeration<URL> resources = cld.getResources(path);
              while (resources.hasMoreElements()) {
                  directories.add(new File(URLDecoder.decode(resources.nextElement().getPath(), "UTF-8")));
              }
          } catch (NullPointerException x) {
              throw new ClassNotFoundException(pckgname + " does not appear to be a valid package (Null pointer exception)");
          } catch (UnsupportedEncodingException encex) {
              throw new ClassNotFoundException(pckgname + " does not appear to be a valid package (Unsupported encoding)");
          } catch (IOException ioex) {
              throw new ClassNotFoundException("IOException was thrown when trying to get all resources for " + pckgname);
          }
          ArrayList<Class> classes = new ArrayList<Class>();
          // For every directory identified capture all the .class files
          for (File directory : directories) {
              if (directory.exists()) {
                  // Get the list of the files contained in the package
                  String[] files = directory.list();
                  for (String file : files) {
                      // we are only interested in .class files
                      if (file.endsWith(".class")) {
                          // removes the .class extension
                        try
                        {
                          classes.add(Class.forName(pckgname + '.' + file.substring(0, file.length() - 6)));                      
                        }
                        catch (NoClassDefFoundError e)
                        {
                          // do nothing. this class hasn't been found by the loader, and we don't care.
                        }
                      }
                  }
              } else {
                  throw new ClassNotFoundException(pckgname + " (" + directory.getPath() + ") does not appear to be a valid package");
              }
          }
          return classes;
      }