Java:项目中的两个 jar 具有相同的类。

新手上路,请多包涵

我有一个 java 项目,它使用两个具有相同类的导入 jar ( com.sun.mail.imap.IMAPFolder )。有没有办法在导入类时明确说明要使用哪个 jar?使用:

 import com.sun.mail.imap.IMAPFolder;

似乎按照构建路径顺序使用该类,但由于某种原因似乎并非如此

Exception in thread "main" java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:616)
        at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: java.lang.NoSuchMethodError: com.sun.mail.imap.IMAPFolder.idle()V
        at com.woodbury.GCM.HelperGmailMonitor.doEmail(HelperGmailMonitor.java:104)
        at com.woodbury.GCM.Launch.listen(Launch.java:16)
        at com.woodbury.GCM.Launch.main(Launch.java:10)
        ... 5 more

在运行时。我正在 eclipse 中构建项目。

原文由 Fenrir 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 697
2 个回答

您不能只在 Java 源代码中做您要求的事情。 Java 不是为此而设计的。

这是一个糟糕的情况,只能使用自定义类加载器可靠地处理,每个类加载器都提供您需要的一个 jar。由于您首先要问这个问题,因此这可能不是您应该采用的方式,因为这会带来很多新的耗时问题。

我强烈建议您找出 为什么 您的类路径中有同一个 jar 的两个不同版本,然后重新编写您的程序,以便您只需要一个版本。

原文由 Thorbjørn Ravn Andersen 发布,翻译遵循 CC BY-SA 3.0 许可协议

当一个类被加载时,第一个与相关的 ClassLoader 的请求的完全限定名称相匹配的实现被返回。具有相同完全限定名称的任何其他实现都有效地隐藏到 ClassLoader

这在标准 Java SE 应用程序中意味着第一个代码库(即 jar)在类路径中列出并提供所需的类,并且隐藏所有其他代码库对相同完全限定类的实现。

例子:

假设 A.jar 包含编译后的类

package com.stackoverflow.example;
public class Hello {
     public static String getGreeting(){
         return "Hello, A!"
     }
}

假设 B.jar 包含编译后的类

package com.stackoverflow.example
public class Hello {
     public static String getGreeting(){
         return "Hello, B!"
     }
}

请注意,在上述两个类中都具有相同的完全限定名称。

假设主类是

   import com.stackoverflow.example.Hello;

   public class ExampleMain {
       public static void main(String[] args){
            System.out.println(Hello.getGreeting());
       }
   }

如果我要调用我的程序

java -cp A.jar:B.jar ExampleMain

输出是: Hello, A!

如果我像这样反转类路径

java -cp B.jar:A.jar ExampleMain

输出是: Hello, B!

原文由 Dev 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题