Java: цикл на всех классах в пути к классу [дубликат]

Gitweb может быть хорошим, но он не имеет интегрированной покупки билетов или Wiki или чего-либо как этот.

13
задан glmxndr 30 September 2009 в 13:28
поделиться

6 ответов

Библиотека Reflections помогает справиться с этой проблемой. Как утверждали другие, это не полностью возможно во всех ситуациях загрузки классов, но если все, что у вас есть, это jar-файлы и файлы, это будет надежно.

13
ответ дан 1 December 2019 в 19:50
поделиться

Вы не можете сделать это элегантно.

Обычно загрузчик классов может попросить загрузить определенное имя класса, но не может быть запрошено для всех классов, которые он может загрузить. (В случае загрузки классов через Интернет,

8
ответ дан 1 December 2019 в 19:50
поделиться

Я решил эту проблему для загрузчика одного класса. Мне нужно было отражение, чтобы написать код для проверки тестов 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;
      }  

Я основывал свое решение на коде в этом потоке :

6
ответ дан 1 December 2019 в 19:50
поделиться

Думаю, вам придется проверить это вручную:

String classpath = System.getProperty("java.class.path");
String[] locations = classpath.split(System.getProperty("path.separator"));
// inspect all jar's and class files in these locations, which is a pain in the b%tt

Или использовать какую-нибудь стороннюю библиотеку, которая делает это (я не знаю ни одной).

3
ответ дан 1 December 2019 в 19:50
поделиться

вы не можете без специального загрузчика классов.

подумайте, например, о случае, когда вы загружаете свои классы с удаленного сервера, который даже не предлагает список каталогов. как вы можете перебирать все классы там?

интерфейс загрузчика классов не предоставляет такой функции. но если вы используете свой собственный загрузчик классов (или расширяете существующий загрузчик классов), вы можете добавить эту функцию. в любом случае некрасиво.

0
ответ дан 1 December 2019 в 19:50
поделиться

Я не знаю библиотеки, которая делает это, но есть проекты с открытым исходным кодом, которые делают это для своих целей. Например, Spring может перебирать классы в пути к классам, чтобы найти те, которые имеют определенную аннотацию. Вы можете посмотреть, как они это делают, чтобы получить некоторые идеи. Я бы начал с классов в пакете org.springframework.context.annotation , таких как ClassPathScanningCandidateComponentProvider и CommonAnnotationBeanPostProcessor

.

.
2
ответ дан 1 December 2019 в 19:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: