3

我正在编写一个库,允许人们使用插件框架(如果您熟悉的话,它是 JPF)来提供某些接口的实现。插件不存储在类路径中。该框架为每个插件提供了一个 ClassLoader,因此当请求接口“MyInterface”的名为“MyImpl”的实现时,我可以找到正确的插件,然后使用该插件的 ClassLoader 加载类,我可以从中创建一个实例如果我对构造函数有所了解。到现在为止还挺好。

但是,现在我有一个案例,我需要调用一个仅在该特定实现上可用的方法。所以,有两种方法我可以尝试做到这一点:

方法一:

// Makes sure that MyImpl has been loaded, using the custom classloader
Plugins.getClass(MyInterface.class, "MyImpl");
// This line will not compile because MyImpl is not available at build time
MyImpl foo = new MyImpl();
// If I could get this far, this line would work:
foo.methodOnlyInMyImpl();

方法二:

// This call will get an instance of MyImpl (already written and tested)
MyInterface foo = Plugins.getInstance(MyInterface.class, "MyImpl");
// Compiler error because there is no MyInterface.methodOnlyInMyImpl method.
foo.methodOnlyInMyImpl()

方法 1 是两者中更简洁的方法,因为它最类似于如果类是“正常”且无法通过插件访问时编写代码的方式。但是,两者都无法编译。

到目前为止我提出的选项:
A. 使用方法 2,但使用反射来执行 methodOnlyInMyImpl 方法调用(请不要!)
B. 将插件类放在构建路径中,然后使用方法 1,这将编译. (我目前最喜欢的)
C. B + 安装插件时,将类文件复制到类路径中的另一个目录,以便系统类加载器可以加载它们(导致其他问题)

所以,我的问题是:

  1. 我是否错过了另一个更好的想法?
  2. 如果我做 B,我会在运行时遇到问题吗?毕竟,使用 MyImpl 的类可能已经使用系统类加载器加载了。所以,一旦它看到MyImpl foo,它会不会尝试使用系统类加载器加载 MyImpl,这会失败(即使 Plugins.newInstance 调用会提供 MyImpl 的实例)?
4

2 回答 2

3

首先,当您需要针对实际实现进行实现时,您从插件机制中获得什么优势?该插件应该实现一个接口,您可以通过该接口使用该实现。

我不熟悉 JPF,但是当由不同的类加载器加载时,java 类永远不兼容。但是有两种可能的方法:

  1. 接口在你的类加载器中,插件类加载器有你的类加载器作为父类,所以它的接口和你的一样。当方法在接口中声明时,代码 2 应该与此一起使用。

  2. 您可以使用序列化。这是一种在独立类加载器之间传输数据对象更有用的有限方式。我需要使用它在两个 webapps 之间使用请求参数进行跨上下文调度。

于 2009-11-18T19:19:24.360 回答
2

上一个问题中提到了一个名为 TransLoader 的库。这是源的 URL:http://code.google.com/p/transloader/

于 2009-11-18T19:34:32.643 回答