【问题标题】:executing java method with dependencies inside a dynamically loaded class在动态加载的类中执行具有依赖关系的java方法
【发布时间】:2011-04-06 19:49:21
【问题描述】:
我的 jar 文件有自己的库,就像任何其他 netbeans 项目一样。此外,我有一个“插件”文件夹以 .jar 文件格式存储插件。我正在使用 URLClassLoader 加载插件,并且我也在执行正确的方法,没有任何问题。
但是,插件文件夹中的 jar 文件可能包含与不在我的类路径中的其他包(例如 java-mail)的依赖关系(插件文件夹也不在我的类路径中),所以我担心该插件是否会正确执行。我也不知道应该在哪里存储该依赖项。
我可以做些什么来解决这个问题吗?我应该在哪里存储插件依赖项?
谢谢。
【问题讨论】:
标签:
java
plugins
dependencies
classloader
【解决方案1】:
ClassLoader 类使用委托模型来搜索类和资源。 ClassLoader 的每个实例都有一个关联的父类加载器。当请求查找类或资源时,ClassLoader 实例将在尝试查找类或资源本身之前将对该类或资源的搜索委托给其父类加载器。虚拟机的内置类加载器称为“引导类加载器”,它本身没有父级,但可以作为 ClassLoader 实例的父级。
(来自ClassLoader的javadoc)
上面的段落意味着通常情况下,您的类加载器会形成一棵树,并且每个类加载器在尝试加载类之前询问其父级。所以理论上,如果加载插件的类加载器或任何上游类加载器都可以看到您的依赖项,那么它将起作用。
但是,有两个注意事项:
- 如果你的插件调用
Thread.setContextClassLoader(),那可能会搞砸。但这应该是插件作者的更多关注,而不是您的关注。
- Web 服务器通常不遵守此委托规则,以确保不同 Web 应用程序与服务器本身之间的最大分离。
(如果有一些我可以查看的代码,我可能会给出一个不太通用的答案。)
【解决方案2】:
根据 biziclop,我已将依赖项放在插件文件夹中。它似乎工作,但我需要下载额外的包。
为了澄清,我使用 apache httpClient 库制作了一个插件。我制作了 jar 文件,然后将 jar 文件及其依赖项(httpClient 和 httpCore)放在插件文件夹中。当我执行插件时,出现了“NoClassDefFoundError”。为了克服这个问题,我下载了“commons-logging”和“servlet”包,并将它们添加到插件文件夹中。
至少,这不是我的问题,因为插件开发人员应该测试插件并提供那些额外的包,但事实是这些额外的包是在测试插件时而不是在编译时公开的。
感谢您的帮助!