Не удается загрузить класс, но может импортировать работает нормально - PullRequest
1 голос
/ 05 февраля 2020

У меня есть этот scala код, который возвращает пустой итератор

val i = ServiceLoader.load(Class.forName("io.grpc.netty.NettyChannelProvider"), classOf[ManagedChannelProvider].getClassLoader )

, что эквивалентно java code

Iterable i = ServiceLoader.load(Class.forName("io.grpc.netty.NettyChannelProvider"), ManagedChannelProvider.class.getClassLoader )

Проект строится нормально, но во время выполнения это повторяется i всегда пусто. Как мне сделать так, чтобы он загружал реальный класс?

Кроме того, когда мы предоставляем все зависимости во время выполнения, а не включаем их, это также работает.

1 Ответ

2 голосов
/ 05 февраля 2020

Я думаю, вы не понимаете, для чего нужен ServiceLoader.

Смысл serviceloader - предоставить ему интерфейс, а затем serviceloader возвращает экземпляр (созданный путем вызова publi c no- конструктор args) каждого типа, «зарегистрированного» как поставщик услуг для этого интерфейса.

Это выполняется путем сканирования всего пути к классам для файла META-INF / services / io.grp c .netty. NettyChannelProvider (и вы никогда не должны использовать Class.forName для этого; вы должны просто использовать: ServiceLoader.load(ThatInterface.class); если это ошибка времени компиляции, потому что интерфейс не находится в вашем пути к классам, то исправьте это; serviceloader не имеет ничего общего с волшебное исправление проблем с classpath).

Такие файлы (можно найти любое число) состоят из текста; одно полное имя класса в строке. Сервисный загрузчик загружает каждый указанный класс, вызывая его конструктор publi c (и если он не существует, это будет ошибкой; они должны быть там, чтобы использовать сервисный загрузчик).

NettyChannelProvider не интерфейс, это реализация; у вас все получилось.

Если вы действительно пытаетесь трактовать NCP как базовый интерфейс и ищете его реализации, то эти реализации должны [A] находиться в пути к классам выполнения поскольку этот код выполняется или не будет найден, и [B] эти реализации должны быть в jar-файлах или других записях пути к классам, которые имеют этот файл META-INF / services / io.grp c .netty.NettyChannelProvider. Если этого нет, serviceloader ничего не делает.

Вот что такое serviceloader: удобный читатель для META-INF/services/fully.qualified.name.of.the.base.Interface файлов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...