在 Java 中访问包的多个版本

发布于 2024-10-07 22:07:45 字数 734 浏览 5 评论 0原文

我们有几个使用 Apache HTTPClient 3 发出 HTTP 请求的应用程序。最近,出于各种原因,我们还开始创建使用 HTTPClient 4 的 Web 服务客户端。 Apache 的立场是“主要版本不向后兼容”。虽然我很想更新我们所有的项目以使用版本 4,但这根本不可行。

因此,虽然我的主要问题相当笼统,但我的特殊问题是。 如何在同一应用程序中使用 HTTPClient 版本 3 和 4? 在我们的示例中,应用程序可以是 Web、桌面或命令行应用程序。

我已阅读 java-dynamically-load-multiple-versions 的问题-of-same-class 看起来半接近,但我不太关心动态部分。事实上,我希望 JAR 与应用程序一起提供(例如,用于 Web 应用程序的 WEB-INF/lib)我还看到 OSGi 在与此类似的问题中提到了很多,但它似乎太过分了,或者可能过于复杂(也许一个简单的例子可以证明事实并非如此)。

最后,我希望能够向团队提供一组他们可以放入的 jar,并且它使用 HTTP Client 3 独立于他们的项目工作。

We have several applications that use Apache HTTPClient 3 to make HTTP requests. Recently we have also began creating web service clients that use HTTPClient 4 for various reasons. The Apache stance is that "major releases are not backwards compatible". While I would love to update all of our projects to use version 4, that's simply not feasible.

So, while my main question is rather general, my particular question is. How can I use HTTPClient version 3 and 4 in the same application? In our case an application can be a web, desktop, or command line app.

I have read the SO question for java-dynamically-load-multiple-versions-of-same-class which seems semi close but I don't care so much about the dynamic part. In fact I would like the JARs to be shipped with the app (example, WEB-INF/lib for web apps) I also see OSGi mentioned a lot in questions similar to this one but it seems to be overkill or perhaps overly complex (maybe a simple example could prove otherwise).

In the end I want to be able to hand a team a set of jars that they can drop in and it just works independent of their project using HTTP Client 3.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

白昼 2024-10-14 22:07:45

正如其他人所说,您可以创建多个类加载器并单独加载两个版本。这部分很简单。

问题是,这本质上分割了您的“类空间”,并且从应用程序的某些部分引用 v3 而从应用程序的其他部分引用 v4 仍然非常困难。您必须非常仔细地对您的应用程序进行分区...那么为什么不将其拆分并交付两个应用程序呢?

如果您能够将功能分解到服务中,OSGi 可能是一个解决方案。但是,将遗留应用程序转换为 OSGi 并不是一件容易的事情,而且它肯定不会是摆脱您所陷入的陷阱的廉价方法。我是作为一本关于 OSGi 的书的作者和一位著名的 OSGi 布道者这样说的。将应用程序转换为 OSGi 的长期目标将为您带来巨大的好处,但也会涉及大量的前期成本。

As others have stated, you can create multiple classloaders and load the two versions in isolation. This part is easy enough.

The problem is, this essentially splits your "class space", and it will still be very hard to refer to v3 from some parts of your application while referring to v4 from other parts of your application. You will have to partition your application very carefully... so why not just split it and deliver two applications?

OSGi could be a solution if you are able to factor out functionality into services. But converting a legacy application to OSGi is not something to take on lightly, and it will certainly not be a cheap escape from the trap that you have walked into. I say this as the author of a book on OSGi and a well-known OSGi evangelist. A long-term goal of converting your applications to OSGi would bring you great benefits, but will also involve significant up-front costs.

无边思念无边月 2024-10-14 22:07:45

一个简单而直接的解决方案是获取 HttpClient3 和 HttpClient4 的源代码,并将

HttpClient3 和 org.apache.commons 的包名称重构为诸如 org.apache.commons.httpclient3 之类的名称。 httpclient4 为 HttpClient4 避免冲突。然后编译,打包,大功告成。

现在可以很容易地在两个实现之间切换,并且它们不会在类加载器中发生冲突。

An easy but straightforward solution would be you get the sources for HttpClient3 and HttpClient4, and refactor the package names to something like

org.apache.commons.httpclient3 for HttpClient3 and org.apache.commons.httpclient4 for HttpClient4 to avoid collision. Then compile, package, done.

Now it is easy to switch between the two implementations and they don't collide in the classloader.

温折酒 2024-10-14 22:07:45

使用多个类加载器,每个类加载器对应您希望采用的每个 HTTP 客户端。

最简单的方法是扩展 URLClassLoader 并破解它以分别对每个版本的类路径进行硬编码。然后,您只需要确保其余代码知道要使用哪个版本的 HTTP 客户端(并访问正确的类加载器来获取它)。

Use multiple class loaders, one for each HTTP Client you wish to embrace.

The simplest way is to extend URLClassLoader and hack it to hardcode the classpath for each version separately. Then you just need to make sure the rest of the code knows which version of the HTTP client to use (and accesses the correct classloader to get to it).

拍不死你 2024-10-14 22:07:45

您必须为 v3 和 v4 使用单独的类加载器。将 v3 和 v4 jar 放在应用程序类路径之外的单独文件夹中。使用 URLClassLoadedr 加载每个版本。传递给每个类加载器的 URL 应包含特定版本的 HTTP 客户端的 URL。

但我可以给你一个建议吗?在开始之前,首先检查您是否确实需要所有这些。没错,版本可能不兼容。但他们很有可能是这样的。

You have to use separate class loaders for v3 and v4. Put v3 and v4 jars to separate folders beyond your application classpath. Use URLClassLoadedr to load each one of the versions. The URL that you pass to each one of class loaders should contain URL to specific version of HTTP client.

But may I give you an advice? Check first that you really need all these before you are starting. That is right that the versions could be incompatible. But there is a huge chance that they are.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文