如何使用加载不同Java类加载器的实现?

时间:2009-11-18 18:57:09

标签: java classloader jpf

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

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

方法1:

// 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();

方法2:

// 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的实例)?

2 个答案:

答案 0 :(得分:3)

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

我与JPF并不相似,但是当由不同的类加载器加载时,java类永远不兼容。但有两种可能的方式:

  1. 界面在您的类加载器中,插件类加载器将您的类加载器作为父类,因此其界面与您的相同。当在接口中声明方法时,代码2应该与此一起使用。

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

答案 1 :(得分:2)

上一个问题中提到了一个名为TransLoader的库。以下是来源的网址:http://code.google.com/p/transloader/