今日、私はグループの友人に出くわし、オンラインプログラムに異なるバージョンの複数のNettyパッケージがあるようだと尋ねましたが、どれが一番下にロードされているかを確認するにはどうすればよいですか? |
見方について話す前に、まずそれについて話しましょう。プロジェクトに複数のバージョンのJarパッケージがあることに気づき始めたら、それはすべて次の例外によるものです。
- 1. java.lang.NoSuchMethodException:他のバージョンのjarがロードされているため、コードでメソッドが呼び出されましたが、このバージョンにはこのメソッドがありません。
- 2. java.lang.NoClassDefFoundError:コンパイル時には問題ありませんが、実行時にはjarバージョンがロードされているため、そのようなクラスはありません。
- 3. java.lang.ClassNotFoundException:クラスが動的にロードされる場合、ロードされるjarが正しいバージョンではないため、クラスが見つかりません。
ローカルでokを実行しても、サーバーでこれらのエラーが見つかった場合は、jarの競合である可能性が高いことを認識しておく必要があります(同じ依存関係には複数のバージョンがあります)。この問題は、多くの場合、次のように現れます。複数のインスタンスをデプロイする場合、一部のインスタンスは適切であり、他のインスタンスは適切ではありません。
ロードされたクラスとメソッドを表示する
以前に分析した異常の種類に応じて、現在の負荷の問題を確認するために手術現場に行くことができます。
ここでは、AliのオープンソースArthasツールを使用できます。初めて使用する場合は、インストールしてから次のように実行してください。
curl -O https://arthas.aliyun.com/arthas-boot.jar java -jar arthas-boot.jar
実行後、次のような現在実行中のJavaアプリケーションを出力します。
[INFO] arthas-bootバージョン:3.4.6 [INFO]プロセス40611はすでにポート3658を使用しています [INFO]プロセス40611はすでにポート8563を使用しています [INFO]既存のJavaプロセスが見つかりました。いずれかを選択し、プロセスのシリアル番号を入力してください。 :1。次にEnterキーを押します。 * [1]:40611 Chapter4-3-0.0.1-SNAPSHOT.jar [2]:37786
番号を入力して、表示するJavaアプリケーションを選択します。たとえば、ここを選択します:1、chapter4-3-0.0.1-SNAPSHOT.jarと入力します。
ここに2つの重要なコマンドがあります:
最初のコマンド:scコマンド、jarパッケージの下に競合する可能性のある対応するクラスがあるかどうかを確認しましょう。パッケージのバージョンによっては、クラスが異なり、すぐに区別できます。
たとえば、次のコマンドを使用して、com.didispaceパッケージに含まれるクラスを確認できます。
[arthas @ 40611] $ sccom.didispace。* com.didispace.chapter43.Chapter43Application com.didispace.chapter43.Chapter43Application $$ EnhancerBySpringCGLIB $$ 8b82b194 com.didispace.chapter43.UploadController Affect(row-cnt:3)コスト6 MS。
2番目のコマンド:smコマンド。特定のクラスが持つメソッドを確認します。バージョンの違いは、特定のメソッドが削除されていることです。現時点では、このコマンドを使用して確認できます。
たとえば、次のコマンドを使用して、com.didispace.chapter43.UploadControllerクラスで使用できるメソッドを確認しましょう。
[arthas @ 40611] $ sm com.didispace.chapter43.UploadController com.didispace.chapter43.UploadController()V com.didispace.chapter43.UploadController create(Lorg / springframework / web / multipart / MultipartFile;)Ljava / lang / String; com.didispace.chapter43.UploadController uploadPage()Ljava / lang / String; 5ミリ秒でAffect(row-cnt:3)コスト。
競合を見つけて解決する
読み込みエラーであることを確認した後、競合を解決する必要があります。したがって、競合を解決するために私たちがしなければならないことは、競合がどこにあるのか、そして何を削除または強制したいのかを見つけることです。
バージョンの競合を見つける方法:Mavenコマンドを使用します:mvn -Udependency:tree-Dverbose。
コマンドが実行されると、すべての依存関係がツリー形式でコンソールに一覧表示され、競合するパッケージが検索されて、どの依存関係が取り込まれるかが確認されます(IDEAで検索すると強調表示され、簡単に見つけることができます)。
[INFO] com.didispace:chapter4-3:jar:0.0.1-SNAPSHOT [INFO] + -org.springframework.boot:spring-boot-starter-web:jar:2.4.1:compile [INFO] | + -org.springframework.boot:spring-boot-starter:jar:2.4.1:compile [INFO] | | + -org.springframework.boot:spring-boot:jar:2.4.1:compile [INFO] | | + -org.springframework.boot:spring-boot-autoconfigure:jar:2.4.1:compile [INFO] | | + -org.springframework.boot:spring-boot-starter-logging:jar:2.4.1:compile [INFO] | | | + -ch.qos.logback:logback-classic:jar:1.2.3:compile [INFO] | | | | \ -ch.qos.logback:logback-core:jar:1.2.3:compile [INFO] | | | \ -org.slf4j:jul-to-slf4j:jar:1.7.30:compile [INFO] | | | + -org.apache.logging.log4j:log4j-to-slf4j:jar:2.13.3:compile [情報] | | | | \ -org.apache.logging.log4j:log4j-api:jar:2.13.3:compile [INFO] | | + -com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.11.3:compile [情報] | | + -jakarta.annotation:jakarta.annotation-api:jar:1.3.5:compile [INFO] | | \ -org.yaml:snakeyaml:jar:1.27:compile [INFO] | + -org.springframework.boot:spring-boot-starter-json:jar:2.4.1:compile [INFO] | | + -com.fasterxml.jackson.core:jackson-databind:jar:2.11.3:compile [INFO] | | | + -com.fasterxml.jackson.core:jackson-annotations:jar:2.11.3:compile [INFO] | | | \ -com.fasterxml.jackson.core:jackson-core:jar:2.11.3:compile [INFO] | | + -com.fasterxml.jackson.datatype:jackson-datatype-jdk8:jar:2.11.3:compile [INFO] | | \ -com.fasterxml.jackson.module:jackson-module-parameter-names:jar:2.11.3:compile [INFO] | + -org.springframework.boot:spring-boot-starter-tomcat:jar:2.4.1:compile [INFO] | | + -org.apache.tomcat.embed:tomcat-embed-core:jar:9.0.41:compile [INFO] | | + -org.glassfish:jakarta.el:jar:3.0.3:compile [INFO] | | \ -org.apache.tomcat.embed:tomcat-embed-websocket:jar:9.0.41:compile [INFO] | + -org.springframework:spring-web:jar:5.3.2:compile [INFO] | | \ -org.springframework:spring-beans:jar:5.3.2:compile [INFO] | \ -org.springframework:spring-webmvc:jar:5.3.2:compile [INFO] | + -org.springframework:spring-aop:jar:5.3.2:compile [INFO] | + -org.springframework:spring-context:jar:5.3.2:compile [INFO] | \ -org.springframework:spring-expression:jar:5.3.2:compile [INFO] + -org.springframework.boot:spring-boot-starter-thymeleaf:jar:2.4.1:compile [INFO] | + -org.thymeleaf:thymeleaf-spring5:jar:3.0.11.RELEASE:compile [情報] | | + -org.thymeleaf:thymeleaf:jar:3.0.11.RELEASE:compile [INFO] | | | + -org.attoparser:attoparser:jar:2.0.5.RELEASE:compile
バージョンの競合を解決するには、主に2つの方法があります。
- 1.上記のコマンドで不要なバージョンを見つけたら、除外を使用して、インポートされた依存関係から不要なバージョンを除外します
- 2. pom.xmlで使用するバージョンを指定する必要があります。これにより、これが最高の優先度を持ち、他のバージョンが取り込むバージョンが導入されなくなります。