简体   繁体   English

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

[英]The exception java.lang.NoSuchMethodError thrown when invoking Azure storage related java API

Leave thread here for others who might run into same issues.为可能遇到相同问题的其他人留下线程。


I'm trying to reading blob from Azure container by code below:我正在尝试通过以下代码从 Azure container读取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());
    }
}

However, when it executes blobContainerClient.listBlobs() , exception as following throws:但是,当它执行blobContainerClient.listBlobs() ,会抛出以下异常:

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

I'm using maven as the build tool.我使用maven作为构建工具。

What happens here?这里会发生什么?

I finally found the solution and it's about the maven dependency conflict.我终于找到了解决方案,它是关于maven依赖冲突的。 More than one dependencies depend on netty in different versions.在不同版本中,不止一种依赖依赖于netty

I have added both aws and azure dependency in maven like below:我在 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>

By using maven tool mvn dependency:tree , I got output as following:通过使用 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

As we can see, azure and aws did depend on netty and the version of netty is different.正如我们所看到的, azureaws也取决于netty的,而版本netty是不同的。 So the question is about solving the conflict.所以问题是解决冲突。

As per introduciton from maven ,根据maven 的介绍,

Since Maven resolves dependencies transitively, it is possible for unwanted dependencies to be included in your project's classpath.由于 Maven 以传递方式解析依赖项,因此项目的类路径中可能包含不需要的依赖项。 For example, a certain older jar may have security issues or be incompatible with the Java version you're using.例如,某个较旧的 jar 可能存在安全问题或与您使用的 Java 版本不兼容。 To address this, Maven allows you to exclude specific dependencies.为了解决这个问题,Maven 允许您排除特定的依赖项。 Exclusions are set on a specific dependency in your POM, and are targeted at a specific groupId and artifactId.排除项是针对 POM 中的特定依赖项设置的,并且针对特定的 groupId 和 artifactId。 When you build your project, that artifact will not be added to your project's classpath by way of the dependency in which the exclusion was declared.构建项目时,该工件不会通过声明排除项的依赖项添加到项目的类路径中。

We need to exclude netty 4.1.17 so that it won't be added to project's classpath and set netty to azure explicitly.我们需要排除netty 4.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>

By adding above dependencies to pom.xml , the azure works fine then.通过将上述依赖项添加到pom.xmlazure可以正常工作了。

If you are using spring boot dependencies as mentioned below, please exclude the azure-core-http-netty and add new individual dependency for azure-core-http-okhttp as follows.如果您使用如下所述的 spring boot 依赖项,请排除 azure-core-http-netty 并为 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM