diff --git a/application/src/main/java/run/halo/app/plugin/DefaultPluginApplicationContextFactory.java b/application/src/main/java/run/halo/app/plugin/DefaultPluginApplicationContextFactory.java index cab91b8da..396e2288f 100644 --- a/application/src/main/java/run/halo/app/plugin/DefaultPluginApplicationContextFactory.java +++ b/application/src/main/java/run/halo/app/plugin/DefaultPluginApplicationContextFactory.java @@ -70,11 +70,6 @@ public class DefaultPluginApplicationContextFactory implements PluginApplication var pluginWrapper = pluginManager.getPlugin(pluginId); var classLoader = pluginWrapper.getPluginClassLoader(); - // Set the context ClassLoader to the plugin ClassLoader to ensure that - // any class loading operations performed by the context (e.g., initializing - // bean definitions, loading class resources during static initialization) - // use the correct ClassLoader. - Thread.currentThread().setContextClassLoader(classLoader); /* * Manually creating a BeanFactory and setting the plugin's ClassLoader is necessary @@ -189,7 +184,18 @@ public class DefaultPluginApplicationContextFactory implements PluginApplication log.debug("Refreshing application context for plugin {}", pluginId); sw.start("Refresh"); - context.refresh(); + // Set the context ClassLoader to the plugin ClassLoader to ensure that + // any class loading operations performed by the context (e.g., initializing + // bean definitions, loading class resources during static initialization) + // use the correct ClassLoader. + var previous = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(classLoader); + context.refresh(); + } finally { + // reset the class loader to previous one to prevent resource leak + Thread.currentThread().setContextClassLoader(previous); + } sw.stop(); log.debug("Refreshed application context for plugin {}", pluginId); if (log.isDebugEnabled()) { diff --git a/application/src/main/java/run/halo/app/plugin/SpringPlugin.java b/application/src/main/java/run/halo/app/plugin/SpringPlugin.java index 0acc14478..45f5fde3b 100644 --- a/application/src/main/java/run/halo/app/plugin/SpringPlugin.java +++ b/application/src/main/java/run/halo/app/plugin/SpringPlugin.java @@ -27,9 +27,11 @@ public class SpringPlugin extends Plugin { public void start() { log.info("Preparing starting plugin {}", pluginContext.getName()); var pluginId = pluginContext.getName(); + var previous = Thread.currentThread().getContextClassLoader(); try { // initialize context this.context = contextFactory.create(pluginId); + Thread.currentThread().setContextClassLoader(this.context.getClassLoader()); log.info("Application context {} for plugin {} is created", this.context, pluginId); var pluginOpt = context.getBeanProvider(Plugin.class) @@ -55,13 +57,17 @@ public class SpringPlugin extends Plugin { this.stop(); // propagate exception to invoker. throw t; + } finally { + Thread.currentThread().setContextClassLoader(previous); } } @Override public void stop() { + var previous = Thread.currentThread().getContextClassLoader(); try { if (context != null) { + Thread.currentThread().setContextClassLoader(context.getClassLoader()); log.info("Before publishing plugin stopping event for plugin {}", pluginContext.getName()); context.publishEvent(new SpringPluginStoppingEvent(this, this)); @@ -74,6 +80,7 @@ public class SpringPlugin extends Plugin { log.info("Stopped {} for plugin {}", this.delegate, pluginContext.getName()); } } finally { + Thread.currentThread().setContextClassLoader(previous); if (context instanceof ConfigurableApplicationContext configurableContext) { log.info("Closing plugin context for plugin {}", pluginContext.getName()); configurableContext.close();