Как заставить Java serviceLoader из внешней библиотеки работать

Я работаю над плагином для стороннего программного обеспечения, который довольно недокументирован. Для плагина я использую внешнюю библиотеку (.jar), управляемую maven и позже выполняемую на сервере Tomcat. Все работало отлично, пока я не обновил до последней версии библиотеки, которая теперь использует java.util.serviceLoader для загрузки конкретной реализации интерфейса. При сборке мой проект имеет следующую структуру пакетов на сервере Tomcat:

mypluginPackage.jar
|
---META-INF
---lib
   |
   --- theExternalLibUsingServiceLoader.jar
      |
      ---META-INF
         |
         ---services
            |
            --- full.path.to.TheFactoryInterface
      ---external.lib.path
         |
         --- TheFactoryInterface.class
         --- TheConreteClass.class
   --- mypluginCore.jar
      |
      ---META-INF
      --- my.plugin.path
         |
         --- MyClassUsingTheExternalLib.class

Как видите, внешняя библиотека имеет правильную запись сервисов, которая необходима для serviceLoader, чтобы найти конкретный интерфейс в META-INF. Содержание full.path.to.TheFactoryInterface файл full.path.to.TheConcreteClass, что кажется законным.

Мой плагин (как пакет, так и ядро), однако, не содержит никакой информации META-INF.

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

То, что я уже пробовал, добавляет точно такое же services/full.path.to.TheFactoryInterface ко всем моим каталогам META-INF, которые не работают (я думаю, мне нужно будет изменить содержимое файла full.path.to.TheFactoryInterface, но я не уверен - из-за недокументированной структуры плагинов для стороннего программного обеспечения - как будет выглядеть правильный (относительный) путь).

Кто-нибудь может подсказать мне, что я здесь делаю неправильно и как это исправить, чтобы конкретный класс был найден в serviceLoader? В какую папку META-INF должна быть помещена папка services с ее содержимым, и следует ли мне изменить пути? Это ошибка вообще или я что-то упускаю совершенно иначе?

Я понимаю, что это очень особая тема, так как стороннее программное обеспечение неизвестно, но любая информация, зависящая от serviceLoader и его поведения при запуске через несколько jar-файлов с несколькими папками META-INF и в разных контекстах выполнения / classpath, будет принята с благодарностью.

1 ответ

Решение

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

Также я смог связаться со сторонними разработчиками инструментов и получить нужную мне информацию - это называется "социальная декомпиляция".

Все работает сейчас.

Другие вопросы по тегам