简体   繁体   English

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

[英]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: 所以,我的问题是:

  1. Am I missing another idea that's better? 我错过了另一个更好的想法吗?
  2. If I do B, will I have problems at runtime? 如果我做B,我会在运行时遇到问题吗? After all, the class using MyImpl will presumably have been loaded using the system classloader. 毕竟,使用MyImpl的类可能已经使用系统类加载器加载。 So, as soon as it sees 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: 但有两种可能的方法:

  1. 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应该与此一起使用。

  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.

相关问题 如何用Java中的其他ClassLoader重新加载已加载的类? - How to reload a loaded class with different ClassLoader in Java? 如何使用反射检查加载了不同ClassLoader的类的非静态字段? - How to use Reflection to inspect non-static fields of a class that is loaded with a different ClassLoader? Java Classloader - 如何引用jar的不同版本 - Java Classloader - how to reference different versions of a jar 如何比较从2个不同的类加载器加载的2个类 - How to compare 2 classes which are loaded from 2 different classloader 如何投射相同加载的不同类加载器的两个实例? - How to cast two instance of the same loaded different classloader? 如何使用由不同的ClassLoader实例化的对象 - How to use an object instantiated by a different ClassLoader 如何验证Java中的ClassLoader是否已加载.jar或类 - How to verify that a .jar or a class has been already loaded by the ClassLoader in Java 如何显式调用标准Java类加载器实现进行序列化? - How explicitly call the standard java classloader implementation for serialization? 如何在Java中使用自定义ClassLoader来新建对象 - How to use Custom ClassLoader to new Object in Java (JAVA) 类加载器和库的使用 - (JAVA) ClassLoader and use of libraries
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM