⇧ 湿度大国日本...
Gradleの依存関係のjarがよく分からない...
ローカル環境で動いていたものが、テスト環境に上げたところ、
NoSuchMethodError reactor.netty.http.client.httpclient.resolver
みたいなエラーが出て正常に動かないという事象が起きてるんだけど、
根本原因はコンパイル時に使ったjarファイルと実行時のjarファイルが違うこと。
jarファイルが同じものか確認することと、同じクラスを含むjarファイルが混在していたりしないかチェック。
一度あったのが、アプリをバージョンアップした後に古いjarがworkディレクトリに残っていたためにこのエラーが出たというケース。
⇧ということらしく、jarの差分を確認すれば、解決できるのか...
そもそも、同じ内容のbuild.gradleを利用しているのに、jarが残ることがあるのか?
⇧ 残るらしい...
確かに、ローカル環境で、build.gradleに依存関係を追加したり削除したりを繰り返して必要な依存関係の洗い出しを行っていたから、残ったjarファイルの影響でローカル環境は正常に動作していたってことになるんかな?
51.9. 依存関係のキャッシュ
Gradleのキャッシュでは、ローカルキャッシュによって問題が隠蔽されるようなことはありませんし、多くのビルドツールで直面してきたような不可解でデバッグ困難な動作をすることもありません。 また、その実装は帯域、ストレージ双方において効率的なものです。それにより、Gradleはエンタープライズでのビルドに必要な信頼性、再現性を達成しているのです。
http://gradle.monochromeroad.com/docs/userguide/dependency_management.html
⇧ ってあるんだけどな...
実際に不可解な現象が起きてるんだが...
Gradleの基本のドキュメントを見ると、
⇧リモートリポジトリにあるライブラリについては、一度ダウンロードできると、「Gradle Cache」に保存され、そちらを参照する仕組みらしい。
であれば、何を基準に、「Gradle Cache」に保存されたライブラリを参照しているかを知りたいんだけどな、まさかキャッシュされたものは無差別にすべて読み込むなんてことは無いと思うし。
最終的には、WARファイルにした後に、中身を確認してどのjarが読み込まれてるのかをチェックしていくしかないんかな...
ちなみに、自分の問題なく動いている環境では、
■build.gradle
plugins { id 'org.springframework.boot' version '2.6.6' id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'java' } group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = '1.8' configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' runtimeOnly 'org.postgresql:postgresql' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-actuator implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'com.azure.resourcemanager:azure-resourcemanager-mediaservices:2.0.0' implementation 'com.googlecode.json-simple:json-simple:1.1.1' implementation 'com.azure:azure-storage-blob:12.16.0' implementation 'com.azure:azure-identity:1.5.0' implementation 'com.azure:azure-security-keyvault-secrets:4.4.2' } tasks.named('test') { useJUnitPlatform() }
で、依存関係を追加しているのですが、
■メインクラスとその依存関係を含む実行可能なjar一覧
accessors-smart-2.4.8.jar antlr-2.7.7.jar asm-9.1.jar aspectjweaver-1.9.7.jar attoparser-2.0.5.RELEASE.jar azure-core-1.28.0.jar azure-core-http-netty-1.12.0.jar azure-core-management-1.5.3.jar azure-identity-1.5.0.jar azure-resourcemanager-mediaservices-2.0.0.jar azure-security-keyvault-secrets-4.4.2.jar azure-storage-blob-12.16.0.jar azure-storage-common-12.15.1.jar azure-storage-internal-avro-12.2.1.jar byte-buddy-1.11.22.jar checker-qual-3.5.0.jar classmate-1.5.1.jar content-type-2.2.jar hamcrest-2.2.jar hamcrest-core-2.2.jar HdrHistogram-2.1.12.jar hibernate-commons-annotations-5.1.2.Final.jar hibernate-core-5.6.7.Final.jar HikariCP-4.0.3.jar istack-commons-runtime-3.0.12.jar jackson-annotations-2.13.2.jar jackson-core-2.13.2.jar jackson-databind-2.13.2.2.jar jackson-dataformat-xml-2.13.2.jar jackson-datatype-jdk8-2.13.2.jar jackson-datatype-jsr310-2.13.2.jar jackson-module-parameter-names-2.13.2.jar jakarta.activation-1.2.2.jar jakarta.annotation-api-1.3.5.jar jakarta.persistence-api-2.2.3.jar jakarta.transaction-api-1.3.3.jar jakarta.xml.bind-api-2.3.3.jar jandex-2.4.2.Final.jar jaxb-runtime-2.3.6.jar jboss-logging-3.4.3.Final.jar jcip-annotations-1.0-1.jar jna-5.6.0.jar jna-platform-5.6.0.jar json-simple-1.1.1.jar json-smart-2.4.8.jar jul-to-slf4j-1.7.36.jar junit-4.13.2.jar lang-tag-1.5.jar LatencyUtils-2.0.3.jar log4j-api-2.17.2.jar log4j-to-slf4j-2.17.2.jar logback-classic-1.2.11.jar logback-core-1.2.11.jar micrometer-core-1.8.4.jar msal4j-1.11.3.jar msal4j-persistence-extension-1.1.0.jar netty-buffer-4.1.75.Final.jar netty-codec-4.1.75.Final.jar netty-codec-dns-4.1.75.Final.jar netty-codec-http-4.1.75.Final.jar netty-codec-http2-4.1.75.Final.jar netty-codec-socks-4.1.75.Final.jar netty-common-4.1.75.Final.jar netty-handler-4.1.75.Final.jar netty-handler-proxy-4.1.75.Final.jar netty-resolver-4.1.75.Final.jar netty-resolver-dns-4.1.75.Final.jar netty-resolver-dns-classes-macos-4.1.75.Final.jar netty-resolver-dns-native-macos-4.1.75.Final-osx-x86_64.jar netty-tcnative-boringssl-static-2.0.51.Final.jar netty-tcnative-classes-2.0.51.Final.jar netty-transport-4.1.75.Final.jar netty-transport-classes-epoll-4.1.75.Final.jar netty-transport-classes-kqueue-4.1.75.Final.jar netty-transport-native-epoll-4.1.75.Final-linux-x86_64.jar netty-transport-native-kqueue-4.1.75.Final-osx-x86_64.jar netty-transport-native-unix-common-4.1.75.Final.jar nimbus-jose-jwt-9.15.2.jar oauth2-oidc-sdk-9.22.1.jar postgresql-42.3.3.jar reactive-streams-1.0.3.jar reactor-core-3.4.16.jar reactor-netty-core-1.0.17.jar reactor-netty-http-1.0.17.jar slf4j-api-1.7.36.jar snakeyaml-1.29.jar spring-aop-5.3.18.jar spring-aspects-5.3.18.jar spring-beans-5.3.18.jar spring-boot-2.6.6.jar spring-boot-actuator-2.6.6.jar spring-boot-actuator-autoconfigure-2.6.6.jar spring-boot-autoconfigure-2.6.6.jar spring-boot-jarmode-layertools-2.6.6.jar spring-context-5.3.18.jar spring-core-5.3.18.jar spring-data-commons-2.6.3.jar spring-data-jpa-2.6.3.jar spring-expression-5.3.18.jar spring-jcl-5.3.18.jar spring-jdbc-5.3.18.jar spring-orm-5.3.18.jar spring-tx-5.3.18.jar spring-web-5.3.18.jar spring-webmvc-5.3.18.jar stax2-api-4.2.1.jar thymeleaf-3.0.15.RELEASE.jar thymeleaf-extras-java8time-3.0.4.RELEASE.jar thymeleaf-spring5-3.0.15.RELEASE.jar tomcat-embed-core-9.0.60.jar tomcat-embed-el-9.0.60.jar tomcat-embed-websocket-9.0.60.jar txw2-2.3.6.jar unbescape-1.1.6.RELEASE.jar woodstox-core-6.2.7.jar
⇧ だけのjarが読み込まれている。
とりあえず、今回の『NoSuchMethodError reactor.netty.http.client.httpclient.resolver』に関わってるんじゃなかろうか的なものを調べてみます。
Azure SDK for Javaとは?
This repository is for active development of the Azure SDK for Java. For consumers of the SDK we recommend visiting our public developer docs at https://docs.microsoft.com/java/azure/ or our versioned developer docs at https://azure.github.io/azure-sdk-for-java.
⇧ と、全く説明がなってないのですが、
- Azure SDK for Java ライブラリは、基になる Azure REST API の上に構築されているため、使い慣れた Java のパラダイムからそれらの API を使用できます。 ただし、REST API は、必要に応じていつでも Java コードから直接使用できます。
https://docs.microsoft.com/ja-jp/azure/developer/java/sdk/overview
⇧ ということらしい。
Azure REST APIありきということのようです。
役立ち情報みたいなまとめが以下らしい。
azuresdkartifacts.blob.core.windows.net
で、
azuresdkartifacts.blob.core.windows.net
⇧ 上記のMaven Siteの中のリンクがバグっていて、肝心のそれぞれのライブラリが必要とする依存関係が参照できなかったので、調整したのが以下のURL。2022年7月2日(土)時点の情報。ドキュメントの配置場所が変わったら参照できなくなると思うけど...
https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-ai-anomalydetector/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-data-appconfiguration/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-security-attestation/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-communication-chat/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-communication-common/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-communication-identity/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-communication-phonenumbers/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-communication-sms/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-security-confidentialledger/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-containers-containerregistry/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-core/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-core-amqp/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-core-amqp-experimental/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-core-experimental/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-core-http-netty/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-core-http-okhttp/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-core-serializer-avro-apache/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-core-serializer-json-gson/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-core-serializer-json-jackson/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-core-test/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-core-tracing-opentelemetry/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-cosmos/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-iot-deviceupdate/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-digitaltwins-core/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-messaging-eventgrid/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-messaging-eventhubs/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-messaging-eventhubs-checkpointstore-blob/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-ai-formrecognizer/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-identity/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-security-keyvault-administration/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-security-keyvault-certificates/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-security-keyvault-jca/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-security-keyvault-keys/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-security-keyvault-secrets/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-ai-metricsadvisor/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-mixedreality-authentication/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-iot-modelsrepository/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-monitor-opentelemetry-exporter/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-monitor-query/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-analytics-purview-catalog/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-analytics-purview-scanning/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-quantum-jobs/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-mixedreality-remoterendering/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-data-schemaregistry/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-data-schemaregistry-avro/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-search-documents/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-messaging-servicebus/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-storage-blob/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-storage-blob-batch/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-storage-blob-changefeed/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-storage-blob-cryptography/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-storage-blob-nio/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-storage-common/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-storage-file-datalake/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-storage-file-share/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-storage-internal-avro/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-storage-queue/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-analytics-synapse-accesscontrol/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-analytics-synapse-artifacts/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-analytics-synapse-managedprivateendpoints/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-analytics-synapse-monitoring/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-analytics-synapse-spark/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-data-tables/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-ai-textanalytics/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-ai-documenttranslator/dependencies.html https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/azure-messaging-webpubsub/dependencies.html
で、試しに、Azure Blob StorageのAPI利用に必要な依存関係を確認してみる。
azuresdkartifacts.blob.core.windows.net
最後の更新が、2021-08-30ってのが、まず辛い...
そして、Azure Blob StorageのAPIを動作させるには、以下の依存関係が必要であると。
⇧ Spring Bootが依存関係をカバーしてくれているように見えますと。
Azure SDK for Java の HTTP クライアント
Azure SDK for JavaとHTTPクライアントの説明によると、
Azure SDK for Java は、HttpClient
の抽象化を使用して実装されます。 この抽象化により、複数の HTTP クライアント ライブラリまたはカスタム実装を受け入れるプラグ可能なアーキテクチャが可能になります。 ただし、ほとんどのユーザーの依存関係の管理を簡素化するために、すべての Azure クライアント ライブラリは azure-core-http-netty
に依存しています。 そのため、すべての Azure SDK for Java ライブラリで使用される既定のクライアントは NettyHTTP クライアントです。
https://docs.microsoft.com/ja-jp/azure/developer/java/sdk/http-client-pipeline
Netty が既定の HTTP クライアントですが、SDK には、お使いのプロジェクトに既に存在する依存関係に応じて 3 つのクライアント実装が用意されています。 これらの実装は、次を対象とします。
- Netty
- OkHttp
- JDK 11 で導入された新しい HttpClient
https://docs.microsoft.com/ja-jp/azure/developer/java/sdk/http-client-pipeline
⇧ とあり、デフォルトだと、全てのAzure SDK for Javaについて、Netty HTTPクライアントが利用されてますと。
Azure SDK for Javaは、Nettyありきというか、Netty無いと動かんってことですかね。
Nettyとは
公式のドキュメントによりますと、
Netty is a NIO client server framework which enables quick and easy development of network applications such as protocol servers and clients. It greatly simplifies and streamlines network programming such as TCP and UDP socket server.
⇧NIOというのは、「Non Blocking I/O」の略らしいんですが、
⇧ 上記サイト様の説明がイメージしやすいかと。
で、
⇧ サラッと、Windowsが除け者にされとるんだが...
I/Oの多重化って、OSに依存するんかな?
まぁ、NettyがI/Oの多重化を実現してないんであれば、関係ないですが、もしNettyがI/Oの多重化を実現しているんであれば、Windows環境でも機能するのは、「Java仮想マシン(JVM:Java Virtual Machine)」のおかげとかになるんかな?
NettyのGitHubで公開している情報によると、
Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.
⇧ 非同期イベント駆動ネットワークアプリケーションフレームワークということらしい。
Reactor Nettyとは
Reactor NettyのGitHubで公開している情報によると、
Reactor Netty
offers non-blocking and backpressure-ready TCP
/HTTP
/UDP
/QUIC
clients & servers based on Netty
framework.
⇧ とあり、Nettyをベースにしているらしい。
Reactorはと言うと、
Reactor is a fourth-generation reactive library, based on the Reactive Streams
specification, for building non-blocking applications on the JVM
⇧「Java仮想マシン(JVM:Java Virtual Machine)」上で動作するアプリケーションがターゲットらしい。
Spring BootとNetty
ドキュメントによると、
WebClient
クラスを使用するには spring-boot-starter-reactor-netty
が必要なので、別の HTTP サーバーを含める必要がある場合でも、Netty への依存関係を維持する必要があります。
https://spring.pleiades.io/spring-boot/docs/current/reference/html/howto.html#howto.webserver
⇧ WebClientを利用しないのであれば、特に気にする必要はないらしいのですが、WebClientを使ってるかどうかの確認の術が不明なんだが...
で、結局、やっぱりSpring Bootが悪いと思う
まぁ、結局のところ、悪いのはSpring Bootになるんだと思う。
というのも、まず、Spring Bootのバージョンによるのかもしれないですが、
⇧ Netty系のライブラリと、
⇧ Reactor Netty系のライブラリが暗黙的に追加されてるという...
ただ、
⇧ Spring Bootのbuild.gradleを見た限り、上記の依存関係がすべて読み込まれるようには見えない気がするんよね...
つまり、Spring Bootが依存関係をどこまで面倒見てくれているのかが非常に分かり辛い...
そして、問題が起こってるSpring Bootのバージョンが低いせいなのかが分からんのだけど、暗黙的に読み込まれてるライブラリで動かんというね...
毎度モヤモヤ感が半端ない...
今回はこのへんで。