From 2a37366c922aced15bd5943f74a5a997238ed945 Mon Sep 17 00:00:00 2001 From: John Niang Date: Fri, 29 Aug 2025 11:30:15 +0800 Subject: [PATCH] Set context ClassLoader to plugin ClassLoader for correct class loading operations (#7725) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind bug /area plugin /milestone 2.21.x #### What this PR does / why we need it: This PR fixes the problem that loading resources from class path during static initialization doesn't work. #### Does this PR introduce a user-facing change? ```release-note 修复部分场景下无法正常启动插件的问题 ``` --- .../app/plugin/DefaultPluginApplicationContextFactory.java | 7 +++++++ .../plugin/DefaultPluginApplicationContextFactoryTest.java | 3 +++ 2 files changed, 10 insertions(+) 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 c075baa5b..cab91b8da 100644 --- a/application/src/main/java/run/halo/app/plugin/DefaultPluginApplicationContextFactory.java +++ b/application/src/main/java/run/halo/app/plugin/DefaultPluginApplicationContextFactory.java @@ -70,6 +70,12 @@ 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 * to ensure that conditional annotations (e.g., @ConditionalOnClass) within the plugin @@ -182,6 +188,7 @@ public class DefaultPluginApplicationContextFactory implements PluginApplication log.debug("Refreshing application context for plugin {}", pluginId); sw.start("Refresh"); + context.refresh(); sw.stop(); log.debug("Refreshed application context for plugin {}", pluginId); diff --git a/application/src/test/java/run/halo/app/plugin/DefaultPluginApplicationContextFactoryTest.java b/application/src/test/java/run/halo/app/plugin/DefaultPluginApplicationContextFactoryTest.java index bf2e4a494..2160abe71 100644 --- a/application/src/test/java/run/halo/app/plugin/DefaultPluginApplicationContextFactoryTest.java +++ b/application/src/test/java/run/halo/app/plugin/DefaultPluginApplicationContextFactoryTest.java @@ -1,5 +1,6 @@ package run.halo.app.plugin; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.mockito.Mockito.mock; @@ -39,6 +40,8 @@ class DefaultPluginApplicationContextFactoryTest { when(pluginManager.getPlugin("fake-plugin")).thenReturn(pw); var context = factory.create("fake-plugin"); + assertEquals(pw.getPluginClassLoader(), Thread.currentThread().getContextClassLoader()); + assertInstanceOf(PluginApplicationContext.class, context); assertNotNull(context.getBeanProvider(SearchService.class).getIfUnique()); assertNotNull(context.getBeanProvider(PluginsRootGetter.class).getIfUnique());