Почему я могу загрузить класс из JAR, но не из ресурса?
Я использую банку, которая содержит только ClassPath
элемент для создания classpath для моего Java-приложения, и я столкнулся со странным поведением: я могу загрузить классы из JAR, упомянутых в ClassPath
элемент, но некоторые (или все) ресурсы отсутствуют.
Пример: мой full-classpath.jar
содержит только META-INF/MANIFEST.MF
с обычным содержанием и этой строкой:
ClassPath: foo-service.jar bar-service.jar service-main.jar
service-main.jar
содержит com.pany.project.Main
,
Когда я бегу java -cp full-classpath.jar com.pany.project.Main
, это работает.
Но foo-service.jar
а также bar-service.jar
содержат определения услуг в META-INF/services/....
Когда я призываю java.util.ServiceLoader
из модульного теста Maven, он может видеть как foo
и bar
оказание услуг. Когда я java -cp full-classpath.jar com.pany.project.Main -service foo
Я вижу пустой список услуг в моем журнале.
Хуже, когда я звоню Main.class.getClassLoader().getResources("META-INF/MANIFEST.MF")
Я получаю только манифест от full-classpath.jar
, Файлы манифеста из трех других JAR отсутствуют, что не имеет смысла, так как я могу загружать классы из этих JAR! Это также работает, когда я создаю весь путь к классам вручную. Это терпит неудачу, только когда я использую ClassPath
элемент в full-classpath.jar
,
Есть идеи, что может быть не так или как я могу это отладить?
Я использую Java 8.
1 ответ
Атрибут манифеста Class-Path
обрабатывается в sun.misc.URLClassPath.JarLoader.parseClassPath(URL, String)
, Этот метод вызывается один раз из sun.misc.URLClassPath.JarLoader.getClassPath()
, В начале getClassPath()
Вы можете найти этот код:
if (index != null) {
return null;
}
if (metaIndex != null) {
return null;
}
что означает: если ваш JAR-путь к классам содержит индекс или "мета-индекс" (что бы это ни было), Class-Path
атрибут игнорируется.
Я не могу сказать, почему Java все еще может загружать классы из JAR, упомянутых в Class-Path
атрибут, но удаление индекса устраняет проблему загрузки ресурса.