我有两个zookeeper的罐子。一个是官方的,另一个是修改过的,只有使用带有LDAP的zookeeper的实现。现在有一个名为ZooDefs的类,它位于org.apache.zookeeper中。
这个类存在于两个罐中,但是修改后的jar中还包含一个变量。
现在我想在我的代码中使用该变量,但我完全不知道如何使用它。
我提到this。但这有两个不同的包名。但我正在处理的罐子具有相同的名称,除了它们内部的逻辑。我知道这在最佳实践方面是完全错误的,但我被要求处理这个问题。
请建议如何处理。
答案 0 :(得分:1)
你去......
Project -> Properties -> Java Build Path -> Order and Export
...你可以先重新订购你想要的罐子......
答案 1 :(得分:0)
通常情况下,如果您对类加载的工作原理没有信心,那么让多个JAR包含具有相同FQDN的类并不是一个好主意。这是因为JAR在类加载方面不是逻辑单位,并且它们没有版本化(不会受到像mylibrary-1.0.0.jar这样的文件名的愚弄,这些只是文件名),加上班级加载"秘密"在后台并且没有明确控制它时,您无法确定在引用类时将加载哪些物理文件。这可能会导致一系列奇怪的错误,从静默错误到NullPointerExceptions再到NoClassDefFoundErrors。
正常情况下,即。当每个类只出现一次时,这意味着没有问题,因为当你引用一个类时,类加载器将只在类路径中找到该类的一个实例,因此它可以被认为是确定的。
在您的情况下,一个简单的解决方案是简单地用修改后的JAR替换原始JAR,其中修改后的JAR具有原始所有类(并且它们也是向后兼容的)。当然,这可能意味着您需要稍微更改构建过程,例如将您的zookeeper版本安装到本地Maven存储库并使用该版本。
更高级(也更有趣)的解决方案可能是使用OSGi(或其他类加载器 - 魔术框架)。 OSGi的工作原理是向清单添加额外的包元数据,您可以在其中指定包ID和版本号。这允许加载具有相同FQDN但具有不同版本号的多个类。
虽然Eclipse和其他IDE经常提供声明导入顺序的能力,但这不是最好的解决方案,因为它们依赖于它们可以控制类加载机制。这意味着,例如,当您构建可运行的JAR并在IDE外部运行时,您的应用程序可能会开始失败,因为它们几乎无法控制在其外部发生的类加载。