From 45fd2e1456c6f393bb4ba8e42f0dbde8961e1174 Mon Sep 17 00:00:00 2001 From: Nidhi Nair Date: Tue, 22 Oct 2024 08:59:05 +0530 Subject: [PATCH 1/2] chore: Enable sharing sprign context in pf4j plugins --- app/server/appsmith-interfaces/pom.xml | 6 ++ .../appsmith/external/plugins/BasePlugin.java | 4 +- .../configurations/PluginConfiguration.java | 87 ++++++++++++++++++- 3 files changed, 92 insertions(+), 5 deletions(-) diff --git a/app/server/appsmith-interfaces/pom.xml b/app/server/appsmith-interfaces/pom.xml index 00ac85011d6..c30a8d73495 100644 --- a/app/server/appsmith-interfaces/pom.xml +++ b/app/server/appsmith-interfaces/pom.xml @@ -61,6 +61,12 @@ pf4j ${org.pf4j.version} + + org.pf4j + pf4j-spring + 0.8.0 + compile + org.springframework.data diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/plugins/BasePlugin.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/plugins/BasePlugin.java index 047f5fd5754..f2b3a76a433 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/plugins/BasePlugin.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/plugins/BasePlugin.java @@ -2,10 +2,10 @@ import com.appsmith.util.SerializationUtils; import com.fasterxml.jackson.databind.ObjectMapper; -import org.pf4j.Plugin; import org.pf4j.PluginWrapper; +import org.pf4j.spring.SpringPlugin; -public abstract class BasePlugin extends Plugin { +public abstract class BasePlugin extends SpringPlugin { protected static final ObjectMapper objectMapper = SerializationUtils.getObjectMapperWithSourceInLocationAndMaxStringLengthEnabled(); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/PluginConfiguration.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/PluginConfiguration.java index ff49c00afeb..810a98af087 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/PluginConfiguration.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/PluginConfiguration.java @@ -1,7 +1,16 @@ package com.appsmith.server.configurations; +import jakarta.annotation.PostConstruct; +import org.pf4j.ExtensionFactory; import org.pf4j.PropertiesPluginDescriptorFinder; +import org.pf4j.spring.ExtensionsInjector; +import org.pf4j.spring.SpringExtensionFactory; +import org.pf4j.spring.SpringPlugin; import org.pf4j.spring.SpringPluginManager; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -9,16 +18,88 @@ public class PluginConfiguration { @Bean - public SpringPluginManager pluginManager() { - return new CustomPluginManager(); + public SpringPluginManager pluginManager(ApplicationContext applicationContext) { + return new CustomPluginManager(applicationContext); } private static class CustomPluginManager extends SpringPluginManager { - public CustomPluginManager() { + + private ApplicationContext applicationContext; + + private CustomSpringExtensionFactory ef; + + public CustomPluginManager(ApplicationContext applicationContext) { super(); + this.applicationContext = applicationContext; + this.ef = new CustomSpringExtensionFactory(this); pluginDescriptorFinder = "development".equals(System.getProperty("pf4j.mode")) ? new PropertiesPluginDescriptorFinder("target/classes/plugin.properties") : new PropertiesPluginDescriptorFinder(); } + + @Override + protected ExtensionFactory createExtensionFactory() { + ef = new CustomSpringExtensionFactory(this); + return ef; + } + + @Override + public ExtensionFactory getExtensionFactory() { + return ef; + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + ef.setApplicationContext(applicationContext); + } + + public ApplicationContext getApplicationContext() { + return applicationContext; + } + + /** + * This method load, start plugins and inject extensions in Spring + */ + @PostConstruct + public void init() { + loadPlugins(); + startPlugins(); + + AbstractAutowireCapableBeanFactory beanFactory = + (AbstractAutowireCapableBeanFactory) applicationContext.getAutowireCapableBeanFactory(); + ExtensionsInjector extensionsInjector = new ExtensionsInjector(this, beanFactory); + + ef.setApplicationContext(this.applicationContext); + extensionsInjector.injectExtensions(); + } + } + + static class CustomSpringExtensionFactory extends SpringExtensionFactory { + + private ApplicationContext applicationContext; + + public CustomSpringExtensionFactory(SpringPluginManager pluginManager) { + this(pluginManager, true); + } + + public CustomSpringExtensionFactory(SpringPluginManager pluginManager, boolean autowire) { + super(pluginManager, autowire); + } + + @Override + public T create(Class extensionClass) { + T extension = createWithSpring(extensionClass, this.applicationContext); + if (extension instanceof SpringPlugin sp) { + ConfigurableApplicationContext pluginContext = + (ConfigurableApplicationContext) sp.getApplicationContext(); + pluginContext.setParent(applicationContext); + } + return extension; + } + + public void setApplicationContext(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } } } From 7547480692f69f28e50f41f89a59f078bbc6fa65 Mon Sep 17 00:00:00 2001 From: Nidhi Nair Date: Tue, 22 Oct 2024 09:05:22 +0530 Subject: [PATCH 2/2] chore: Enable sharing sprign context in pf4j plugins --- .../main/java/com/appsmith/external/plugins/BasePlugin.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/plugins/BasePlugin.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/plugins/BasePlugin.java index f2b3a76a433..fab40412edb 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/plugins/BasePlugin.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/plugins/BasePlugin.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.pf4j.PluginWrapper; import org.pf4j.spring.SpringPlugin; +import org.springframework.context.ApplicationContext; public abstract class BasePlugin extends SpringPlugin { @@ -13,4 +14,9 @@ public abstract class BasePlugin extends SpringPlugin { public BasePlugin(PluginWrapper wrapper) { super(wrapper); } + + @Override + protected ApplicationContext createApplicationContext() { + return null; + } }