Как пройти через ресурсы класса Java?

Я знаю, что мы можем сделать что-то вроде этого:

Class.class.getResourceAsStream("/com/youcompany/yourapp/module/someresource.conf")

чтобы прочитать файлы, которые упакованы в нашем файле jar.

У меня много проблем в googled, и я, конечно же, не использую правильные условия; что я хочу сделать, это перечислить доступные ресурсы, например:

Class.class.listResources("/com/yourcompany/yourapp")

Это должно вернуть список ресурсов, находящихся внутри пакета com.yourcompany.yourapp.*

Это возможно? Любые идеи о том, как это сделать, если это невозможно сделать так же легко, как я показал?

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

Ответ 1

Для ресурсов в JAR файле работает что-то вроде этого:

URL url = MyClass.class.getResource("MyClass.class");
String scheme = url.getProtocol();
if (!"jar".equals(scheme))
  throw new IllegalArgumentException("Unsupported scheme: " + scheme);
JarURLConnection con = (JarURLConnection) url.openConnection();
JarFile archive = con.getJarFile();
/* Search for the entries you care about. */
Enumeration<JarEntry> entries = archive.entries();
while (entries.hasMoreElements()) {
  JarEntry entry = entries.nextElement();
  if (entry.getName().startsWith("com/y/app/")) {
    ...
  }
}

Вы можете сделать то же самое с ресурсами, "взорванными" в файловой системе или во многих других репозиториях, но это не так просто. Вам нужен конкретный код для каждой схемы URL, которую вы хотите поддержать.

Ответ 2

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

(Этот вопрос похож, кстати.)

Ответ 3

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

Ответ 4

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

List<String> resourceNames;
try (ScanResult scanResult = new ClassGraph()
            .whitelistPaths("com/yourcompany/yourapp")
            .scan()) {
    resourceNames = scanResult.getAllResources().getNames();
}

Ответ 5

Я обычно использую

getClass().getClassLoader().getResourceAsStream(...)

но я сомневаюсь, что вы можете перечислить записи из пути к классам, не зная их априори.