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中构建项目。

您无法在Java源代码中执行您的要求。 Java不是为此而设计的。

这是一个糟糕的情况,只能通过自定义类加载器可靠地处理,每个加载器都提供您需要的其中一个jar子。 既然你首先要问这个问题,这可能不是你应该去的方式,因为这会带来很多新的耗时问题。

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

加载类时,匹配相关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!

1)通常:是的,您可以在不同的.jar文件中使用相同的类:您只需使用完全限定的包名称消除它们的歧义。 “Date”类(存在于java.util和java.sql中)是一个很好的例子。

2)如果你有两个不同的 .jar文件,这些文件具有相同的完全限定的软件包名称…可能性,你就会发生冲突。 即使您可以通过使用类加载器来破解InvocationTargetException,您仍可能遇到其他问题。 在这种情况下,听起来好像你的两个.jar文件有两个不同的JavaMail API实现。 我不知道。

3)最安全的选择是满足您所有程序的参考, 而不会有冲突的风险。 我相信如果您从Oracle的JavaMail网页上获取了“官方”.jar,您可以这样做:

https://java.net/projects/javamail/pages/Home

‘希望有所帮助!

是的,有办法解决这个问题。 在我的场景中,我有两个具有相同名称和相同路径的类,eclipse总是导入错误的类。 我所做的是更改构建路径中的jar顺序,eclipse将选择构建路径中的第一个。

如果您使用的是IDE,则可以设置将文件导出到类加载器的顺序。

我在eclipse上工作,我使用maven。 当我使用maven安装项目时,它产生了许多额外的jar(我没有在我的依赖项中定义)并且有一个文件org.w3c.dom.Element存在于2个jar文件中,同一个文件的第3个实例也是在JRE7。

为了确保获取正确的文件,我所要做的就是转到Java Build Path – > Order and Export 。 选择Jar文件,我希望类加载器提供更多的首选项,并使用“Up”按钮将其移动。

这是它的外观。 Eclipse  -  Java构建路径 -/>订单和导出”> 请注意,此图片适用于日食。 但对于其他IDE,肯定会有类似的方法来解决这个问题。 </p>

</div><!-- #comment-## -->

	<div class=