【问题标题】:How to isolate an API's dependencies from the main program where it is used?如何将 API 的依赖项与使用它的主程序隔离开来?
【发布时间】:2011-04-14 22:24:05
【问题描述】:

我有一个系统,我正在通过定义明确的访问点为其创建插件。但是,有问题的插件使用了框架也使用的一些 jar,但版本不同。

代码的结构方式是集成在框架中的代码(扩展插件扩展点)和执行实际工作的代码很好地解耦(基本上归结为少于 10 个类的 API)。然而在这几个类的背后隐藏着一个相当大且复杂的系统(60+ jar 依赖)

问题如下:

如何确保由 API 类实例化的任何内容都是使用单独的私有 jar 文件库完成的?

换句话说,我如何隔离插件,使其与自己的私有库一起运行,而不会干扰主应用程序的库?

---- 编辑 ---- 到目前为止,唯一可以实现的两种方法是嵌入 OSGi 等框架或提供我自己的类加载器实现。后者可以完成,并且在网上提出了许多变体,尽管我没有发现任何东西可以让我对手头系统所需的稳定性充满信心。

这让我们回到了 OSGi,我希望有一个更轻量级的解决方案,但也许一旦我学习了这项技术,它就会证明它可以毫不费力地做我想做的事。

【问题讨论】:

    标签: java plugins jar classloader dependency-management


    【解决方案1】:

    据我所知,在 Java 中加载同一类的两个版本的唯一方法是运行 JVM 的两个实例。

    【讨论】:

    • 不。您可以使用自定义类加载器。见download-llnw.oracle.com/javase/1.5.0/docs/api/java/lang/…
    • 确实应该使用自定义类加载器。但是,我将如何让类加载器混淆私有库,同时确保 API 类能够找到它们的依赖项。我将研究 Class loader API,看看是否可以满足我的需求。
    • 这是可能的,因为这是大多数 Web 应用服务器运行的模型。有些人会分叉一个新的虚拟机,但大多数人会允许在同一个虚拟机下执行不同的应用程序,同时保持每个应用程序彼此隔离。我很想知道是否有一种快速的方法可以实现相同的功能。
    【解决方案2】:

    这就是OSGi 的用途。还有Equinox 一个不错的小实现。

    【讨论】:

    • 我知道 OSGi,但一直在寻找更轻量级的东西。如果我可以访问主应用程序,我可能会选择 OSGi 来实现插件基础设施,但由于我只是为现有系统开发插件,这似乎有点矫枉过正。更不用说引入这个增加的复杂性了。我牢记这一点,就好像其他解决方案失败一样,我会求助于 OSGi。
    • 嗯...那么我想您可以将类世界添加到您的插件依赖项中,并使用它来设置自定义类加载器,优先考虑插件的类路径。
    • 为此,您需要在插件中设置某种加载器类,该类加载器设置自定义类加载器,然后使用它来动态加载“真实”插件类。
    • 如果您发布更多信息,例如您的插件如何向系统公开接口以及您的插件如何被系统实例化,这将更容易举例说明。
    • 忘记了 classworlds 示例的链接:classworlds.codehaus.org/apiusage.html
    猜你喜欢
    • 2017-11-15
    • 2016-07-07
    • 2018-07-18
    • 1970-01-01
    • 2022-11-21
    • 2010-09-22
    • 1970-01-01
    • 2018-07-22
    • 2021-11-28
    相关资源
    最近更新 更多