LINUX.ORG.RU

Как получить классы по имени пакета?

 ,


0

1

Голова уже не соображает, на стековерфлоу куча мнений как это сделать лучше. А мне просто хочется дать на вход имя пакета, а на выходе получить все его классы, включая классы подпакетов.

Приветствую библиотеки или ссылки на реализацию на github'е в каком-нибудь из фреймворков типа tapestry5 (но у меня не получается щас найти в каком место оно это делает).

★★★★★

Последнее исправление: foror (всего исправлений: 1)

эээ как tapestry5 относится к вопросу категории java core?

Добавь в мавен вот это:

<dependency>
    <groupId>org.reflections</groupId>
    <artifactId>reflections</artifactId>
    <version>0.9.10</version>
</dependency>

И используй однострочник:

Set<Class<? extends Object>> classes = new Reflections("ru.foror.monkeycode").getSubTypesOf(Object.class);

с тебя пиво амстел безалкогольное.

stevejobs ★★★★☆
()
Последнее исправление: stevejobs (всего исправлений: 1)
Ответ на: комментарий от stevejobs

Ох, нет уж https://github.com/ronmamo/reflections/blob/master/pom.xml

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

        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>${guava.version}</version>
        </dependency>

        <dependency>
            <groupId>org.javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>${javassist.version}</version>
            <optional>false
            </optional> <!-- case: when not actually scanning with javassist or if using {@link Reflections.collect()} -->
        </dependency>

tapestry5 тут при том, что в этом фреймворке все классы резолвятся по имени пакета, указал корневой пакет и оно само нашло все домены, сервисы и прочие утилиты.

foror ★★★★★
() автор топика
Ответ на: комментарий от stevejobs

В общем принял допинг и вытащил из этой либы вот это:

    public static enum DefaultUrlTypes implements UrlType {
        jarFile {
            public boolean matches(URL url) {
                return url.getProtocol().equals("file") && url.toExternalForm().contains(".jar");
            }

            public Dir createDir(final URL url) throws Exception {
                return new ZipDir(new JarFile(getFile(url)));
            }
        },

        jarUrl {
            public boolean matches(URL url) {
                return "jar".equals(url.getProtocol()) || "zip".equals(url.getProtocol()) || "wsjar".equals(url.getProtocol());
            }

            public Dir createDir(URL url) throws Exception {
                try {
                    URLConnection urlConnection = url.openConnection();
                    if (urlConnection instanceof JarURLConnection) {
                            return new ZipDir(((JarURLConnection) urlConnection).getJarFile());
                    }
                } catch (Throwable e) { /*fallback*/ }
                java.io.File file = getFile(url);
                if (file != null) {
                    return new ZipDir(new JarFile(file));
                }
                return null;
            }
        },

        directory {
            public boolean matches(URL url) {
                return url.getProtocol().equals("file") && !url.toExternalForm().contains(".jar") &&
                        getFile(url).isDirectory();
            }

            public Dir createDir(final URL url) throws Exception {
                return new SystemDir(getFile(url));
            }
        },

        jboss_vfs {
            public boolean matches(URL url) {
                return url.getProtocol().equals("vfs");
            }

            public Vfs.Dir createDir(URL url) throws Exception {
                Object content = url.openConnection().getContent();
                Class<?> virtualFile = ClasspathHelper.contextClassLoader().loadClass("org.jboss.vfs.VirtualFile");
                java.io.File physicalFile = (java.io.File) virtualFile.getMethod("getPhysicalFile").invoke(content);
                String name = (String) virtualFile.getMethod("getName").invoke(content);
                java.io.File file = new java.io.File(physicalFile.getParentFile(), name);
                if (!file.exists() || !file.canRead()) file = physicalFile;
                return file.isDirectory() ? new SystemDir(file) : new ZipDir(new JarFile(file));
            }
        },

        jboss_vfsfile {
            public boolean matches(URL url) throws Exception {
                return "vfszip".equals(url.getProtocol()) || "vfsfile".equals(url.getProtocol());
            }

            public Dir createDir(URL url) throws Exception {
                return new UrlTypeVFS().createDir(url);
            }
        },

        bundle {
            public boolean matches(URL url) throws Exception {
                return url.getProtocol().startsWith("bundle");
            }

            public Dir createDir(URL url) throws Exception {
                return fromURL((URL) ClasspathHelper.contextClassLoader().
                        loadClass("org.eclipse.core.runtime.FileLocator").getMethod("resolve", URL.class).invoke(null, url));
            }
        },

        jarInputStream {
            public boolean matches(URL url) throws Exception {
                return url.toExternalForm().contains(".jar");
            }

            public Dir createDir(final URL url) throws Exception {
                return new JarInputDir(url);
            }
        }
    }

Осталось почитать, что там у них за лицензия, чтобы не засудили или сделать рерайт )

foror ★★★★★
() автор топика

строго говоря, никак. package + class loader - может быть. но нужно смотреть конкретный class loader. в java.lang.ClassLoader нет нужных функций.

а в целом это убогий подход. используется теми, кому жить неможно без аннотаций.

dzidzitop ★★
()

В общем все оказалось еще проще, в 7-ке же есть FileSystems, поэтому не надо городить всякие велосипеды как это делает либа Reflections:

Enumeration<URL> resources = Ostov.class.getClassLoader().getResources(basePath);

...

if ("jar".equals(url.getProtocol())) {
    FileSystem fs = FileSystems.newFileSystem(url.toURI(), Collections.emptyMap());
    startDir = fs.getPath(basePath);
}
else {
    startDir = Paths.get(url.toURI());
}

// Ну а дальше 
Files.walkFileTree(startDir, new SimpleFileVisitor<Path>() {
...
})
foror ★★★★★
() автор топика
Последнее исправление: foror (всего исправлений: 3)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.