В JDK9 и выше все банки являются «модулями». Если у них нет есть определение модуля (которое вы создаете, создав файл с именем module-info.java
и помещая объявление модуля внутри), его имя - «безымянный модуль @whwhat», он экспортирует все свои пакеты, и может получить доступ ко всему, экспортированному любым другим модулем (в модуле-говорит: он «читает» все). Это означает, что если all ваши зависимости classpath являются такими безымянными модулями, они все экспортируют все, и все они читают все, таким образом, все они могут получить доступ к чему-либо, помеченному public
, от кого-либо еще - как это работает в JDK8, и таким образом, почему все это совместимо.
Чтобы было понятно: в JDK9 для кода в модуле (jar) A для доступа к методу, классу или полю из модуля (jar) B, затем в дополнение к обычному модификаторы доступа (ключевое слово public
), B необходимо «экспортировать» этот пакет, а A должен прочитать этот модуль, иначе он не работает. Если вы явно не пишете файлы информации о модуле для какой-либо из сторон, ну, тогда вы получаете поведение по умолчанию: «экспортировать все» и «читать все», что возвращает нас к сценарию JDK8: вещь должна быть отмечена public
, и тогда вы можете получить к нему доступ.
На самом деле я не рекомендую вам создавать этот файл информации модуля; это большой шаг, который вы должны предпринять только после того, как познакомитесь с модульной системой.
Ошибка означает, что «тип сервиса» [1] не «доступен» [2] для «неназванного модуля» @ 3754a4bf "[3]. Давайте разберем это на части:
[1] загрузчик сервисов работает, определяя интерфейс, который реализует «сервис-провайдер», и класс, использующий загрузчик сервисов, затем заканчивается кучей экземпляров этого интерфейса; каждый представляет одну реализацию. Это Foo
в ServiceLoader.load(Foo.class)
.
[2], «доступный» для модуля, говорит: либо код, которому это необходимо, явно не «читал» его, либо код, который его не экспортировал it.
[3] 'неназванное module@3754abf' - это имя модуля, который пытается получить к нему доступ.
Взяв все это вместе, это означает: вы работаете под ложным предположения: Что бы ни содержал jar в вашем интерфейсе сервиса (о котором я говорил * 1026), это NOT неназванный модуль или, возможно, не опубликован c. Обратите внимание, что если это интерфейс publi c внутри класса not-publi c (то есть: /* package private */ class Example { public interface MyServiceInterface {} }
), то он, вероятно, все еще считается «не опубликован c достаточно».
Если это именованный модуль (что означает: у него есть файл module-info.java
), затем экспортируйте пакет, в котором находится интерфейс службы. См. любое руководство (название системы модулей java) о том, как это настроить. Если это не так, убедитесь, что это интерфейс publi c или абстрактный класс, а если он внутри какого-то другого типа, убедитесь, что это тоже publi c. Если это не так, проверьте ваши пути к классам; javac довольно непреклонен, что один из этих двух случай.