关于在不同的jar中存在两个同名类?

时间:2016-09-19 14:44:25

标签: java classpath classloader

在我当前的项目中,我使用Guava Cache来缓存一些过期的东西,但是当实际调用此接口时,它有以下错误

Caused by: java.lang.NoSuchMethodError: com.google.common.base.Platform.systemNanoTime()J
    at com.google.common.base.Ticker$1.read(Ticker.java:64)
    at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2225)

原因是类路径中有两个Platform

enter image description here

Gauva中的一个,google-collections:jar

中的一个

LocalCache的Guava使用Paltform google-collections导致此错误。我对此有一些疑问,为什么不在同一个jar中的Class有更高的优先级?为什么不随机选择一个,但始终使用Platform的{​​{1}}?

3 个答案:

答案 0 :(得分:1)

两个罐子可能包含相同的类名。当您导入两个相同库的不同版本的jar时会发生这种情况。

如果您使用maven导入依赖项,例如导入库时,它可能会导入导致此类问题的其他库的依赖项。在这种情况下,您需要明确指出在导入库时需要排除辅助依赖项。这是通过exclusions标记完成的。

答案 1 :(得分:0)

您可以通过指定classpath顺序来强制优先级。 Java在jar中查找类,以便在类路径中进行pecifyed。

如果您使用maven和ide运行,则无法控制类路径的顺序,但您可以从类路径中排除dependee模块。

GL_HALF_FLOAT_OES

在这种情况下, <dependency> <groupId>some</groupId> <artifactId>id1</artifactId> <version>1.0.0.0</version> <exclusions> <exclusion> <groupId>another</groupId> <artifactId>id2</artifactId> </exclusion> </exclusions> </dependency> 将不再出现在您的类路径中。

答案 2 :(得分:0)

类加载优先级将取决于ClassLoader,你可以找到很多关于java类加载的文章。如果您尝试运行独立的Java应用程序,则可能会通过URLClassLoader完成类加载。

在这种情况下,-cp或-classpath中给出的所有url(jar文件位置或类)将作为URL添加到URLClassLoader,然后当应用程序需要加载类时,此URLClassLoader将迭代其URL并且一旦它找到了它将被加载的类。

所以一切都取决于类路径顺序。

注意:但在某些上下文中,类加载并不简单。例如:jboss-module类加载器。