Ситуация
Я разрабатываю приложение, которое использует URLClassLoader и ServiceLoader Java для загрузки файлов jar. Внутри этих файлов jar находится провайдер, реализующий мой интерфейс. Структура папок описана в этом сообщении oracle, что означает тот:
- Интерфейс находится в том же каталоге, что и класс, реализующий интерфейс в плагине (com.x.projectname.plugin.IInterface.java). В подключаемом модуле интерфейс и реализующий его класс находятся в папке com.x.projectname.plugin.
- В подключаемом модуле есть каталог resources.META-INF.services с одним файлом в нем: com.x.projectname.plugin.IInterface со следующим содержимым: com.x.projectname.plugin.ClassThatImplementsIInterface.
При запуске на моем локальном компьютере (протестировано с Oracle JDK 1.8 162 и OpenJDK 1.8 171) плагин загружается нормально, и приложение может использовать плагин по своему усмотрению.
Проблема
При запуске основного приложения в контейнере докеров он не может загрузить нужный плагин. Контейнер Docker имеет папку на машине, смонтированную внутри него, где находится плагин. Образ докера приложения использует openjdk: 8-jdk-alpine, но проблема сохраняется независимо от того, использую я версию alpine или нет.
При попытке загрузить подключаемый модуль с помощью Serviceloader.load () (см. ServiceLoader.load (InterfaceName.class, загрузчик ClassLoader)
происходит сбой со следующей ошибкой: Provider com.x.projectname.plugin.InterfaceImplementingClass не является подтипом.
Вот соответствующая часть трассировки стека:
Caused by: java.util.ServiceConfigurationError: com.x.projectname.plugin.IInterface: Provider com.x.projectname.plugin.ImplementingClass not a subtype
at java.util.ServiceLoader.fail(ServiceLoader.java:239) ~[na:1.8.0_151]
at java.util.ServiceLoader.access$300(ServiceLoader.java:185) ~[na:1.8.0_151]
at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:376) ~[na:1.8.0_151]
at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404) ~[na:1.8.0_151]
at java.util.ServiceLoader$1.next(ServiceLoader.java:480) ~[na:1.8.0_151]
at com.x.projectname.loader.PluginLoader.loadPlugins(PluginLoader.java:118) ~[classes!/:na]
at com.x.projectname.loader.PluginLoader.initializePluginLoading(PluginLoader.java:67) ~[classes!/:na]
at com.x.projectname.service.PluginService.<init>(PluginService.java:37) ~[classes!/:na]
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_151]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_151]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_151]
Есть идеи, почему он не загружает плагины при запуске внутри контейнера Docker?
ИЗМЕНИТЬ 1. Dockerfile и команда запуска docker
FROM openjdk:8-jdk-alpine
ARG JAR_FILE
ADD ${JAR_FILE} /CICD-dashboard.jar
# Remote debugging port for intelliJ == address
EXPOSE 50505
ENTRYPOINT [ "java", "-Xrunjdwp:transport=dt_socket,address=50505,suspend=n,server=y", "-jar", "/X-project.jar"]
Команда запуска докера:
docker run -d -v /home/folder/pluginfolder:/pluginfolder -p=50505:50505 image-name
docker run
илиdocker-compose.yml
в зависимости от того, что вы использовали для запуска контейнера. - person Saqib Ahmed   schedule 26.04.2018java -jar ..
, он будет работать? - person Saqib Ahmed   schedule 26.04.2018docker rmi
и создать новый образ. Если он работает на вашем компьютере сjava -jar
, он также должен работать в контейнере докера с теми же аргументами. - person Saqib Ahmed   schedule 26.04.2018