我正在开发一个Eclipse插件,它需要在编译时不知道的类。这些类通过jar文件在网络上发送。我想在运行时动态加载这些类。
我尝试过此处列出的方法:http://blog.imaginea.com/making-applications-work-together-in-eclipse/
不幸的是它没有达到预期的效果。当类被加载时,我不能在我加载它们的函数之外使用它们。我猜这与使用不同的类加载器有关。
感谢任何帮助。即使你告诉我,这是不可能的,所以我知道我不需要再看了。
答案 0 :(得分:5)
如果你将这些jar放入OSGi包中(即给它们一个MANIFEST.MF),那么你可以动态地将它们安装到OSGi运行库中。
如果您将插件激活器添加到插件中,那么您可以存储org.osgi.framework.BundleContext,然后您可以执行以下操作:
Bundle [] newBundle = new Bundle[] { bundleContext.install(location, newJarInputStream) };
packageAdmin.refreshPackages( newBundle );
packageAdmin.resolveBundles( newBundle);
packageAdmin
是org.osgi.service.packageAdmin.PackageAdmin的一个实例,您可以使用BundleContext#getService
新的jar可以是完整的捆绑包,也可以是以插件为主机的捆绑片段。如果它们是您的包的片段,则您的包(BundleContext#getBundle()
)将需要包含在传递给refreshPackages和resolveBundles的数组中。
(EDIT类加载)
如果您的插件具有依赖关系,那么插件代码中的Class.forName
将只能在新安装的包中找到类,这些依赖关系将在新的包解析后得到满足。
Import-Package
。在这种情况下,您的插件将需要包含在传递给refreshPackages
的数组中。 DynamicImport-Package
语句。在类加载期间解析动态导入另一种选择是在新安装的bundle的bundle对象上使用Bundle.loadClass
(而不是Class.forName)。这使用了新bundle的类加载器,因此你的插件本身不需要依赖新的bundle。
答案 1 :(得分:2)
我最近为一个插件来做这个:
这是显着的代码
URL[] urls = new URL[]{ new URL("jar", "", "file:" + jarFile.getAbsolutePath() + "!/")};
URLClassLoader cl = URLClassLoader.newInstance(urls, this.getClass().getClassLoader());
Class<?> loadedClass = cl.loadClass("com.whatever.SomeClass");