我有一个pom.xml,其中我有hadoop-core依赖
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-core</artifactId>
<version>${hadoop.version}</version>
<scope>provided</scope>
</dependency>
当我添加cfg4j作为编译时依赖
<dependency>
<groupId>org.cfg4j</groupId>
<artifactId>cfg4j-core</artifactId>
<version>4.4.0</version>
</dependency>
<dependency>
<groupId>org.cfg4j</groupId>
<artifactId>cfg4j-consul</artifactId>
<version>4.4.0</version>
</dependency>
我有一个异常"java.lang。NoSuchMethodError: javax.ws.rs.core.Response.someMethod"。我调查了这个问题,发现问题来自hadoop和cfg4j-consul。Hadoop核心依赖于jersey-core, cfg4j依赖于cxf。两者都将javax.ws.rs声明为依赖项,因此问题是jersey的版本是1.1,而cxf的版本是2.0.2。提供Hadoop依赖,因为Flink(框架)需要它,它在lib文件夹中。我不能只是升级它或删除它,也不能将它添加为编译时并排除lib。即使我能够做到这一点,我也不能保证hadoop会像预期的那样工作。我猜阴影不能解决问题,因为它不是与cfg4j,而是他的依赖关系之一。有解决冲突的方法吗?gradle有自己的方法来解决这样的问题吗?
两种方法:
- Shading:正如你所说的,这有点困难,因为这是一个可传递的依赖项,但我想看看Maven的阴影插件,如果有必要,它仍然可以直接声明依赖项。 不要使用依赖项,并尝试寻找其他库或解决方案来解决您的问题。
尝试以下步骤,这里是源代码:https://reflectoring.io/nosuchmethod/你的问题与maven和Gradle之间的选择无关,因此切换也无济于事。
修复NoSuchMethodErrorNoSuchMethodErrors
有很多不同的风格,但它们都归结为一个事实,即编译时类路径不同于运行时类路径。
以下步骤将有助于查明问题:
步骤1:找出课程的来源首先,我们需要找出包含有问题的方法的类来自哪里。我们在NoSuchMethodError
的错误信息中发现了这个信息:
Exception in thread "main" java.lang.NoSuchMethodError:
io.reflectoring.nosuchmethod.Service.sayHello(Ljava/lang/String;)Ljava/lang/String;
现在,我们可以在web或IDE中搜索哪个JAR文件包含这个类。在上面的例子中,我们可以看到它是来自我们自己的代码库的Service类,而不是来自另一个库的类。
如果找不到该类的JAR文件,可以在运行应用程序时添加Java选项-verbose:class。这将导致Java打印出所有的类和它们加载的jar:
[Loaded io.reflectoring.nosuchmethod.Service from file:
/C:/daten/workspaces/code-examples2/patterns/build/libs/java-1.0.jar]
步骤2:找出谁调用了这个类接下来,我们要找出调用方法的位置。该信息在堆栈跟踪的第一个元素中可用:
Exception in thread "main" java.lang.NoSuchMethodError:
io.reflectoring.nosuchmethod.Service.sayHello(Ljava/lang/String;)Ljava/lang/String;
at io.reflectoring.nosuchmethod.ProvokeNoSuchMethodError.main(ProvokeNoSuchMethodError.java:7)
这里,类ProvokeNoSuchMethodError
试图调用一个在运行时不存在的方法。我们现在应该找出这个文件属于哪个库。
步骤3:检查版本既然我们知道了NoSuchMethodError
在哪里被激发,缺少了什么方法,我们就可以采取行动了。
我们现在应该列出所有的项目依赖项。
在Gradle中,我们可以调用:。/gradlew dependencies>dependencies.txt如果我们使用Maven,可以使用以下命令获得类似的结果:
mvn dependency:list>dependencies.txt"在这个文件中,我们可以搜索包含缺少方法的类和尝试调用该方法的类的库。
通常我们会在某处找到这样的输出:
--- org.springframework.retry:spring-retry:1.2.2.RELEASE
| --- org.springframework:spring-core:4.3.13.RELEASE -> 5.0.8.RELEASE
上面的意思是spring-retry库依赖于4.3.13版本的spring-core,但是其他一些库也依赖于5.0.8版本的spring-core,并且推翻了依赖版本。
我们现在可以在dependencies.txt文件中搜索5.0.8。
最后,我们需要决定我们实际上需要哪一个版本来满足这两个依赖项。通常,这是较新的版本,因为大多数框架在某种程度上是向后兼容的。然而,也有可能是另一种方式,或者我们甚至根本无法解决冲突。