Я работаю над проектом maven, и я добавил в свой файл pom.xml зависимость guava и зависимость другого проекта. Я хочу получить весь класс данного пакета этого проекта, который я добавил в свой pom в качестве зависимости. Итак, я попробовал это:

public void getClassOfPackage() {

    final ClassLoader loader = Thread.currentThread()
            .getContextClassLoader();
    try {
        for (final ClassPath.ClassInfo info : ClassPath.from(loader)
                .getTopLevelClasses()) {

                System.out.println(info.getSimpleName());

        }
    } catch (IOException e) {
        e.printStackTrace();
    }

}

public static void main(String[] args) {
    new TestMain().getClassOfPackage();
}

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

HierarchicalConfigurationConverter
HierarchicalConfigurationXMLReader
HierarchicalINIConfiguration
SubsetConfiguration
SystemConfiguration...

Я не знаю, где я могу указать проект, о котором я говорю, и как я могу просто передать имя пакета, и он дает мне весь класс, который он содержит.

4
TinyOS 4 Фев 2015 в 20:13

4 ответа

Лучший ответ

Я нашел решения для буксировки:

С гуавой:

public void getClassOfPackage(String packagenom) {

    final ClassLoader loader = Thread.currentThread()
            .getContextClassLoader();
    try {

        ClassPath classpath = ClassPath.from(loader); // scans the class path used by classloader
        for (ClassPath.ClassInfo classInfo : classpath.getTopLevelClasses(packagenom)) {
         if(!classInfo.getSimpleName().endsWith("_")){
            System.out.println(classInfo.getSimpleName());
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

}

public static void main(String[] args) {
    new TestMain().getClassOfPackage("org.myproject");
}

С Java.util:

    public List<Class> getClassOfPackage(String packageName)
        throws ClassNotFoundException, IOException {

    ClassLoader classLoader = Thread.currentThread()
            .getContextClassLoader();

    assert classLoader != null;
    String path = packageName.replace('.', '/');
    Enumeration<URL> resources = classLoader.getResources(path);
    List<File> dirs = new ArrayList<File>();
    while (resources.hasMoreElements()) {
        URL resource = resources.nextElement();
        dirs.add(new File(resource.getFile()));
    }
    ArrayList<Class> classes = new ArrayList<Class>();
    for (File directory : dirs) {
        classes.addAll(findClasses(directory, packageName));
    }
    return classes;
}

private static List<Class> findClasses(File directory, String packageName)
        throws ClassNotFoundException {
    List<Class> classes = new ArrayList<Class>();
    if (!directory.exists()) {
        return classes;
    }
    File[] files = directory.listFiles();
    for (File file : files) {
        if (file.isDirectory()) {
            assert !file.getName().contains(".");
            classes.addAll(findClasses(file,
                    packageName + "." + file.getName()));
        } else if (file.getName().endsWith(".class")) {
            classes.add(Class.forName(packageName
                    + '.'
                    + file.getName().substring(0,
                            file.getName().length() - 6)));
        }
    }
    return classes;
}

public static void main(String[] args) throws ClassNotFoundException,
        IOException {

    for (Class className : new ClassOfPackage()
            .getClassOfPackage("org.mypackage")) {
        if (!className.getSimpleName().endsWith("_")) {
            System.out.println(className.getSimpleName());
        }

    }

}
2
TinyOS 5 Фев 2015 в 10:28

Эту проблему проще решить с помощью отражений Google.

Пожалуйста, проверьте следующий вопрос для правильного ответ - обратите внимание, что отмеченный ответ не дает рабочего решения, второй (Александр Бломскельд) - дает!

-1
Community 23 Май 2017 в 12:01

Вот почему вы видите его распечатанным sun.misc.Launcher$AppClassLoader:

} else {
     System.out.println(loader.getClass().getName());
}

Каждый класс в вашем пути к классам, которого нет в вашем пакете, заставляет вашу программу распечатывать имя класса реализации ClassLoader, что вам, вероятно, не нужно.

Кроме того, хотя info.getName().startsWith("org.mypackage") должен работать, может быть предпочтительнее написать info.getPackageName().equals("org.mypackage") (или startsWith, если вы хотите также включить подпакеты).

1
ColinD 4 Фев 2015 в 17:51

Я могу показать все классы, которые находятся в том же проекте, но для другого проекта, добавленного как зависимость в pom.xml, еще нет:

Решение для того, что у меня есть в том же проекте:

 public void getClassOfPackage() {

    final ClassLoader loader = Thread.currentThread()
            .getContextClassLoader();
    try {

        ClassPath classpath = ClassPath.from(loader); // scans the class path used by classloader
        for (ClassPath.ClassInfo classInfo : classpath.getTopLevelClasses("org.mypackage")) {
          System.out.println(classInfo.getSimpleName()+" <==> "+classInfo.getPackageName());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

}

public static void main(String[] args) {
    new TestMain().getClassOfPackage();
}
2
TinyOS 5 Фев 2015 в 08:53