我是通过导入 mirai-core-jvm 和 mirai-core-api-jvm 和kotlin 相关的maven来构建项目的,是一个springboot项目,也写了相关的前端页面,现在想把功能单独抽出来写成插件,我在网上看了java怎么写插件,也做了个demo试了下,用的是java的spi思想(我看论坛里的kotlin写的插件格式都是一样的),下面是加载插件的类,也是网上找的
public class PluginLoader {
private static final Logger LOGGER = LoggerFactory.getLogger(PluginLoader.class);
public static List<IPluginService> loadPlugins() throws MalformedURLException {
List<IPluginService> plugins = new ArrayList<>();
File parentDir = new File(PLUGIN_PATH);
File[] files = parentDir.listFiles();
if (null == files) {
return Collections.emptyList();
}
// 从目录下筛选出所有jar文件
List<File> jarFiles = Arrays.stream(files)
.filter(file -> file.getName().endsWith(".jar"))
.collect(Collectors.toList());
URL[] urls = new URL[jarFiles.size()];
for (int i = 0; i < jarFiles.size(); i++) {
// 加上 "file:" 前缀表示本地文件
urls[i] = new URL("file:" + jarFiles.get(i).getAbsolutePath());
}
URLClassLoader urlClassLoader = new URLClassLoader(urls);
// 使用 ServiceLoader 以SPI的方式加载插件包中的 IPluginService 实现类
ServiceLoader<IPluginService> serviceLoader = ServiceLoader.load(IPluginService.class, urlClassLoader);
for (IPluginService iPluginService : serviceLoader) {
plugins.add(iPluginService);
LOGGER.info("插件 "+iPluginService.name() + " 加载成功");
}
return plugins;
}
下面是要实现的接口
public interface IPluginService {
/**
* 插件功能入口方法
*/
void service();
/**
* 插件名成,通常用于展示在界面
*
* @return 插件名称
*/
String name();
/**
* 表示当前插件的版本
*
* @return 插件版本号
*/
String version();
}
现在有个问题,当打包主程序时,如果使用
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.2.5.RELEASE</version>
</plugin>
</plugins>
</build>
打包,插件项目引用主程序打包出来的jar的时候,会在编译时就找不到对应的IPluginService
如果不用上面那段打包,插件项目就能正常打包,但是打包出来让主程序运行时会出现java.lang.NoClassDefFoundError,提示IPluginService 没有定义
我确定 插件META-INF/services 文件夹下的文件和文件内容没有写错,因为报错的那段是
//这是PluginLoader类的方法里的代码
ServiceLoader<IPluginService> serviceLoader = ServiceLoader.load(IPluginService.class, urlClassLoader);
我想问一下,如果非得是maven项目做主程序,插件项目该怎么引入主程序的jar才能让插件能正常运行?插件项目是普通的java项目和maven项目我都试过了。我上面的思想有没有哪里是错误的。还请大佬指点一下。谢谢!!