Как заставить 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 по умолчанию был неправильным.
Также я смог связаться со сторонними разработчиками инструментов и получить нужную мне информацию - это называется "социальная декомпиляция".
Все работает сейчас.