我们有几个使用Apache HTTPClient 3发出HTTP请求的应用程序。最近我们也开始创建使用HTTPClient 4的Web服务客户端,原因有很多。 Apache的立场是“主要版本不向后兼容”。虽然我很乐意将所有项目更新为使用版本4,但这根本不可行。
所以,虽然我的主要问题相当笼统,但我的具体问题是。 如何在同一个应用程序中使用HTTPClient版本3和4?在我们的示例中,应用程序可以是Web,桌面或命令行应用程序。
我已经阅读了SO question for java-dynamically-load-multiple-versions-of-same-class,这似乎是半封闭的,但我并不在乎动态部分。事实上我希望JAR随应用程序一起提供(例如,WEB-INF / lib for web apps)我也看到OSGi在与此类似的问题中提到了很多,但它似乎有点矫枉过正过于复杂(也许一个简单的例子可能证明不是这样)。
最后,我希望能够为一个团队提供一组他们可以投入使用的罐子,它只是使用HTTP Client 3独立于他们的项目。
答案 0 :(得分:6)
正如其他人所说,您可以创建多个类加载器并单独加载这两个版本。这部分很容易。
问题是,这基本上会拆分你的“类空间”,从应用程序的其他部分引用v4时,仍然很难从应用程序的某些部分引用v3。您必须仔细分区您的应用程序非常 ...那么为什么不拆分它并提供两个应用程序呢?
如果您能够将功能分解为服务,OSGi可能是一种解决方案。但是将遗留应用程序转换为OSGi并不是一件容易接受的事情,它肯定不会成为你走进陷阱的便宜之选。我说这是一本关于OSGi和着名的OSGi布道者的书的作者。将您的应用程序转换为OSGi 的长期目标将为您带来巨大的好处,但也会带来巨大的前期成本。
答案 1 :(得分:2)
一个简单但直截了当的解决方案是获取HttpClient3和HttpClient4的源代码,并将包名称重构为类似
的内容 HttpClient3的org.apache.commons.httpclient3 和HttpClient4的 org.apache.commons.httpclient4 以避免冲突。然后编译,打包,完成。
现在很容易在两个实现之间切换,并且它们不会在类加载器中发生碰撞。
答案 2 :(得分:1)
使用多个类加载器,每个加载器对应一个您希望拥抱的HTTP客户端。
最简单的方法是扩展URLClassLoader并将其破解为分别对每个版本的类路径进行硬编码。然后,您只需要确保其余代码知道要使用哪个版本的HTTP客户端(并访问正确的类加载器以获取它)。
答案 3 :(得分:1)
您必须为v3和v4使用单独的类加载器。将v3和v4 jar放在应用程序类路径之外的单独文件夹中。使用URLClassLoadedr加载每个版本。传递给每个类加载器的URL应包含特定版本的HTTP客户端的URL。
但我可以给你一个建议吗?在开始之前首先检查您是否真的需要所有这些。这是正确的,版本可能不兼容。但他们很有可能。