mirror of
https://gitee.com/devlive-community/datacap.git
synced 2024-12-01 19:48:14 +08:00
feat(plugin): delete redundant dependencies of convert and fix version number acquisition rules
This commit is contained in:
parent
5297c22fca
commit
c7cda15d42
@ -25,6 +25,7 @@
|
||||
<dependency>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap-convert-spi</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
|
@ -25,6 +25,7 @@
|
||||
<dependency>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap-convert-spi</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
|
@ -25,6 +25,7 @@
|
||||
<dependency>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap-convert-spi</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
|
@ -25,6 +25,7 @@
|
||||
<dependency>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap-convert-spi</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
|
@ -23,6 +23,10 @@ public class PluginConfigure
|
||||
// Auto cleanup, only effective when unloading
|
||||
public boolean autoCleanup;
|
||||
|
||||
// 同一目录下多个插件是否共享类加载器
|
||||
// Whether multiple plugins in the same directory share the class loader
|
||||
public boolean shareClassLoaderWhenSameDir;
|
||||
|
||||
public static PluginConfigure defaultConfig()
|
||||
{
|
||||
return PluginConfigure.builder()
|
||||
|
@ -437,7 +437,7 @@ public class PluginManager
|
||||
else {
|
||||
// 如果是目录则遍历加载
|
||||
// Load plugins from directory
|
||||
try (Stream<Path> paths = Files.walk(pluginsPath, config.getScanDepth())) {
|
||||
try (Stream<Path> paths = Files.walk(pluginsPath, config.getScanDepth() == 0 ? 1 : config.getScanDepth())) {
|
||||
paths.filter(Files::isDirectory)
|
||||
.peek(path -> log.debug("Scanning plugin directory: {}", path))
|
||||
.filter(path -> !path.equals(pluginsPath))
|
||||
@ -466,18 +466,47 @@ public class PluginManager
|
||||
String pluginVersion = VersionUtils.determinePluginVersion(pluginDir);
|
||||
log.debug("Found plugin version: {}", pluginVersion);
|
||||
|
||||
// 创建插件专用类加载器
|
||||
// Create plugin-specific class loader
|
||||
PluginClassLoader loader = PluginClassLoaderUtils.createClassLoader(
|
||||
pluginDir,
|
||||
pluginBaseName,
|
||||
pluginVersion
|
||||
);
|
||||
PluginClassLoader loader;
|
||||
if (config.shareClassLoaderWhenSameDir) {
|
||||
log.info("Use shared ClassLoader for plugin: {} at {}", pluginBaseName, pluginDir);
|
||||
// 多个插件在同一目录下,使用同一个类加载器
|
||||
// Multiple plugins in the same directory, use the same class loader
|
||||
loader = pluginClassLoaders.computeIfAbsent(
|
||||
pluginDir.toString(),
|
||||
k -> {
|
||||
try {
|
||||
return PluginClassLoaderUtils.createClassLoader(pluginDir, pluginBaseName, pluginVersion);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("Failed to create ClassLoader for plugin: {} at {}", pluginBaseName, pluginDir, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
log.info("Use independent ClassLoader for plugin: {} at {}", pluginBaseName, pluginDir);
|
||||
// 创建插件专用类加载器
|
||||
// Create plugin-specific class loader
|
||||
loader = PluginClassLoaderUtils.createClassLoader(
|
||||
pluginDir,
|
||||
pluginBaseName,
|
||||
pluginVersion
|
||||
);
|
||||
}
|
||||
|
||||
if (loader == null) {
|
||||
log.error("Failed to create ClassLoader for plugin: {} at {} skipped", pluginBaseName, pluginDir);
|
||||
return;
|
||||
}
|
||||
|
||||
List<Plugin> modules = PluginContextManager.runWithClassLoader(loader, () -> PluginLoaderFactory.loadPlugins(pluginDir));
|
||||
|
||||
for (Plugin module : modules) {
|
||||
PluginContextManager.runWithClassLoader(loader, () -> {
|
||||
log.debug("Loader version: {}", loader.getPluginVersion());
|
||||
log.debug("Module loader version: {}", module.getPluginClassLoader().getPluginVersion());
|
||||
|
||||
// 为每个插件模块创建独立的注入器
|
||||
// Create separate injector for each plugin module
|
||||
Injector pluginInjector = Guice.createInjector(module);
|
||||
@ -486,7 +515,12 @@ public class PluginManager
|
||||
String pluginName = module.getName();
|
||||
// 保存类加载器信息
|
||||
// Save class loader information
|
||||
pluginClassLoaders.put(pluginName, loader);
|
||||
if (config.shareClassLoaderWhenSameDir) {
|
||||
pluginClassLoaders.putIfAbsent(pluginName, loader);
|
||||
}
|
||||
else {
|
||||
pluginClassLoaders.put(pluginName, loader);
|
||||
}
|
||||
|
||||
PluginMetadata pluginMetadata = PluginMetadata.builder()
|
||||
.name(pluginName)
|
||||
@ -510,8 +544,8 @@ public class PluginManager
|
||||
|
||||
plugins.put(pluginName, pluginMetadata);
|
||||
|
||||
log.info("Install plugin: [ {} ] type [ {} ] version [ {} ] loader [ {} ] from source [ {} ]",
|
||||
pluginName, module.getType().getName(), module.getVersion(), pluginMetadata.getLoaderName(), pluginDir);
|
||||
log.info("Install plugin: [ {} ] type [ {} ] version [ {} ] loader [ {} ] from source [ {} ] loader name [ {} ]",
|
||||
pluginName, module.getType().getName(), module.getVersion(), pluginMetadata.getLoaderName(), pluginDir, loader.getName());
|
||||
|
||||
return null;
|
||||
});
|
||||
|
@ -14,6 +14,8 @@ import java.net.URLClassLoader;
|
||||
public class PluginClassLoader
|
||||
extends URLClassLoader
|
||||
{
|
||||
@Getter
|
||||
private final String name;
|
||||
|
||||
@Getter
|
||||
private final String pluginName;
|
||||
@ -26,6 +28,7 @@ public class PluginClassLoader
|
||||
super(urls, parent);
|
||||
this.pluginName = pluginName;
|
||||
this.pluginVersion = pluginVersion;
|
||||
this.name = String.join("-", "loader", pluginName.toLowerCase(), pluginVersion.toLowerCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,9 +1,14 @@
|
||||
package io.edurt.datacap.plugin.utils;
|
||||
|
||||
import io.edurt.datacap.plugin.Plugin;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
@ -176,14 +181,14 @@ public class VersionUtils
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (Path jarPath : jarFiles) {
|
||||
String version = readVersionFromJar(jarPath);
|
||||
String version = readVersionFromPluginJar(jarPath);
|
||||
if (version != null) {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (pluginPath.toString().endsWith(".jar")) {
|
||||
return readVersionFromJar(pluginPath);
|
||||
return readVersionFromPluginJar(pluginPath);
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
@ -192,6 +197,77 @@ public class VersionUtils
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read version from a JAR file, but only if it contains a Plugin class
|
||||
*/
|
||||
private static String readVersionFromPluginJar(Path jarPath)
|
||||
{
|
||||
try (JarFile jarFile = new JarFile(jarPath.toFile())) {
|
||||
// 首先检查是否包含 Plugin 类的实现
|
||||
// Check if the JAR contains a Plugin class
|
||||
if (!containsPluginClass(jarFile)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO: 如果是插件JAR,则从文件名中提取版本
|
||||
// TODO: If the JAR is a plugin JAR, extract the version from the file name
|
||||
String fileName = jarPath.getFileName().toString();
|
||||
|
||||
// 如果文件名中没有版本,尝试从 MANIFEST.MF 读取
|
||||
// If the version is not in the file name, try to read it from the MANIFEST.MF
|
||||
Manifest manifest = jarFile.getManifest();
|
||||
if (manifest != null) {
|
||||
String version = getVersionFromManifest(manifest);
|
||||
if (version != null) {
|
||||
log.debug("Found version {} from plugin JAR manifest: {}", version, fileName);
|
||||
return version;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
log.debug("Failed to read from JAR: {}", jarPath, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if JAR contains a Plugin class implementation
|
||||
*/
|
||||
private static boolean containsPluginClass(JarFile jarFile)
|
||||
{
|
||||
try {
|
||||
// 使用临时类加载器来加载和检查类
|
||||
// Use a temporary class loader to load and check the class
|
||||
try (URLClassLoader classLoader = new URLClassLoader(
|
||||
new URL[] {new File(jarFile.getName()).toURI().toURL()}, Plugin.class.getClassLoader())) {
|
||||
|
||||
return jarFile.stream()
|
||||
.filter(entry -> entry.getName().endsWith(".class"))
|
||||
.anyMatch(entry -> {
|
||||
String className = entry.getName()
|
||||
.replace('/', '.')
|
||||
.replace('\\', '.')
|
||||
.replace(".class", "");
|
||||
try {
|
||||
Class<?> clazz = classLoader.loadClass(className);
|
||||
return Plugin.class.isAssignableFrom(clazz) &&
|
||||
!Modifier.isAbstract(clazz.getModifiers()) &&
|
||||
!clazz.equals(Plugin.class);
|
||||
}
|
||||
catch (ClassNotFoundException | NoClassDefFoundError e) {
|
||||
// 忽略加载失败的类
|
||||
// Ignore classes that fail to load
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
log.debug("Failed to check for Plugin class in JAR: {}", jarFile.getName(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read version from a JAR file
|
||||
*/
|
||||
|
@ -116,6 +116,10 @@
|
||||
<artifactId>datacap-plugin</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap-convert-spi</artifactId>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>io.edurt.datacap</groupId>-->
|
||||
<!-- <artifactId>datacap-jdbc-clickhouse</artifactId>-->
|
||||
|
@ -33,7 +33,6 @@ public class PluginConfiguration
|
||||
Path projectRoot = PluginPathUtils.findProjectRoot();
|
||||
io.edurt.datacap.plugin.PluginConfigure config = io.edurt.datacap.plugin.PluginConfigure.builder()
|
||||
.pluginsDir(PluginPathUtils.appendPath("plugins"))
|
||||
.scanDepth(2)
|
||||
.build();
|
||||
|
||||
// 开发模式下生效
|
||||
|
@ -82,34 +82,9 @@
|
||||
<version>${datacap.influxdb.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- Support convert -->
|
||||
<dependency>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap-convert-txt</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap-convert-json</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap-convert-none</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap-convert-csv</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.edurt.datacap</groupId>
|
||||
<artifactId>datacap-convert-xml</artifactId>
|
||||
<artifactId>datacap-convert-spi</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
@ -15,6 +15,8 @@
|
||||
|
||||
<properties>
|
||||
<clickhouse-jdbc.version>0.6.5</clickhouse-jdbc.version>
|
||||
<httpclient5.version>5.3.1</httpclient5.version>
|
||||
<lz4.version>1.8.0</lz4.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@ -37,13 +39,13 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents.client5</groupId>
|
||||
<artifactId>httpclient5</artifactId>
|
||||
<version>5.3.1</version>
|
||||
<version>${httpclient5.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.lz4</groupId>
|
||||
<artifactId>lz4-java</artifactId>
|
||||
<version>1.8.0</version>
|
||||
<version>${lz4.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user