【问题标题】:Adding jars to an Eclipse plugin at runtime在运行时将 jars 添加到 Eclipse 插件
【发布时间】:2011-01-28 15:39:53
【问题描述】:

我正在开发一个需要在编译时未知的类的 Eclipse 插件。这些类在 jar 文件中通过网络发送。我想在运行时动态加载这些类。

我已经尝试过这里列出的方法:http://blog.imaginea.com/making-applications-work-together-in-eclipse/

不幸的是,它没有达到预期的效果。虽然确实加载了类,但我不能在加载它们的函数之外使用它们。我猜这与使用不同的类加载器有关。

感谢任何帮助。即使你告诉我,这是不可能的,所以我知道我不必再看下去了。

【问题讨论】:

    标签: java eclipse eclipse-plugin


    【解决方案1】:

    如果您将这些 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 的数组中。

    (编辑类加载) 插件代码中的Class.forName 只会在新安装的捆绑包中找到类,前提是您的插件具有新捆绑包解决后将满足的依赖项。

    • 一种方法是在你的插件清单中添加一个可选的Import-Package。在这种情况下,您的插件需要包含在传递给refreshPackages 的数组中。
    • 另一种选择是在插件清单中使用DynamicImport-Package 语句。动态导入在类加载期间解析

    另一种选择是在新安装的包的包对象上使用Bundle.loadClass(而不是 Class.forName)。这使用了新包的类加载器,因此您的插件本身不需要依赖于新包。

    【讨论】:

    • 谢谢。这听起来是个不错的方法。不过,我仍然有一些麻烦。我设法加载了捆绑包。但是 Class.forName("MyClass") 仍然会抛出 ClassNotFound 异常。我指定了package,里面包含manifest的export语句中的class
    • 我编辑了原始答案,并在安装捆绑包后提供了有关类加载的更多详细信息。
    【解决方案2】:

    我最近为一个 Eclipse 插件做了这个:

    这是显着的代码

    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");
    

    【讨论】:

      猜你喜欢
      • 2011-08-10
      • 2012-03-14
      • 2017-04-30
      • 2016-05-17
      • 2011-11-17
      • 2020-03-31
      • 2011-04-05
      • 2013-06-18
      • 2019-10-14
      相关资源
      最近更新 更多