mirror of https://github.com/halo-dev/halo
fix: different jar file with the same name appears in the plugins directory after a failed installation (#3841)
#### What type of PR is this? /kind bug /area core /milestone 2.5.x #### What this PR does / why we need it: 修复插件安装后无法启动会导致卸载后插件 JAR 文件残留的问题 how to test it? 1. 安装一个无法启动的插件,比如在插件声明周期方法中抛一个异常 2. 启动插件,然后卸载插件看插件 JAR 是否被正确删除 3. 如果是插件开发模式则不会删除文件 #### Which issue(s) this PR fixes: Fixes #3840 #### Does this PR introduce a user-facing change? ```release-note 修复插件安装后无法启动会导致卸载后插件 JAR 文件残留的问题 ```pull/3845/head
parent
2dcbceea5e
commit
d589ce56cc
|
@ -1,5 +1,6 @@
|
|||
package run.halo.app.core.extension.reconciler;
|
||||
|
||||
import static org.pf4j.util.FileUtils.isJarFile;
|
||||
import static run.halo.app.plugin.PluginConst.DELETE_STAGE;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -22,6 +23,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.pf4j.PluginDescriptor;
|
||||
import org.pf4j.PluginRuntimeException;
|
||||
import org.pf4j.PluginState;
|
||||
import org.pf4j.PluginWrapper;
|
||||
import org.pf4j.RuntimeMode;
|
||||
|
@ -277,6 +279,15 @@ public class PluginReconciler implements Reconciler<Request> {
|
|||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentState != desiredState) {
|
||||
log.error("Plugin [{}] state transition failed: {}", name,
|
||||
haloPluginManager.getPluginStartingError(name));
|
||||
var e = new PluginRuntimeException("Plugin [" + name + "] state transition from ["
|
||||
+ currentState + "] to [" + desiredState + "] failed");
|
||||
persistenceFailureStatus(name, e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
void persistenceFailureStatus(String pluginName, Throwable e) {
|
||||
|
@ -554,25 +565,41 @@ public class PluginReconciler implements Reconciler<Request> {
|
|||
}
|
||||
|
||||
PluginWrapper pluginWrapper = haloPluginManager.getPlugin(name);
|
||||
if (pluginWrapper == null) {
|
||||
return;
|
||||
}
|
||||
// pluginWrapper must not be null in below code
|
||||
// stop and unload plugin, see also PluginBeforeStopSyncListener
|
||||
if (!haloPluginManager.unloadPlugin(name)) {
|
||||
throw new IllegalStateException("Failed to unload plugin: " + name);
|
||||
if (pluginWrapper != null) {
|
||||
// pluginWrapper must not be null in below code
|
||||
// stop and unload plugin, see also PluginBeforeStopSyncListener
|
||||
if (!haloPluginManager.unloadPlugin(name)) {
|
||||
throw new IllegalStateException("Failed to unload plugin: " + name);
|
||||
}
|
||||
}
|
||||
|
||||
// delete plugin resources
|
||||
if (RuntimeMode.DEPLOYMENT.equals(pluginWrapper.getRuntimeMode())) {
|
||||
Path pluginPath = determinePluginLocation(plugin);
|
||||
if (pluginPath != null && !isDevelopmentMode(name) && isJarFile(pluginPath)) {
|
||||
// delete plugin file
|
||||
try {
|
||||
Files.deleteIfExists(pluginWrapper.getPluginPath());
|
||||
Files.deleteIfExists(pluginPath);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
Path determinePluginLocation(Plugin plugin) {
|
||||
final var name = plugin.getMetadata().getName();
|
||||
PluginWrapper pluginWrapper = haloPluginManager.getPlugin(name);
|
||||
return Optional.ofNullable(pluginWrapper)
|
||||
.map(PluginWrapper::getPluginPath)
|
||||
.orElseGet(() -> {
|
||||
var localtionUri = plugin.statusNonNull().getLoadLocation();
|
||||
if (localtionUri != null) {
|
||||
return Path.of(localtionUri);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
void createInitialReverseProxyIfNotPresent(Plugin plugin) {
|
||||
String pluginName = plugin.getMetadata().getName();
|
||||
String reverseProxyName = initialReverseProxyName(pluginName);
|
||||
|
|
Loading…
Reference in New Issue