Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> поиск классов определенного интерфейса в пакете 
V
    Опции темы
ALKS
Дата 21.4.2006, 11:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 354
Регистрация: 22.3.2006

Репутация: 1
Всего: 11



Задача примерно такая: 
Известно имя пакета (ну скажем net.mycoolproject.sypertool.*) 
Известно что в этом пакете могут быть классы имплементирующее определённый интерфейс (и более того скажеи все такие классы, используя Java 5, аннотированы определенным образом)
Где пакет находиться неизвестно. (ну понятно что он где-то возможно внутри какого-то jar в classpath или jre/lib/ext или далее по списку возможных мест)
Известно что искомые классы могут быть еще не загружены. т.е. искать в списке загруженных лоадером классов не получиться...
Нужно все такие классы найти.

Понятно что можно проверить все jar-ы (и не только) во всех местах, выщемить таки нужное место где наш пакет, пробежаться по всем классам внутри него... трудно и не-изящно... smile

Есть ли другие пути? можно ли скажем вынудить загрузчик загрузить все классы в пакете(тогда хоть искать физическое расположение пакета не придеться)? можно ли получить список всех классов в пакете проаннатированных определенным образом? хоть что не будь? 
PM   Вверх
powerOn
Дата 21.4.2006, 12:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 47
Всего: 159



С пакетами можно работать через java.lang.Package. Может он чем поможет... 


--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
ALKS
Дата 21.4.2006, 13:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 354
Регистрация: 22.3.2006

Репутация: 1
Всего: 11



Изучал я его... правда глубоко тестовый код не писал(ночью юуду щас времени нету...) он может вернуть информацию о пакете по имени включая аннотации самого пакета(если я верно понял) и последнее интересно, ведь в эту анотацию пакета можно в общем-то вписать интересующие нас классы из пакета. на то и мета-данные. правда не очень понятно как можно аннотировать сам пакет... может кто-то подбросит пример? 
PM   Вверх
COVD
Дата 21.4.2006, 15:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 17
Всего: 43



Понятно, что вам прежде всего надо решить вашу задачу. Но все-таки любопытно, а для чего это? В какого класса приложениях или ситуациях такая необходимость возникает? 
PM MAIL   Вверх
ALKS
Дата 21.4.2006, 15:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 354
Регистрация: 22.3.2006

Репутация: 1
Всего: 11



Грубо говоря - плагины. куча мелких и не очень классов реализующих определенный интерфейс и раскиданных по разным пакетам и даже jar. есть несколько инсталиций определенного приложения которое грузит их в момент запуска(однократная операци (по этому нестрашно если оно будет запускаться даже пару минут) и потом использует. Само приложение знает только об интефейсе естественно. Конечно ничего не мешает просто перечислить все используемы классы в конфигурациооных файлах, например. Но лень - 40 строк можно заменить тремя... с именами пакетов smile 
PM   Вверх
Stampede
Дата 21.4.2006, 20:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гносеолог
**


Профиль
Группа: Участник Клуба
Сообщений: 963
Регистрация: 25.4.2005
Где: Calgary, Alberta, Canada

Репутация: 24
Всего: 144



Может вот это придаст мыслям некоторое направление?

Я тоже как-то думал о плагинной архитектуре для одной проги. Понятно, что там пахло своим загрузчиком, менеджером плагинов, рефлексией и пр. Убивало то, что стартап правращался в весьма длительную процедуру: как ни крути, а надо прошерстить весь classpath и не только.

И вот думал я, значить, думал, и вдруг пришло решение: а надо чекать не все места, а только изменения! То есть идея такая. В самый первый раз проверяется все что можно - и по результатам этой проверки генерится XML-описатель всех найденных плагинов. После этого при каждом последующем запуске сравнивается текущий classpath с ранее сохраненным, и процедура повторяется только для новых путей. Для всех остальных проверка осуществляется только на наличие изменений. Результаты снова записываются в описатель.

Таким же макаром можно было бы реализовать механизм горячего развертывания плагинов: слушать изменения в директориях и запускать процедуру поиска.

Прогу я тогда так и не собрался сделать, а вот недавно наткнулся на одну библиотечку, которая, возможно, оказалась бы хорошим подспорьем в реализации этого механизма. Назвается Java Plugin Framework, находится вот здесь: http://jpf.sourceforge.net/.

Посмотри. может как-то сгодится.
 
PM WWW   Вверх
ALKS
Дата 21.4.2006, 21:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 354
Регистрация: 22.3.2006

Репутация: 1
Всего: 11



Stampede, спасибо. идея не дурственна, но смысл в том что мы лентяи и вообще не хотим замарачиваться с поиском smile

Чем закончились исследования с классом Package, если кому-то интересно:

1. создаем ананотацию нужного нам вида. ну например:
Код

package net.mycoolproject.sypertool;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PACKAGE)
public @interface CoolTest {

