Провайдер не является подтипом внутри контейнера Docker - PullRequest
0 голосов
/ 26 апреля 2018

Положение

Я разрабатываю приложение, которое использует Java URLClassLoader и ServiceLoader для загрузки файлов JAR. Внутри этих jar-файлов находится поставщик, который реализует мой интерфейс. Структура папок описана в в этом сообщении оракулом , что означает:

  • Интерфейс находится в том же каталоге, что и класс, реализующий интерфейс в плагине (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 оно не может загрузить нужный плагин. Контейнер Docker имеет папку на машине, смонтированную внутри, где находится плагин. В образе докера приложения используется openjdk: 8-jdk-alpine, но проблема остается, использую ли я альпийскую версию или нет.

При попытке загрузить плагин с помощью Serviceloader.load () (см. ServiceLoader.load (InterfaceName.class, загрузчик ClassLoader)

происходит сбой со следующей ошибкой: Поставщик 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:

docker run -d -v /home/folder/pluginfolder:/pluginfolder -p=50505:50505 image-name

1 Ответ

0 голосов
/ 01 мая 2018

Как оказалось, ответ был таким, как сказал Сакиб в комментарии: построить толстую банку. Я использовал shadowJar для этого: http://imperceptiblethoughts.com/shadow/#configuring_shadow.

...