Задать вопрос

Как считать список классов из пакета который находится в том же jar-файле что и программа?

Пишеться программа на java, которая должна обрабатывать картинки с помощью операторов.
Классы операторов считываються динамически из одного пакета в программе в массив классов.
Метод для считывания работает в консоле а в jar-файле не работает...

public class PackageClassList {
	public static List<Class<?>> getClasses( String pack ) throws Exception{
    	    	ClassLoader cl = PackageClassList.class.getClassLoader();
    	        String packageDir = pack.replaceAll("[.]", "/");
            	List<Class<?>> classes = new ArrayList<Class<?>>();
    	    	URL upackage = cl.getResource(packageDir);
    	    	InputStream in = (InputStream) upackage.getContent();
    	    	BufferedReader br = new BufferedReader(new InputStreamReader(in));
    	    	String line = null;
    	    	while ((line = br.readLine()) != null) {
    	    	    	if(line.endsWith(".class"))
    	    	    	classes.add(Class.forName( pack+"."+line.substring(0,line.lastIndexOf('.'))));
    	    	}
    	    	return classes;
    	}
}


вобще-то это учебный проект - делаю паралельно с подготовкой к OCPJP.

хочу сделать быстро и научиться чему нибудь...

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

моя идея была такая - пишу себе операторы, складываю в пакет oparators. Операторы наследуют у абстрактного класса AbstractOperator.
Программа автоматом читает пакет operators и грузит классы оттуда в массив. Из массвива делате dropbox, истанциирует операторы и пременяет их, полиморфизм, все красиво и т.д.

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

хочу все делать в Eclipse и не заморачиваться на копирование и упаковку операторов... настройку, конфигурацию...
откомпилировал, запаковал и все.
  • Вопрос задан
  • 4586 просмотров
Подписаться 3 Оценить 1 комментарий
Пригласить эксперта
Ответы на вопрос 2
Нет такого способа. Разве что какой-нибудь недокументированный.

Вместо этого рекомендую с использованием annotation processing, во время компиляции вашего проекта составить список классов и поместить его в отдельный файл. Стандартное расположение таких файлов - в META-INF/services/<имя интерфейса>. Загрузить экземпляры классов из этого списка можно с помощью класса ServiceLoader.

Ну или вручную этот список составлять.
Ответ написан
vlad20012
@vlad20012
Еще как можно. annotation processing - хорошая вещица, не немного не ответ на вопрос. Предположим, что есть причины его не использовать. Тогда обычно источник кода (code source), т.е. jar архив с классами, берется как файл, из него, как из zip архива, читается список файлов, и, если название файла соответствует определенному шаблону (например, находится в определенном пакете), загружается класс тем же названием. Получить code source можно как-то так:
getClass().getProtectionDomain().getCodeSource().getLocation();

Хотя, этим будет получено лишь расположение текущего класса. Все линкованные URL можно получить так:
((java.net.URLClassLoader)getClass().getClassLoader()).getURLs();

А дальше использовать ZipFile, читать список Entry, проверять соответствие шаблону.

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

Этот способ считается не очень хорошим, потому что классы могут загружаться не только из jar архивов. Как минимум, нужно учесть загрузку из директории, но в теории классы могут загружаться откуда угодно, а code source вполне может отсутствовать, т.е. getCodeSource() вернет null. Тем не менее, многие пользуются этим способом. Например, log4j загружает плагины таким образом, но annotation processing там тоже присутствует, комбинирование подходов таки никто не отменял.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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