    String comment(); 
}


2. создаем фаил package-info.java (помещаем его внутри нашего пакета, естественно) следующего содержания
Код

@CoolTest(comment="Super test") 
package net.alexei.validator.configcheck;

Если кто-то не догадался, то этот спицифический класс со строго таким именем используеться для анатоций пакета (и кроме того еще для javadoc но это уже другая тема)

3. теперь, там где вам хочется вы можете вызвать такой вот код:
Код

Package pack = Package.getPackage("net.mycoolproject.sypertool");
        
if (pack != null ) {
    CoolTest сoolTest = pack.getAnnotation(CoolTest.class);
    if (сoolTest != null) {
        System.out.println(сoolTest.comment());
    }
}

Что оно вам вернет вы наверняка догадались smile

Остальное дело техники. никто не мешает вам в этой анотации к пакету перечислить(например массивом) интересующие вас объекты класса Class smile. Т.е. сам пакет заботиться о том чтобы проинформировать вас например о том какие классы в нем есть. Этот путь конечно далек от моей мечты, потому что требует немножко специальной работы над пакетом с "плагинами", но хоть что-то.
 
PM   Вверх
LSD
Дата 22.4.2006, 00:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Вот это я понимаю smile

Добавил в FAQ. 


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
ALKS
Дата 22.4.2006, 09:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 354
Регистрация: 22.3.2006

Репутация: 1
Всего: 11



LSD, там ошибка в package-info.java неправильное имя пакета - должно быть net.mycoolproject.sypertool. Раз уж ты в FAQ это запихнул, то надо исправить smile 
PM   Вверх
LSD
Дата 22.4.2006, 10:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Fixed 


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
ALKS
Дата 22.4.2006, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 354
Регистрация: 22.3.2006

Репутация: 1
Всего: 11



Возвращаясь собственно к теме топа, вот что получилось окончательно (мне понравился результат по-этому очень хочется поделиться smile )

аннотация (net.mycoolproject.IMonsterPlugin это интерфейс, для чистоты эксперемента он вынесен в другой пакет ):
Код

package net.mycoolproject.sypertool;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PACKAGE)
public @interface @CoolTest{
    Class<? extends net.mycoolproject.IMonsterPlugin>[] monsters();
}


package-info.java (Hydra,Cerberus,Cyclop - это классы из нашего пакета, имплементирующие net.mycoolproject.IMonsterPlugin ):
Код

@CoolTest(monsters={Hydra.class,Cerberus.class,Cyclop.class}) 
package net.mycoolproject.sypertool;


использование (предпологаеться что Hydra,Cerberus,Cyclop имеют конструктор без параметров, а net.mycoolproject.IMonsterPlugin имеет единственный метод: beCool() ):
Код


Package pack = Package.getPackage("net.mycoolproject.sypertool");    
if (pack != null ) {
    CoolTest a = pack.getAnnotation(CoolTest.class);
    if (a != null) {
        for (Class<? extends net.mycoolproject.IMonsterPlugin> c : a.checkClasses() ) {
            //создаем и используем объект найденного класса.
            net.mycoolproject.IMonsterPlugin monster = c.getConstructor(null).newInstance();
            check.beCool();
        }
    }
}


Вот. А теперь внимательно посмотрим на то, что получилось:
Уже на стадии компиляции проверяеться, что во-первых все перечисленные в аннотации классы существуют в нашем пакете и, что во-вторых они действительно имплементируют нужный нам интерфейс! это гораздо больше чем, например, имя класса указаное в конфиге, это дало много информации вызывающей программе и подстраховало нас от ряда ошибок времени выполнения.

А Class.forName() в вызывающей програме-то нету, ну разве не мило? smile

P.S. вообще ИМХО аннотации - самое мощное новшество в Java 5. в связке с рефлексией можно чудеса творить (и JUnit 4 тому живой пример)
P.P.S. возвращаясь к теме топа - всё, это максимум что можно вытянуть из анотаций для поставленной задачи. единственное с чем можно по-извращаться - автоматическая генерация package-info.java. Ну... я конечно лентяй, но уж не настолько smile
P.P.P.S. возвращаясь к теме топа - всё еще интересуют альтернативные пути решения проблеммы.... ??? 
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0968 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.