У меня есть модуль, содержащий пакет com.temp
, который имеет интерфейс и реализацию этой службы - ServiceInterface
и ServiceImpl
. И у меня есть в моем модуле информация:
module temp {
exports com.temp;
provides com.temp.ServiceInterface with com.temp.ServiceImpl;
}
Это часть моего pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.22.0</version>
<executions>
<execution>
<id>integration-tests</id>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<skipTests>${skip.integration.tests}</skipTests>
</configuration>
</execution>
</executions>
</plugin>
А это мой TempIT
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
class TempIT {
@Test
void tempTest() {
System.out.println("JDKModulePath:" + System.getProperty("jdk.module.path")); //LINE Y
ServiceLoader<ServiceInterface> loader = ServiceLoader.load(ServiceInterface.class);
System.out.println(loader.findFirst().get().getString());//LINE X
}
}
LINE Y печатает: JDKModulePath:null
. На ЛИНИИ X я получаю java.util.NoSuchElementException: No value present
.
Как провести интеграционный тест сервиса JPMS? Можно ли сделать вне модуля, чтобы проверить модуль как one whole
, но без создания дополнительного модуля тестирования?
РЕДАКТИРОВАТЬ 1: Это реализация и интерфейс:
package com.temp;
public class ServiceImpl implements ServiceInterface {
@Override
public String getString() {
return "This is test string";
}
}
package com.temp;
public interface ServiceInterface {
public String getString();
}
@khmarbaise Редактировал вопрос.
Вы правильно создали файл в src/main/resources/META-INF/services/com.example.CodecFactory
? Что нужно для ServiceLoader
?
@khmarbaise, насколько мне известно, при использовании сервисов JPMS мы не создаем никаких файлов в мета-информации, так как все сервисы контролируются JPMS.
@khmarbaise Боюсь, я не могу с вами согласиться. ServiceLoader появился до JPMS и может быть настроен через файлы в meta-inf. Однако, если мы создадим эти файлы, мы выйдем из JPMS.
ServiceLoader не связан с JPMS, потому что это реализация механизма загрузки во время выполнения, которому нужен некоторый ресурс, чтобы определить, что это за реализация ... см. Документы ... (Опечатка в моем первом комментарии) ...
@khmarbaise При использовании модулей вы объявляете службы по-другому - с помощью директив provides
и uses
в module-info
. Однако вам все равно понадобятся файлы META-INF/services
, если вы используете не с модулями. Документация ServiceLoader
была обновлена в Java 9, чтобы охватить это.
Можете ли вы изменить тест, чтобы распечатать значение системного свойства "jdk.module.path"? Я подозреваю, что проблема в том, что поставщик услуг не находится на пути к модулю.
@AlanBateman Я редактировал вопрос, см. Класс TempIT.
Если я правильно прочитал, путь к модулю пуст. Я не знаю maven-failsafe-plugin, но он предполагает, что он не установил путь к модулю, он может помещать все в путь к классу, но по-прежнему отсутствует поставщик услуг. Кто-то, знакомый с maven-failsafe-plugin, может также предложить варианты отладки, чтобы выяснить, что он делает.
Кажется, это ошибка, поскольку отказоустойчивость не помещает модуль в путь к модулю. См. Вопрос https://issues.apache.org/jira/browse/SUREFIRE-1570
Покажите, пожалуйста, код реализации ServiceInterface и, конечно, интерфейс тоже будет полезен ...