猿问

为什么 pluginManager.getExtensions 的结果为空?

尝试使用 PF4J 时,我创建了必要的部分,如

https://github.com/pf4j/pf4j

  1. 扩展 ExtensionPoint 的接口

  2. 一个插件

  3. 带有清单的罐子

  4. 插件加载和激活

为什么 clickHandlers 列表是空的?

我已经使用 JUnit 测试对此进行了测试,我可以在其中调试似乎工作正常的其他部分。请参阅下面的调试日志。

我还查看了https://github.com/pf4j/pf4j/issues/21并激活了 Eclipse 注释处理,但没有任何积极影响。

1.扩展扩展点的接口


public interface ClickHandler extends ExtensionPoint {

...


}

2.一个插件


public class MBClickHandlerPlugin extends Plugin {


  /**

   * construct me

   * @param wrapper

   */

  public MBClickHandlerPlugin(PluginWrapper wrapper) {

    super(wrapper);

  }


  @Extension

  public static class  MBClickHandler implements ClickHandler {



  }

}

3. 带有清单的罐子


unzip -q -c target/com.bitplan.mb-0.0.1.jar META-INF/MANIFEST.MF

Manifest-Version: 1.0

Plugin-Dependencies: 

Plugin-Id: com.bitplan.mb

Built-By: wf

Plugin-Provider: BITPlan GmbH

Plugin-Version: 0.0.1

Plugin-Class: com.bitplan.mb.MBClickHandlerPlugin

Created-By: Apache Maven 3.5.2

Build-Jdk: 1.8.0_152

4.插件加载和激活


  /**

   * activate the plugins requested on the command line

   */

  public void activatePlugins() {

    pluginManager = new DefaultPluginManager();


    for (String plugin : plugins) {

      Path pluginPath = Paths.get(plugin);

      pluginManager.loadPlugin(pluginPath);

    }

    pluginManager.startPlugins();


    List<ClickHandler> clickHandlers = pluginManager

        .getExtensions(ClickHandler.class);

    for (ClickHandler clickHandler : clickHandlers) {

      installClickHandler(clickHandler);

    }

  }


慕桂英546537
浏览 438回答 1
1回答

慕的地6264312

解决方法 #1使用定制的 PluginManagerpluginManager = new JarPluginManager(this.getClass().getClassLoader());从将使用插件的类中确保使用相同的类加载器JarPluginManager 源代码:import java.nio.file.Path;import org.pf4j.DefaultPluginManager;import org.pf4j.JarPluginLoader;import org.pf4j.ManifestPluginDescriptorFinder;import org.pf4j.PluginClassLoader;import org.pf4j.PluginDescriptor;import org.pf4j.PluginDescriptorFinder;import org.pf4j.PluginLoader;import org.pf4j.PluginManager;/**&nbsp;* see https://github.com/pf4j/pf4j/issues/249 see&nbsp;* https://pf4j.org/doc/class-loading.html&nbsp;*&nbsp;&nbsp;* @author wf&nbsp;*&nbsp;*/public class JarPluginManager extends DefaultPluginManager {&nbsp; public static class ParentClassLoaderJarPluginLoader extends JarPluginLoader {&nbsp; &nbsp; static ClassLoader parentClassLoader;&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;*&nbsp;&nbsp; &nbsp; &nbsp;* @param pluginManager&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; public ParentClassLoaderJarPluginLoader(PluginManager pluginManager) {&nbsp; &nbsp; &nbsp; super(pluginManager);&nbsp; &nbsp; }&nbsp; &nbsp; static PluginClassLoader pluginClassLoader;&nbsp; &nbsp; @Override&nbsp; &nbsp; public ClassLoader loadPlugin(Path pluginPath,&nbsp; &nbsp; &nbsp; &nbsp; PluginDescriptor pluginDescriptor) {&nbsp; &nbsp; &nbsp; if (pluginClassLoader == null) {&nbsp; &nbsp; &nbsp; &nbsp; boolean parentFirst=true;&nbsp; &nbsp; &nbsp; &nbsp; pluginClassLoader = new PluginClassLoader(pluginManager,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pluginDescriptor, parentClassLoader,parentFirst);&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; pluginClassLoader.addFile(pluginPath.toFile());&nbsp; &nbsp; &nbsp; return pluginClassLoader;&nbsp; &nbsp; }&nbsp; }&nbsp; /**&nbsp; &nbsp;* construct me with the given classloader&nbsp; &nbsp;* @param classLoader&nbsp; &nbsp;*/&nbsp; public JarPluginManager(ClassLoader classLoader) {&nbsp; &nbsp; ParentClassLoaderJarPluginLoader.parentClassLoader=classLoader;&nbsp; &nbsp; //System.setProperty("pf4j.mode", RuntimeMode.DEPLOYMENT.toString());&nbsp; &nbsp; //System.setProperty("pf4j.mode", RuntimeMode.DEVELOPMENT.toString());&nbsp; }&nbsp; @Override&nbsp; protected PluginLoader createPluginLoader() {&nbsp; &nbsp; // load only jar plugins&nbsp; &nbsp; return new ParentClassLoaderJarPluginLoader(this);&nbsp; }&nbsp; @Override&nbsp; protected PluginDescriptorFinder createPluginDescriptorFinder() {&nbsp; &nbsp; // read plugin descriptor from jar's manifest&nbsp; &nbsp; return new ManifestPluginDescriptorFinder();&nbsp; }}解决方法 #2 如果未创建 extensions.idx 文件,则说明您的注释处理有问题。您可能想解决问题的根源,但也可以尝试解决它:https://groups.google.com/forum/#!topic/pf4j/nn20axJHpfI 指出我手动创建 META-INF/extensions.idx 文件并确保静态内部类没有 args 构造函数。有了这个改变,事情就开始了。注意在 extensions.idx 文件中正确设置类名 - 否则您将在处理程序列表中得到一个空条目注意有一个空参数构造函数,否则你会得到一个异常@Extensionpublic static class&nbsp; MBClickHandler implements ClickHandler {&nbsp; /**&nbsp; &nbsp;* constructor with no argument&nbsp; &nbsp;*/&nbsp; public MBClickHandler() {&nbsp; }src/main/resources/META-INF/extensions.idxcom.bitplan.mb.MBClickHandlerPlugin$MBClickHandler要检查的代码extension.idx 条目的正确名称MBClickHandler ch=new MBClickHandler();File extFile=new File("src/main/resources/META-INF/extensions.idx");String extidx=FileUtils.readFileToString(extFile,"UTF-8");assertEquals(extidx,ch.getClass().getName());检查扩展List<PluginWrapper> startedPlugins = pluginManager.getStartedPlugins();&nbsp; &nbsp; for (PluginWrapper plugin : startedPlugins) {&nbsp; &nbsp; &nbsp; &nbsp;String pluginId = plugin.getDescriptor().getPluginId();&nbsp; &nbsp; &nbsp; &nbsp;System.out.println(String.format("Extensions added by plugin '%s':", pluginId));&nbsp; &nbsp; &nbsp; &nbsp;Set<String> extensionClassNames = pluginManager.getExtensionClassNames(pluginId);&nbsp; &nbsp; &nbsp; &nbsp;for (String extension : extensionClassNames) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;System.out.println("&nbsp; &nbsp;" + extension);&nbsp; &nbsp; &nbsp; &nbsp;}&nbsp; &nbsp; }
随时随地看视频慕课网APP

相关分类

Java
我要回答