[英]How to use implementation loaded with different Java classloader?
I am writing a library where I allow people to provide implementations of certain interfaces using a plugin framework (it's JPF if you're familiar). 我正在编写一个库,我允许人们使用插件框架提供某些接口的实现(如果你熟悉的话,它是JPF)。 The plugins are not stored in the classpath.
插件不存储在类路径中。 The framework gives me a ClassLoader for each plugin, so when implementation named "MyImpl" of interface "MyInterface" is requested, I can find the correct plugin, and then use that plugin's ClassLoader to load the class, from which I can make an instance if I know something about the constructor.
该框架为每个插件提供了一个ClassLoader,因此当请求接口“MyInterface”的实现命名为“MyImpl”时,我可以找到正确的插件,然后使用该插件的ClassLoader来加载类,我可以从中创建一个实例如果我对构造函数有所了解。 So far so good.
到现在为止还挺好。
However, now I have a case where I need to call a method that is only available on that particular implementation. 但是,现在我需要调用一个仅在该特定实现上可用的方法。 So, there are two ways I could try to do this:
所以,有两种方法我可以尝试这样做:
Method 1: 方法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();
Method 2: 方法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()
Method 1 is the cleaner of the two, as it is most similar to how you would write the code if the class were "normal" and not accessible via a plugin. 方法1是两者中的清洁程序,因为它最类似于如果类是“正常”并且无法通过插件访问而编写代码的方式。 However, neither compiles.
但是,既不编译。
Options I've come up with so far: 到目前为止我提出的选项:
A. Use Method 2, but use reflection to do the methodOnlyInMyImpl method call (please, no!) A.使用方法2,但使用反射来执行methodOnlyInMyImpl方法调用(请,不!)
B. Place the plugin classes in the build path and then use Method 1, which would compile. B.将插件类放在构建路径中,然后使用方法1,它将编译。 (my current favorite)
(我目前最喜欢的)
C. B + when plugins are installed, copy the classfiles to another directory that is in the classpath, so the system classloader can load them (causes other problems) C. B +安装插件时,将类文件复制到类路径中的另一个目录,这样系统类加载器就可以加载它们(导致其他问题)
So, my questions are: 所以,我的问题是:
MyImpl foo
, won't it try to load MyImpl using the system classloader, which will fail (even though the Plugins.newInstance call would provide an instance of MyImpl)? MyImpl foo
,它是否会尝试使用系统类加载器加载MyImpl,这将失败(即使Plugins.newInstance调用将提供MyImpl的实例)? First, what advantage you get from the plugin mechanism, when you need to implement against the real implementation? 首先,当您需要针对实际实现实施时,您从插件机制获得了什么好处? The plugin should implement an interface and you can use the implementation via the interface.
该插件应该实现一个接口,您可以通过该接口使用该实现。
I am not fimilar with JPF, but java classes are never compatible when loaded by different classloaders. 我与JPF并不相似,但是当由不同的类加载器加载时,java类永远不兼容。 But there are two possible ways:
但有两种可能的方法:
The interface is in your classloader, the plugin classloader has your classloader as parent, so its interface is the same as yours. 接口在您的类加载器中,插件类加载器将您的类加载器作为父接口,因此其接口与您的接口相同。 The code 2 should work with this, when the method is decladed in the interface.
当在接口中声明方法时,代码2应该与此一起使用。
You can use serialisation. 您可以使用序列化。 This is a limited way more usefull transfering data objects between independent classloaders.
这是一种在独立类加载器之间传输数据对象更有用的有限方法。 I needed to use this for cross context dispatching with request parameter between two webapps.
我需要使用它来交叉上下文调度两个webapps之间的请求参数。
There's a library called TransLoader that was mentioned in a previous question. 在前一个问题中提到了一个名为TransLoader的库。 Here's the URL for the source: http://code.google.com/p/transloader/ .
以下是来源的网址: http : //code.google.com/p/transloader/ 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.