2

我有一组三个 RCP 插件:一个是我的主应用程序插件,另一个是计算集合,第三个是 GridGain 的包装器,其中必须从计算插件创建类的实例。

主插件使用 ExtensionPoint 实例化从计算和 GridGain 插件中实例化类,例如:

    IExtensionRegistry registry = Platform.getExtensionRegistry();

    IExtensionPoint providerExtensionPoint = registry.getExtensionPoint(EXT_CORE_DATA_PROVIDERS);
    IConfigurationElement[] providers = providerExtensionPoint.getConfigurationElements();

    List<DataProviderFactory> dataProviders = new ArrayList<DataProviderFactory>();
    for (IConfigurationElement member : providers) {
        try {
            Object obj = member.createExecutableExtension(K_CLASS);
            if (obj instanceof DataProviderFactoryFactory) {
                DataProviderFactoryFactory factory = (DataProviderFactoryFactory) obj;
                for (Object o : factory.createProviderFactories(this, holdingProperties())) {
                    dataProviders.add((DataProviderFactory) o);
                }
            }
        }
        catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    return dataProviders;

因此与其他插件没有直接依赖关系。

当 GridGain 必须从计算插件实例化类的实例时,我的问题就出现了。由于 GridGain 插件没有直接依赖于计算插件,它的类加载过程看不到那里的类,所以我得到了 ClassNotFoundException。

我过去曾使用RCP buddy policies解决过类似的问题,这似乎是一个类似于您在使用 ORM 时遇到的问题。但是,“注册”策略取决于定义类的插件(在我的情况下为计算插件)依赖于实例化它们的插件(GridGain 插件)这一事实。在我的场景中,没有这样的依赖。因此,将 BuddyPolicy: 注册到 GridGain 和 RegisterBuddy: gridgain 添加到计算插件不起作用。

我发现让 GridGain 插件从计算插件中解析类的唯一方法是将 GridGain 显式定义为对计算具有依赖性。在我看来,这不应该是必要的,应该有一种方法可以让它成为一个软依赖,如果存在计算插件,GridGain 可以从中实例化类。是否有另一种方法来模拟这种相互依赖关系,以便我的类加载问题消失?

4

3 回答 3

1

GridGain 插件应该有某种方式依赖于您的计算插件。如果您不定义任何依赖项,GridGain 将无法访问计算类。我可以想到这一点,创建另一个具有通用接口的插件(基本插件)并使 GridGain 和计算依赖于基本插件。在计算插件中为您在基本插件中定义的接口公开声明性服务。

在 GridGain 插件中,使用 osgiServiceTracker等待 Calculations 插件中暴露的服务。

于 2012-10-18T22:26:48.183 回答
1

有两种安全的方法可以在不导入包的情况下从另一个包中实例化类。

在大多数情况下,您想要一个您知道的接口的实现。对于这种情况,一种好的方式是为包中的类创建一个工厂,该类知道 impl 并发布它,例如使用 OSGi 服务。然后可以在工厂内部使用 new 实例化该类。

另一种方法是使用知道 impl 的包的类加载器。在这种情况下,您必须使用允许检索其他包的类加载器的接口。然后你可以通过它的名字来加载这个类。

于 2012-10-19T06:06:19.373 回答
1

你可以:

  1. 使对计算插件的依赖成为可选的。

  2. 如果您事先知道包名称,请使用Import-Package而不是(同样,可能是可选的)。Require-Bundle

  3. 使用DynamicImport-Package,但在大多数情况下应避免使用。

于 2012-10-19T09:11:06.903 回答