我有一个Maven模块A中定义的SPI接口. In Module B,这是一个 spring-boot 应用程序,我已经定义了META-INF/services/<interface-named-file>
.
In Module A,我有这个代码。
public class NotificationResultPluginProvider {
private static NotificationResultPluginProvider notificationResultPluginProvider;
private NotificationResultPlugin notificationResultPlugin;
private NotificationResultPluginProvider() {
final ServiceLoader<NotificationResultPlugin> loader = ServiceLoader.load(NotificationResultPlugin.class);
final Iterator<NotificationResultPlugin> it = loader.iterator();
if (it.hasNext()) {
notificationResultPlugin = it.next();
}
}
public static synchronized NotificationResultPluginProvider getInstance() {
if (null == notificationResultPluginProvider) {
notificationResultPluginProvider = new NotificationResultPluginProvider();
}
return notificationResultPluginProvider;
}
public NotificationResultPlugin getNotificationResultPlugin() {
return notificationResultPlugin;
}
}
在模块 B - spring boot 应用程序 - 我有一个实现NotificationResultPlugin
界面。
现在这是泡菜。
当我从 intellij 运行启动应用程序时,我看到了(在下面的代码中)it.hasNext()
is true
and notificationResultPlugin
被发现。在这种情况下,我的应用程序按预期工作。
if (it.hasNext()) {
notificationResultPlugin = it.next();
}
但是当我使用 CLI 运行启动应用程序时,使用如下命令(注意我首先对 jar 进行放气,然后启动)
jar -xf <jar file>;
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=12341 -cp 'BOOT-INF/lib/*:BOOT-INF/classes' <main/class/fqn>;
Then it.hasNext()
is false
并且我在模块 B 中针对给定 SPI 的实现未找到。结果,我的应用程序没有按预期工作。我现在束手无策了。
其他相关信息:
我的 Spring Boot 应用程序不是 Web 应用程序。也就是说,我没有暴露任何休息终点。我只是使用spring-kafka
具有最小的依赖性。
我缺少什么?任何帮助表示赞赏。
找到解决方案
正如他们所说,当你不去尝试时,头脑会发挥最佳作用。
ServiceLoader 无法加载 SPI 实现,因为META-INF/services
当我启动应用程序时,目录不在类路径中。正确设置类路径就可以了。因此,这就是我需要做的改变。
-cp 'BOOT-INF/lib/*:BOOT-INF/classes:.'
请注意额外的点在最后。