调用Azure存储相关的java API时引发异常java.lang.NoSuchMethodError



将线程留在此处,供可能遇到相同问题的其他人使用。


我正试图通过以下代码从Azurecontainer读取blob

public static void main(String[] args) {
String connectStr = "it's a workable connection string...";
// Create a BlobServiceClient object which will be used to create a container client
BlobServiceClient blobServiceClient = new BlobServiceClientBuilder().connectionString(connectStr).buildClient();
String containerName = "eugenecontainer";
BlobContainerClient blobContainerClient = blobServiceClient.getBlobContainerClient(containerName);
for (BlobItem blobItem: blobContainerClient.listBlobs()){
System.out.println(blobItem.getName());
}
}

然而,当它执行blobContainerClient.listBlobs()时,会抛出以下异常:

Exception in thread "main" java.lang.NoSuchMethodError: io.netty.bootstrap.Bootstrap.config()Lio/netty/bootstrap/BootstrapConfig;

我使用maven作为构建工具。

这里发生了什么?

我终于找到了解决方案,它是关于maven依赖冲突的。多个依赖关系依赖于不同版本中的netty

我在maven中添加了awsazure依赖项,如下所示:

<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.11.327</version>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-storage-blob</artifactId>
<version>12.0.0</version>
</dependency>

通过使用maven工具mvn dependency:tree,我得到了如下输出:

[INFO] |  +- com.amazonaws:aws-java-sdk-kinesisvideo:jar:1.11.327:compile
[INFO] |  |  +- io.netty:netty-codec-http:jar:4.1.17.Final:compile
[INFO] |  |  |  - io.netty:netty-codec:jar:4.1.17.Final:compile
[INFO] |  |  - io.netty:netty-handler:jar:4.1.17.Final:compile
[INFO] |  |     +- io.netty:netty-buffer:jar:4.1.17.Final:compile
[INFO] |  |     |  - io.netty:netty-common:jar:4.1.17.Final:compile
[INFO] |  |     - io.netty:netty-transport:jar:4.1.17.Final:compile
[INFO] |  |        - io.netty:netty-resolver:jar:4.1.17.Final:compile
[INFO] |  - com.azure:azure-storage-common:jar:12.0.0:compile
[INFO] |     - com.azure:azure-core-http-netty:jar:1.0.0:compile
[INFO] |        +- io.netty:netty-handler-proxy:jar:4.1.42.Final:compile
[INFO] |        |  - io.netty:netty-codec-socks:jar:4.1.42.Final:compile
[INFO] |        +- io.projectreactor.netty:reactor-netty:jar:0.9.0.RELEASE:compile
[INFO] |        |  +- io.netty:netty-codec-http2:jar:4.1.39.Final:compile
[INFO] |        |  +- io.netty:netty-transport-native-epoll:jar:linux-x86_64:4.1.39.Final:compile
[INFO] |        |  |  - io.netty:netty-transport-native-unix-common:jar:4.1.39.Final:compile
[INFO] |        |  - io.projectreactor.addons:reactor-pool:jar:0.1.0.RELEASE:compile
[INFO] |        - com.azure:azure-core-test:jar:1.0.0:compile
[INFO] |           - io.projectreactor:reactor-test:jar:3.3.0.RELEASE:compile

可以看出,azureaws确实依赖于netty,并且netty的版本不同。因此,问题在于解决冲突。

根据maven的介绍,

由于Maven通过传递方式解析依赖关系,因此将不需要的依赖项包含在项目的类路径中。对于例如,某个较旧的jar可能存在安全问题或与您使用的Java版本不兼容。为了解决这个问题,Maven允许您排除特定的依赖项。已设置排除项针对POM中的特定依赖项,并针对特定groupId和artifactId。当你构建你的项目时,这个工件不会通过依赖项的方式添加到项目的类路径中其中宣布排除。

我们需要排除netty4.1.17,这样它就不会被添加到项目的类路径中,并显式地将netty设置为azure

<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.11.327</version>
<exclusions>
<exclusion>
<artifactId>*</artifactId>
<groupId>io.netty</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-storage-blob</artifactId>
<version>12.0.0</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.42.Final</version>
</dependency>

通过将上述依赖项添加到pom.xmlazure就可以正常工作。

如果您使用下面提到的spring-boot依赖项,请排除azure core http-nety,并为azure core-http-okhttp添加新的单独依赖项,如下所示。

<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>azure-spring-boot-starter-storage</artifactId>
<exclusions>
<exclusion>
<groupId>com.azure</groupId>
<artifactId>azure-core-http-netty</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-core-http-okhttp</artifactId>
<version>1.2.1</version>
</dependency>

最新更新