From b0463bb4de651a94d7dbdb4603bdd21752ccfd9f Mon Sep 17 00:00:00 2001 From: StarBlues Date: Sun, 28 May 2023 16:32:21 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8D=B8=E8=BD=BD=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=8D=A0=E7=94=A8=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gitee/starblues/utils/FilesUtils.java | 61 +++++++- .../gitee/starblues/utils/ObjectUtils.java | 14 +- .../loader/PluginResourceStorage.java | 47 +++++-- .../resource/loader/JarResourceLoader.java | 5 +- .../storage/AbstractResourceStorage.java | 23 +-- .../storage/CacheFastResourceStorage.java | 10 +- .../gitee/starblues/loader/jar/Handler.java | 24 +--- .../starblues/loader/jar/JarFileWrapper.java | 6 +- .../starblues/loader/utils/ResourceUtils.java | 43 ++++-- .../starblues/core/DefaultPluginManager.java | 25 ++-- .../starblues/core/PluginLauncherManager.java | 6 +- .../gitee/starblues/core/PluginManager.java | 6 +- .../descriptor/ComposeDescriptorLoader.java | 14 +- .../plugin/SpringPluginHookWrapper.java | 17 ++- .../involved/DefaultPluginLaunchInvolved.java | 13 +- .../operator/DefaultPluginOperator.java | 133 +++++++++++------- .../com/gitee/starblues/utils/LogUtils.java | 6 +- update.md | 4 +- 18 files changed, 307 insertions(+), 150 deletions(-) diff --git a/spring-brick-common/src/main/java/com/gitee/starblues/utils/FilesUtils.java b/spring-brick-common/src/main/java/com/gitee/starblues/utils/FilesUtils.java index 50c481d..34fa6ce 100644 --- a/spring-brick-common/src/main/java/com/gitee/starblues/utils/FilesUtils.java +++ b/spring-brick-common/src/main/java/com/gitee/starblues/utils/FilesUtils.java @@ -21,13 +21,15 @@ import com.gitee.starblues.common.PackageStructure; import java.io.File; import java.io.IOException; +import java.nio.file.Path; +import java.util.List; /** * 文件工具类 * * @author starBlues * @since 3.0.0 - * @version 3.1.0 + * @version 3.1.2 */ public class FilesUtils { @@ -232,5 +234,62 @@ public class FilesUtils { return path.startsWith(Constants.RELATIVE_SIGN); } + /** + * 判断两文件是否在同一个目录下 + * @param file1 文件1 + * @param file2 文件2 + * @return 所属目录 + */ + public static File sameParent(File file1, File file2){ + if(file1 == null || file2 == null){ + return null; + } + File parentFile = file1.getParentFile(); + if(parentFile.equals(file2.getParentFile())){ + return parentFile; + } + return null; + } + + /** + * 判断某个目录是否存在于根目录下 + * @param rootPath 根目录 + * @param comparePath 比较的目录 + * @return boolean + */ + public static boolean includePath(Path rootPath, Path comparePath){ + if(rootPath == null || comparePath == null){ + return false; + } + return comparePath.toString().startsWith(rootPath.toString()); + } + + /** + * 是否为子文件 + * @param rootFile rootFile + * @param childFile 子文件 + * @return boolean + */ + public static boolean isChildFile(List rootFile, File childFile){ + if(ObjectUtils.isEmpty(rootFile) || childFile == null || !childFile.exists()){ + return false; + } + for (String fileStr : rootFile) { + File file = new File(fileStr); + if(!file.exists()){ + continue; + } + File[] files = file.listFiles(); + if(files == null){ + continue; + } + for (File f : files) { + if(f.equals(childFile)){ + return true; + } + } + } + return false; + } } diff --git a/spring-brick-common/src/main/java/com/gitee/starblues/utils/ObjectUtils.java b/spring-brick-common/src/main/java/com/gitee/starblues/utils/ObjectUtils.java index fede520..7e0172c 100644 --- a/spring-brick-common/src/main/java/com/gitee/starblues/utils/ObjectUtils.java +++ b/spring-brick-common/src/main/java/com/gitee/starblues/utils/ObjectUtils.java @@ -25,7 +25,7 @@ import java.util.*; * * @author starBlues * @since 3.0.0 - * @version 3.0.0 + * @version 3.1.2 */ public class ObjectUtils { @@ -270,6 +270,18 @@ public class ObjectUtils { return false; } + public static boolean equalsElement(Object element, Object... objects) { + if (element == null || objects == null) { + return false; + } + for (Object obj : objects) { + if (Objects.equals(element, obj)) { + return true; + } + } + return false; + } + public static boolean nullSafeEquals(Object o1, Object o2) { if (o1 == o2) { return true; diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/PluginResourceStorage.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/PluginResourceStorage.java index 7af081c..67ec8ec 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/PluginResourceStorage.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/PluginResourceStorage.java @@ -25,6 +25,7 @@ import java.io.Closeable; import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -34,7 +35,7 @@ import java.util.concurrent.ConcurrentHashMap; * * @author starBlues * @since 3.0.0 - * @version 3.0.0 + * @version 3.1.2 */ public class PluginResourceStorage { @@ -45,11 +46,11 @@ public class PluginResourceStorage { * @param pluginId 插件id * @param pluginFileName 插件文件名称 */ - public static void addPlugin(String pluginId, String pluginFileName){ + public static void addPlugin(String pluginId, String pluginFileName, List libPath){ if(STORAGE_MAP.containsKey(pluginId)){ return; } - STORAGE_MAP.put(pluginId, new Storage(pluginFileName)); + STORAGE_MAP.put(pluginId, new Storage(pluginFileName, libPath)); } /** @@ -80,7 +81,7 @@ public class PluginResourceStorage { * @param file 插件文件 * @param jarFile 插件jar文件 */ - public static void addRootJarFile(File file, JarFile jarFile){ + public static void addRootJarFile(File file, JarFileWrapper jarFile){ STORAGE_MAP.forEach((k,v)->{ v.addRootJarFile(file, jarFile); }); @@ -91,9 +92,9 @@ public class PluginResourceStorage { * @param file 插件文件 * @return 插件jar文件 */ - public static JarFile getRootJarFile(File file){ + public static JarFileWrapper getRootJarFile(File file){ for (Storage value : STORAGE_MAP.values()) { - JarFile jarFile = value.getRootJarFile(file); + JarFileWrapper jarFile = value.getRootJarFile(file); if(jarFile != null){ return jarFile; } @@ -104,31 +105,37 @@ public class PluginResourceStorage { private static class Storage implements Closeable { private final String pluginFileName; - private final Map rootJarFileMap = new ConcurrentHashMap<>(); + private final List libPath; + private final Map rootJarFileMap = new ConcurrentHashMap<>(); private final Map> jarFileMap = new ConcurrentHashMap<>(); - public Storage(String pluginFileName) { + public Storage(String pluginFileName, List libPath) { this.pluginFileName = pluginFileName; + if(libPath == null){ + this.libPath = Collections.emptyList(); + } else { + this.libPath = libPath; + } } public void addJarFile(String name, AbstractJarFile jarFile){ if(name == null || jarFile == null){ return; } - if(name.contains(pluginFileName)){ + if(isAddFile(name)){ List jarFiles = jarFileMap.computeIfAbsent(name, k -> new ArrayList<>()); jarFiles.add(jarFile); } } - public void addRootJarFile(File file, JarFile jarFile){ + public void addRootJarFile(File file, JarFileWrapper jarFile){ String absolutePath = file.getAbsolutePath(); - if(absolutePath.contains(pluginFileName)){ + if(isAddFile(absolutePath)){ rootJarFileMap.put(file, jarFile); } } - public JarFile getRootJarFile(File file){ + public JarFileWrapper getRootJarFile(File file){ return rootJarFileMap.get(file); } @@ -145,15 +152,29 @@ public class PluginResourceStorage { IOUtils.closeQuietly(jarFile); } } - for (JarFile jarFile : rootJarFileMap.values()) { + for (JarFileWrapper jarFile : rootJarFileMap.values()) { if(jarFile == null){ continue; } + jarFile.canClosed(); IOUtils.closeQuietly(jarFile); } jarFileMap.clear(); rootJarFileMap.clear(); } + + private boolean isAddFile(String path){ + if(path.contains(pluginFileName)){ + return true; + } + for (String libPath : libPath) { + if(path.contains(libPath)){ + return true; + } + } + return false; + } + } diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/loader/JarResourceLoader.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/loader/JarResourceLoader.java index 48c4132..69d374b 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/loader/JarResourceLoader.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/loader/JarResourceLoader.java @@ -29,7 +29,7 @@ import java.util.jar.JarInputStream; * jar 资源加载者 * @author starBlues * @since 3.0.0 - * @version 3.1.1 + * @version 3.1.2 */ public class JarResourceLoader extends AbstractResourceLoader { @@ -75,6 +75,7 @@ public class JarResourceLoader extends AbstractResourceLoader { JarEntry jarEntry = null; while ((jarEntry = jarInputStream.getNextJarEntry()) != null) { if(excludeResource.exclude(jarEntry)){ + jarInputStream.closeEntry(); continue; } if(includeResource.include(jarEntry)){ @@ -84,8 +85,8 @@ public class JarResourceLoader extends AbstractResourceLoader { return getClassBytes(name, jarInputStream, false); }); resourceStorage.add(cacheResource); - jarInputStream.closeEntry(); } + jarInputStream.closeEntry(); } } finally { jarInputStream.close(); diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/storage/AbstractResourceStorage.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/storage/AbstractResourceStorage.java index 924633d..f915df5 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/storage/AbstractResourceStorage.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/storage/AbstractResourceStorage.java @@ -32,7 +32,7 @@ import java.util.*; * * @author starBlues * @since 3.0.0 - * @version 3.1.1 + * @version 3.1.2 */ public abstract class AbstractResourceStorage implements ResourceStorage { @@ -69,6 +69,7 @@ public abstract class AbstractResourceStorage implements ResourceStorage { IOUtils.closeQuietly(inputStream); } inputStreams.clear(); + hotUrls.clear(); baseUrls.clear(); } @@ -171,11 +172,9 @@ public abstract class AbstractResourceStorage implements ResourceStorage { addResource(resource); return resource; } catch (Exception e) { - e.printStackTrace(); return null; } } - return null; } @@ -211,6 +210,7 @@ public abstract class AbstractResourceStorage implements ResourceStorage { resource = null; return r; } + private boolean next() { if (resource != null) { return true; @@ -233,13 +233,20 @@ public abstract class AbstractResourceStorage implements ResourceStorage { return null; } Resource resource = new DefaultResource(name, baseUrl, existUrl); - try { - addResource(resource); - } catch (Exception e){ - // 忽略异常 - } + addResourceWrapper(resource); return resource; } } + private void addResourceWrapper(Resource resource){ + if(resource == null){ + return; + } + try { + addResource(resource); + } catch (Exception e){ + // 忽略异常 + } + } + } diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/storage/CacheFastResourceStorage.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/storage/CacheFastResourceStorage.java index 121ded3..b6b162d 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/storage/CacheFastResourceStorage.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/classloader/resource/storage/CacheFastResourceStorage.java @@ -33,15 +33,13 @@ import java.util.concurrent.TimeUnit; * * @author starBlues * @since 3.1.1 - * @version 3.1.1 + * @version 3.1.2 */ public class CacheFastResourceStorage extends AbstractResourceStorage { protected final MultiCache resourceStorage; private final ResourceStorage cacheResourceStorage; - private final List inputStreams = new ArrayList<>(); - private volatile boolean release = false; @SuppressWarnings("all") @@ -136,10 +134,8 @@ public class CacheFastResourceStorage extends AbstractResourceStorage { @Override public void close() throws Exception { resourceStorage.clear(ResourceUtils::release); - for (InputStream inputStream : inputStreams) { - IOUtils.closeQuietly(inputStream); - } - inputStreams.clear(); + IOUtils.closeQuietly(cacheResourceStorage); + super.close(); } diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/Handler.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/Handler.java index e8f61ed..517893d 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/Handler.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/Handler.java @@ -64,12 +64,6 @@ public class Handler extends URLStreamHandler { private static URL jarContextUrl; - private static SoftReference> rootFileCache; - - static { - rootFileCache = new SoftReference<>(null); - } - private final JarFile jarFile; private URLStreamHandler fallbackHandler; @@ -372,9 +366,9 @@ public class Handler extends URLStreamHandler { throw new IllegalStateException("Not a file URL"); } File file = new File(URI.create(name)); - JarFile jarFile = PluginResourceStorage.getRootJarFile(file); + JarFileWrapper jarFile = PluginResourceStorage.getRootJarFile(file); if (jarFile == null) { - jarFile = new JarFile(file); + jarFile = new JarFileWrapper(new JarFile(file)); PluginResourceStorage.addRootJarFile(file, jarFile); } return jarFile; @@ -383,20 +377,6 @@ public class Handler extends URLStreamHandler { } } - /** - * Add the given {@link JarFile} to the root file cache. - * @param sourceFile the source file to add - * @param jarFile the jar file. - */ - static void addToRootFileCache(File sourceFile, JarFile jarFile) { - Map cache = rootFileCache.get(); - if (cache == null) { - cache = new ConcurrentHashMap<>(); - rootFileCache = new SoftReference<>(cache); - } - cache.put(sourceFile, jarFile); - } - /** * If possible, capture a URL that is configured with the original jar handler so that * we can use it as a fallback context later. We can only do this if we know that we diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarFileWrapper.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarFileWrapper.java index 46d6d21..bc344a6 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarFileWrapper.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/jar/JarFileWrapper.java @@ -40,7 +40,7 @@ import com.gitee.starblues.loader.utils.ObjectUtils; * * @author Phillip Webb */ -public class JarFileWrapper extends AbstractJarFile { +public class JarFileWrapper extends JarFile { private final String parentName; @@ -58,7 +58,7 @@ public class JarFileWrapper extends AbstractJarFile { } @Override - URL getUrl() throws MalformedURLException { + public URL getUrl() throws MalformedURLException { return this.parent.getUrl(); } @@ -88,7 +88,7 @@ public class JarFileWrapper extends AbstractJarFile { } @Override - public JarEntry getJarEntry(String name) { + public com.gitee.starblues.loader.jar.JarEntry getJarEntry(String name) { return this.parent.getJarEntry(name); } diff --git a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/utils/ResourceUtils.java b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/utils/ResourceUtils.java index 6af0671..440edc4 100644 --- a/spring-brick-loader/src/main/java/com/gitee/starblues/loader/utils/ResourceUtils.java +++ b/spring-brick-loader/src/main/java/com/gitee/starblues/loader/utils/ResourceUtils.java @@ -16,13 +16,11 @@ package com.gitee.starblues.loader.utils; + import java.io.File; import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLConnection; -import java.util.Objects; +import java.net.*; +import java.util.Collection; import java.util.function.Consumer; /** @@ -30,7 +28,7 @@ import java.util.function.Consumer; * * @author starBlues * @since 3.0.0 - * @version 3.0.0 + * @version 3.1.2 */ public class ResourceUtils { @@ -144,16 +142,36 @@ public class ResourceUtils { */ public static void release(final Object object, final Consumer consumer) { if (object instanceof Release) { - try { - ((Release)object).release(); - } catch (final Exception e) { - if (consumer != null) { - consumer.accept(e); + release((Release) object, consumer); + } + if(object instanceof Collection){ + Collection collection = (Collection) object; + for (Object o : collection) { + if(o instanceof Release){ + release((Release) o, consumer); } } } } + /** + * 释放资源 + * @param release release + * @param consumer consumer + */ + public static void release(final Release release, final Consumer consumer) { + if(release == null){ + return; + } + try { + release.release(); + } catch (final Exception e) { + if (consumer != null) { + consumer.accept(e); + } + } + } + /** * 获取存在的url * @param url url @@ -180,8 +198,9 @@ public class ResourceUtils { } catch (MalformedURLException e) { throw new IllegalArgumentException("非法:" + name); } + URLConnection uc = null; try { - URLConnection uc = url.openConnection(); + uc = url.openConnection(); if (uc instanceof HttpURLConnection) { HttpURLConnection hconn = (HttpURLConnection)uc; hconn.setRequestMethod("HEAD"); diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/DefaultPluginManager.java b/spring-brick/src/main/java/com/gitee/starblues/core/DefaultPluginManager.java index 66dcd01..00f63cd 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/DefaultPluginManager.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/DefaultPluginManager.java @@ -50,7 +50,7 @@ import java.util.stream.Collectors; * 抽象的插件管理者 * @author starBlues * @since 3.0.0 - * @version 3.1.0 + * @version 3.1.2 */ public class DefaultPluginManager implements PluginManager{ @@ -190,6 +190,7 @@ public class DefaultPluginManager implements PluginManager{ String sourcePluginPath = pluginPath.toString(); try { // 解析插件 + PluginInfo pluginInfo = parse(pluginPath); // 检查是否存在当前插件 PluginInsideInfo plugin = getPlugin(pluginInfo.getPluginId()); @@ -352,7 +353,7 @@ public class DefaultPluginManager implements PluginManager{ } @Override - public synchronized PluginInfo getPluginInfo(String pluginId) { + public synchronized PluginInsideInfo getPluginInfo(String pluginId) { if(ObjectUtils.isEmpty(pluginId)){ return null; } @@ -360,23 +361,15 @@ public class DefaultPluginManager implements PluginManager{ if(wrapperInside == null){ wrapperInside = resolvedPlugins.get(pluginId); } - if(wrapperInside != null){ - return wrapperInside.toPluginInfo(); - } else { - return null; - } + return wrapperInside; } @Override - public synchronized List getPluginInfos() { - List pluginDescriptors = new ArrayList<>( + public synchronized List getPluginInfos() { + List pluginDescriptors = new ArrayList<>( resolvedPlugins.size() + startedPlugins.size()); - for (PluginInsideInfo wrapperInside : startedPlugins.values()) { - pluginDescriptors.add(wrapperInside.toPluginInfo()); - } - for (PluginInsideInfo wrapperInside : resolvedPlugins.values()) { - pluginDescriptors.add(wrapperInside.toPluginInfo()); - } + pluginDescriptors.addAll(startedPlugins.values()); + pluginDescriptors.addAll(resolvedPlugins.values()); return pluginDescriptors; } @@ -499,6 +492,7 @@ public class DefaultPluginManager implements PluginManager{ resultPath = targetFile.toPath(); } } else { + // 不在插件目录 File pluginFile = pluginPath.toFile(); pluginRootDir = new File(getDefaultPluginRoot()); File pluginRootDirFile = new File(getDefaultPluginRoot()); @@ -523,7 +517,6 @@ public class DefaultPluginManager implements PluginManager{ return resultPath; } - /** * 统一启动插件操作 * @param pluginInsideInfo PluginInsideInfo diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/PluginLauncherManager.java b/spring-brick/src/main/java/com/gitee/starblues/core/PluginLauncherManager.java index d48c543..4318ede 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/PluginLauncherManager.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/PluginLauncherManager.java @@ -48,7 +48,7 @@ import java.util.concurrent.ConcurrentHashMap; * 可引导启动的插件管理者 * @author starBlues * @since 3.0.0 - * @version 3.1.0 + * @version 3.1.2 */ public class PluginLauncherManager extends DefaultPluginManager{ @@ -129,9 +129,13 @@ public class PluginLauncherManager extends DefaultPluginManager{ } try { SpringPluginHook springPluginHook = registryPluginInfo.getSpringPluginHook(); + // 校验是否可停止 springPluginHook.stopVerify(); + // 关闭插件 springPluginHook.close(closeType); + // 移除插件相互调用缓存的信息 invokeSupperCache.remove(pluginId); + // 移除插件注册信息 registryInfo.remove(pluginId); super.stop(pluginInsideInfo, closeType); } catch (Exception e){ diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/PluginManager.java b/spring-brick/src/main/java/com/gitee/starblues/core/PluginManager.java index 5641ef1..7f453d1 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/PluginManager.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/PluginManager.java @@ -25,7 +25,7 @@ import java.util.List; * 插件管理者 * @author starBlues * @since 3.0.0 - * @version 3.0.0 + * @version 3.1.2 */ public interface PluginManager { @@ -125,12 +125,12 @@ public interface PluginManager { * @param pluginId 插件id * @return PluginDescriptor */ - PluginInfo getPluginInfo(String pluginId); + PluginInsideInfo getPluginInfo(String pluginId); /** * 得到全部的插件信息 * @return List PluginWrapper */ - List getPluginInfos(); + List getPluginInfos(); } diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/ComposeDescriptorLoader.java b/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/ComposeDescriptorLoader.java index f8aa241..6bcc236 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/ComposeDescriptorLoader.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/descriptor/ComposeDescriptorLoader.java @@ -21,6 +21,7 @@ import com.gitee.starblues.core.descriptor.decrypt.EmptyPluginDescriptorDecrypt; import com.gitee.starblues.core.descriptor.decrypt.PluginDescriptorDecrypt; import com.gitee.starblues.core.exception.PluginException; import com.gitee.starblues.utils.SpringBeanUtils; +import lombok.extern.slf4j.Slf4j; import org.springframework.context.ApplicationContext; import java.nio.file.Path; @@ -33,6 +34,7 @@ import java.util.List; * @since 3.0.0 * @version 3.0.1 */ +@Slf4j public class ComposeDescriptorLoader implements PluginDescriptorLoader{ private final List pluginDescriptorLoaders = new ArrayList<>(); @@ -73,10 +75,14 @@ public class ComposeDescriptorLoader implements PluginDescriptorLoader{ @Override public InsidePluginDescriptor load(Path location) throws PluginException { for (PluginDescriptorLoader pluginDescriptorLoader : pluginDescriptorLoaders) { - InsidePluginDescriptor pluginDescriptor = pluginDescriptorLoader.load(location); - if(pluginDescriptor != null){ - pluginChecker.checkDescriptor(pluginDescriptor); - return pluginDescriptor; + try { + InsidePluginDescriptor pluginDescriptor = pluginDescriptorLoader.load(location); + if(pluginDescriptor != null){ + pluginChecker.checkDescriptor(pluginDescriptor); + return pluginDescriptor; + } + } catch (Exception e){ + log.debug("非法路径插件: {}", location); } } return null; diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/SpringPluginHookWrapper.java b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/SpringPluginHookWrapper.java index 6b977ea..8c411f6 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/SpringPluginHookWrapper.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/SpringPluginHookWrapper.java @@ -20,6 +20,7 @@ import com.gitee.starblues.core.PluginCloseType; import com.gitee.starblues.core.PluginInsideInfo; import com.gitee.starblues.core.exception.PluginProhibitStopException; import com.gitee.starblues.core.launcher.plugin.involved.PluginLaunchInvolved; +import com.gitee.starblues.loader.PluginResourceStorage; import com.gitee.starblues.spring.ApplicationContext; import com.gitee.starblues.spring.SpringPluginHook; import com.gitee.starblues.spring.WebConfig; @@ -31,7 +32,7 @@ import lombok.extern.slf4j.Slf4j; * SpringPluginHook-Wrapper * @author starBlues * @since 3.0.0 - * @version 3.1.0 + * @version 3.1.2 */ @Slf4j public class SpringPluginHookWrapper implements SpringPluginHook { @@ -72,15 +73,21 @@ public class SpringPluginHookWrapper implements SpringPluginHook { @Override public void close(PluginCloseType closeType) throws Exception { + // 1. 关闭 application 等信息 try { - pluginLaunchInvolved.close(pluginInsideInfo, classLoader); + target.close(closeType); } catch (Exception e){ log.error("关闭插件异常: {}", e.getMessage(), e); } + // 2. 关闭 pluginLaunchInvolved try { - target.close(closeType); - } finally { - ResourceUtils.closeQuietly(classLoader); + pluginLaunchInvolved.close(pluginInsideInfo, classLoader); + } catch (Exception e){ + log.error("关闭插件异常: {}", e.getMessage(), e); } + // 3. 关闭classloader + ResourceUtils.closeQuietly(classLoader); + // 4. 移除插件jar等信息 + PluginResourceStorage.removePlugin(pluginInsideInfo.getPluginId()); } } diff --git a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/involved/DefaultPluginLaunchInvolved.java b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/involved/DefaultPluginLaunchInvolved.java index 25184b1..9b97d6b 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/involved/DefaultPluginLaunchInvolved.java +++ b/spring-brick/src/main/java/com/gitee/starblues/core/launcher/plugin/involved/DefaultPluginLaunchInvolved.java @@ -19,6 +19,7 @@ package com.gitee.starblues.core.launcher.plugin.involved; import com.gitee.starblues.core.PluginInsideInfo; import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; import com.gitee.starblues.core.PluginExtensionInfo; +import com.gitee.starblues.core.descriptor.PluginLibInfo; import com.gitee.starblues.loader.PluginResourceStorage; import com.gitee.starblues.spring.ApplicationContext; import com.gitee.starblues.spring.SpringPluginHook; @@ -30,12 +31,14 @@ import lombok.extern.slf4j.Slf4j; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; /** * 默认的插件启动介入者 * @author starBlues * @since 3.0.0 - * @version 3.1.0 + * @version 3.1.2 */ @Slf4j public class DefaultPluginLaunchInvolved implements PluginLaunchInvolved{ @@ -43,7 +46,12 @@ public class DefaultPluginLaunchInvolved implements PluginLaunchInvolved{ @Override public void before(PluginInsideInfo pluginInsideInfo, ClassLoader classLoader) throws Exception { InsidePluginDescriptor descriptor = pluginInsideInfo.getPluginDescriptor(); - PluginResourceStorage.addPlugin(descriptor.getPluginId(), descriptor.getPluginFileName()); + Set pluginLibInfo = descriptor.getPluginLibInfo(); + List libPath = null; + if(pluginLibInfo != null){ + libPath = pluginLibInfo.stream().map(PluginLibInfo::getPath).collect(Collectors.toList()); + } + PluginResourceStorage.addPlugin(descriptor.getPluginId(), descriptor.getPluginFileName(), libPath); } @Override @@ -57,7 +65,6 @@ public class DefaultPluginLaunchInvolved implements PluginLaunchInvolved{ public void close(PluginInsideInfo pluginInsideInfo, ClassLoader classLoader) throws Exception { InsidePluginDescriptor descriptor = pluginInsideInfo.getPluginDescriptor(); String pluginId = descriptor.getPluginId(); - PluginResourceStorage.removePlugin(pluginId); PluginStaticResourceResolver.remove(pluginId); } diff --git a/spring-brick/src/main/java/com/gitee/starblues/integration/operator/DefaultPluginOperator.java b/spring-brick/src/main/java/com/gitee/starblues/integration/operator/DefaultPluginOperator.java index 77709d6..07b3208 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/integration/operator/DefaultPluginOperator.java +++ b/spring-brick/src/main/java/com/gitee/starblues/integration/operator/DefaultPluginOperator.java @@ -16,10 +16,9 @@ package com.gitee.starblues.integration.operator; -import com.gitee.starblues.core.PluginInfo; -import com.gitee.starblues.core.PluginLauncherManager; -import com.gitee.starblues.core.PluginManager; -import com.gitee.starblues.core.RealizeProvider; +import com.gitee.starblues.core.*; +import com.gitee.starblues.core.descriptor.InsidePluginDescriptor; +import com.gitee.starblues.core.descriptor.PluginType; import com.gitee.starblues.core.exception.PluginDisabledException; import com.gitee.starblues.core.exception.PluginException; import com.gitee.starblues.integration.IntegrationConfiguration; @@ -50,12 +49,13 @@ import java.time.format.DateTimeFormatter; import java.util.List; import java.util.Objects; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.stream.Collectors; /** * 默认的插件操作者 * @author starBlues * @version 3.0.0 - * @since 3.0.4 + * @since 3.1.2 */ public class DefaultPluginOperator implements PluginOperator { protected final Logger log = LoggerFactory.getLogger(this.getClass()); @@ -219,7 +219,7 @@ public class DefaultPluginOperator implements PluginOperator { return backDirPath; } Objects.requireNonNull(backDirPath); - return backup(backDirPath, sign, false); + return operatePluginFile(backDirPath, sign, true, false); } @Override @@ -234,12 +234,18 @@ public class DefaultPluginOperator implements PluginOperator { @Override public List getPluginInfo() { - return pluginManager.getPluginInfos(); + return pluginManager.getPluginInfos().stream() + .map(PluginInsideInfo::toPluginInfo) + .collect(Collectors.toList()); } @Override public PluginInfo getPluginInfo(String pluginId) { - return pluginManager.getPluginInfo(pluginId); + PluginInsideInfo pluginInfo = pluginManager.getPluginInfo(pluginId); + if(pluginInfo != null){ + return pluginInfo.toPluginInfo(); + } + return null; } /** @@ -250,22 +256,16 @@ public class DefaultPluginOperator implements PluginOperator { * @return 如果备份插件, 则返回备份后的插件路径 */ protected Path uninstallBackup(String pluginId, boolean isDelete, boolean isBackup){ - PluginInfo pluginInfo = pluginManager.getPluginInfo(pluginId); - if(pluginInfo == null){ + PluginInsideInfo pluginInsideInfo = pluginManager.getPluginInfo(pluginId); + if(pluginInsideInfo == null){ throw new PluginException(pluginId, "没有发现"); } pluginManager.uninstall(pluginId); - if(!isDelete || configuration.isDev()){ + if(configuration.isDev()){ + log.trace("开发环境对插件文件不备份和删除"); return null; } - // 删除插件 - Path pluginPath = Paths.get(pluginInfo.getPluginPath()); - Path backupPath = null; - if(isBackup){ - // 将插件文件移到备份文件中 - backupPath = backup(pluginPath, "uninstall", true); - } - return backupPath; + return operatePluginFile(pluginInsideInfo, "uninstall", isBackup, isDelete); } protected PluginInfo uploadPlugin(String pluginFileName, InputStream inputStream, @@ -326,45 +326,84 @@ public class DefaultPluginOperator implements PluginOperator { /** * 备份 - * @param sourcePath 源文件的路径 + * @param pluginInsideInfo 插件信息 * @param sign 文件标志 - * @param deletedSourceFile 是否删除源文件 - * @return 返回备份的插件路径 + * @param back 是否备份插件文件 + * @param delete 是否删除插件文件 + * @return 如果为备份则返回备份后的文件,否则返回null */ - protected Path backup(Path sourcePath, String sign, boolean deletedSourceFile) { - try { - if(configuration.isDev()){ - // 如果是开发环境, 则不进行备份 - return null; - } - if(sourcePath == null){ - return null; - } - if(!Files.exists(sourcePath)){ - log.error("Path '{}' does not exist", sourcePath.toString()); - return null; + protected Path operatePluginFile(PluginInsideInfo pluginInsideInfo, String sign, boolean back, boolean delete) { + InsidePluginDescriptor pluginDescriptor = pluginInsideInfo.getPluginDescriptor(); + if(configuration.isDev()){ + // 如果是开发环境, 则不进行备份 + return null; + } + PluginType pluginType = pluginDescriptor.getType(); + if(ObjectUtils.equalsElement(pluginType, PluginType.ZIP, PluginType.JAR, PluginType.DIR)){ + return operatePluginFile(Paths.get(pluginInsideInfo.getPluginPath()), sign, back, delete); + } else if(ObjectUtils.equalsElement(pluginType, PluginType.JAR_OUTER, PluginType.ZIP_OUTER)){ + File pluginLibFile = new File(pluginDescriptor.getPluginLibDir()); + File pluginFile = new File(pluginDescriptor.getPluginPath()); + // 判断获取插件包和插件依赖是否在同一个目录,如果在返回父目录 + File parentFile = FilesUtils.sameParent(pluginLibFile, pluginFile); + if(FilesUtils.isChildFile(pluginManager.getPluginsRoots(), parentFile)){ + // 如果当前插件的父目录为当前插件的子目录 + // 为插件存放目录的子目录 + return operatePluginFile(parentFile.toPath(), sign, back, delete); + } else { + // 只备份插件jar包 + return operatePluginFile(pluginFile.toPath(), sign, back, delete); } - File sourceFile = sourcePath.toFile(); - touchBackupPath(); - String targetPathStr = configuration.backupPath() + File.separator; - if(!ObjectUtils.isEmpty(sign)){ - targetPathStr = targetPathStr + sign; + } else { + return operatePluginFile(Paths.get(pluginDescriptor.getPluginPath()), sign, back, delete); + } + } + + /** + * 备份路径 + * @param pluginPath 插件文件 + * @param sign 操作标志 + * @param back 是否备份插件文件 + * @param delete 是否删除插件文件 + * @return 如果为备份则返回备份后的文件,否则返回null + */ + private Path operatePluginFile(Path pluginPath, String sign, boolean back, boolean delete){ + if(!back && !delete){ + return null; + } + if(pluginPath == null){ + log.error("{}失败, 没有发现路径", sign); + return null; + } + if(!Files.exists(pluginPath)){ + log.error("{}}失败, 路径不存在: {}", sign, pluginPath); + return null; + } + File sourceFile = pluginPath.toFile(); + try { + Path targetBackPath = null; + if(back){ + touchBackupPath(); + String targetPathStr = configuration.backupPath() + File.separator; + if(!ObjectUtils.isEmpty(sign)){ + targetPathStr = targetPathStr + sign; + } + targetPathStr = targetPathStr + "_" + getNowTimeByFormat() + "_" +sourceFile.getName(); + targetBackPath = Paths.get(targetPathStr); + File targetBackFile = targetBackPath.toFile(); + copyFile(sourceFile, targetBackFile); + log.info("备份插件文件到: {}", targetBackFile.getAbsolutePath()); } - targetPathStr = targetPathStr + "_" + getNowTimeByFormat() + "_" +sourceFile.getName(); - Path targetPath = Paths.get(targetPathStr); - File targetFile = targetPath.toFile(); - copyFile(sourceFile, targetFile); - log.info("备份插件文件到: {}", targetFile.getAbsolutePath()); - if(deletedSourceFile){ + if(delete){ if(sourceFile.isFile()){ FileUtils.delete(sourceFile); } else { FileUtils.deleteDirectory(sourceFile); } } - return targetPath; + return targetBackPath; } catch (IOException e) { - log.error("Backup plugin jar '{}' failure. {}", sourcePath.toString(), e.getMessage(), e); + log.error("{}路径[{}]失败: {}", sign, pluginPath, e.getMessage(), e); return null; } } diff --git a/spring-brick/src/main/java/com/gitee/starblues/utils/LogUtils.java b/spring-brick/src/main/java/com/gitee/starblues/utils/LogUtils.java index ac9f547..9b90e8a 100644 --- a/spring-brick/src/main/java/com/gitee/starblues/utils/LogUtils.java +++ b/spring-brick/src/main/java/com/gitee/starblues/utils/LogUtils.java @@ -24,7 +24,7 @@ import org.slf4j.Logger; * * @author starBlues * @since 3.0.0 - * @version 3.0.0 + * @version 3.1.2 */ public class LogUtils { @@ -34,4 +34,8 @@ public class LogUtils { logger.info("插件[{}]{}", MsgUtils.getPluginUnique(pluginDescriptor), msg); } + public static String getMsg(PluginDescriptor pluginDescriptor, String msg, Object... args){ + return "插件[ " + MsgUtils.getPluginUnique(pluginDescriptor) + " ]" + String.format(msg, args); + } + } diff --git a/update.md b/update.md index de7cb66..c4da9ac 100644 --- a/update.md +++ b/update.md @@ -1,4 +1,6 @@ 1. 【修复】修复主程序打成`jar-out`类型包时,无法加载主类的问题 2. 【修复】修复插件包打成`jar-out`时无法加载依赖的问题 3. 【修复】修复插件在运行状态无法加载类的问题 -4. 【修复】修复对同一个插件包重复安装时,源插件包被系统占用的问题 \ No newline at end of file +4. 【修复】修复对同一个插件包重复安装时,源插件包被系统占用的问题 +5. 【修复】修复`jar-outer`、`zip-outer`类型插件卸载时依赖文件被占用问题 +6. 【新增】新增`jar-outer`、`zip-outer`带依赖,且为压缩包的上传安装 【暂未完成】 \ No newline at end of file -- Gitee