Idea で Tomcat のソースコードデバッグを開始し、デバッグのために Tomcat に入る方法

Idea で Tomcat のソースコードデバッグを開始し、デバッグのために Tomcat に入る方法

idea 開発ツールを使用してコードをデバッグする場合、Java Web プロジェクトで、Web コンテナーとして Tomcat を使用し、ブレークポイント デバッグ トレースを実行すると、org.apache.catalina パッケージにトレースするときに、入ることができません。これは、idea で実行されている Tomcat がプラグインを通じて統合されており、Tomcat 内の lib パッケージがプロジェクトの依存パスにないため、トレースできないためです。

まず、自分のプロジェクトで Tomcat からコールバックされるインターフェース実装クラスにブレークポイントをマークし、idea を通じて Web プロジェクトを起動します。図に示すブレークポイント情報が表示されると、ブレークポイントの位置は Tomcat からコールバックされるインターフェースクラスをマークしているため、コールスタックは Tomcat の内部コードです。ただし、この時点では org.apache.catalina パッケージの下のクラス名をダブルクリックしても応答がありません。これは、Tomcat に対応する依存ファイルをクラスパスに追加していないためです。

依存関係の追加

<依存関係>
 <グループ ID>org.apache.tomcat</グループ ID>
 <artifactId>tomcat-catalina</artifactId>
 <バージョン>8.5.55</バージョン>
 <scope>提供</scope>
</依存関係>

tomcatのlibディレクトリにあるjarファイルは実行時に使用されるため、ここでのスコープは提供されたメソッドを使用します。

これでTomcatソースコードのデバッグに入ることができます

tomcat の起動ログはどのように印刷されますか?

2020 年 6 月 3 日 10:31:30.929 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server。サーバー バージョン: Apache Tomcat/8.5.55
2020 年 6 月 3 日 10:31:30.938 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log サーバービルド: 2020 年 5 月 5 日 22:10:54 UTC
2020 年 6 月 3 日 10:31:30.938 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log サーバーのバージョン番号 (: 8.5.55.0
2020 年 6 月 3 日 10:31:30.938 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log オペレーティング システム名: Windows 10
2020 年 6 月 3 日 10:31:30.938 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS.Version: 10.0
2020 年 6 月 3 日 10:31:30.938 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log アーキテクチャ: amd64
2020 年 6 月 3 日 10:31:30.939 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java 環境変数: C:\Program Files\Java\jdk1.8.0_212\jre
2020 年 6 月 3 日 10:31:30.939 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java 仮想マシンのバージョン: 1.8.0_212-b10
2020 年 6 月 3 日 10:31:30.939 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM.Vendor: Oracle Corporation
2020 年 6 月 3 日 10:31:30.939 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE: C:\Users\Administrator\.IntelliJIdea2018.3\system\tomcat\Unnamed_spring-shiro-training
2020 年 6 月 3 日 10:31:30.939 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME: D:\tomcat8.5.55\apache-tomcat-8.5.55

VersionLoggerListenerログを見つけると、次の情報が表示されます。

プライベートvoid log() {
 log.info(sm.getString("versionLoggerListener.serverInfo.server.version",
  ServerInfo.getServerInfo());
 log.info(sm.getString("versionLoggerListener.serverInfo.server.built",
  ServerInfo.getServerBuilt());
 log.info(sm.getString("versionLoggerListener.serverInfo.server.number",
  ServerInfo.getServerNumber()));
 log.info(sm.getString("versionLoggerListener.os.name",
  System.getProperty("os.name"));
 log.info(sm.getString("versionLoggerListener.os.version",
  System.getProperty("os.version"));
 log.info(sm.getString("versionLoggerListener.os.arch",
  System.getProperty("os.arch"));
 log.info(sm.getString("versionLoggerListener.java.home",
  System.getProperty("java.home"));
 log.info(sm.getString("versionLoggerListener.vm.version",
  System.getProperty("java.runtime.version"));
 log.info(sm.getString("versionLoggerListener.vm.vendor",
  System.getProperty("java.vm.vendor"));
 log.info(sm.getString("versionLoggerListener.catalina.base",
  System.getProperty("catalina.base"));
 log.info(sm.getString("versionLoggerListener.catalina.home",
  System.getProperty("catalina.home"));


 if (logArgs) {
 リスト<String> args = ManagementFactory.getRuntimeMXBean().getInputArguments();
 for (文字列引数:引数) {
  log.info(sm.getString("versionLoggerListener.arg", arg));
 }
 }


 ログ環境の場合
 SortedMap<String, String> sortedMap = new TreeMap<>(System.getenv());
 Map.Entry<String, String> e の場合: sortedMap.entrySet()) {
  log.info(sm.getString("versionLoggerListener.env", e.getKey(), e.getValue()));
 }
 }


 (ログプロパティ)の場合{
 SortedMap<String, String> sortedMap = new TreeMap<>();
 Map.Entry<Object, Object> e の場合: System.getProperties().entrySet()) {
  sortedMap.put(String.valueOf(e.getKey()), String.valueOf(e.getValue()));
 }
 Map.Entry<String, String> e の場合: sortedMap.entrySet()) {
  log.info(sm.getString("versionLoggerListener.prop", e.getKey(), e.getValue()));
 }
 }
}

検出はキーと値のペアを通じて取得され、その後グローバル文字列検索を通じて発見される。

ここに画像の説明を挿入

しかし、一致しているのは英語なので、中国語はどのように入力すればよいのでしょうか?

最終的にデバッグを通じて、私はこれを見つけました

ここに画像の説明を挿入

上記と同様に、デバッグ中に、tocmatによって開始されたものがまだかなりたくさんあることがわかりました。次のものを見てください。

ここに画像の説明を挿入

アイデアTomcat起動後のデータ

2020 年 6 月 3 日 10:31:30.939 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log コマンドライン引数: -Djava.util.logging.config.file=C:\Users\Administrator\.IntelliJIdea2018.3\system\tomcat\Unnamed_spring-shiro-training\conf\logging.properties
2020 年 6 月 3 日 10:31:30.940 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log コマンドライン引数: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
2020 年 6 月 3 日 10:31:30.940 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log コマンドライン引数: -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:52290,suspend=y,server=n
2020 年 6 月 3 日 10:31:30.940 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log コマンドライン引数: -javaagent:C:\Users\Administrator\.IntelliJIdea2018.3\system\captureAgent\debugger-agent.jar
2020 年 6 月 3 日 10:31:30.940 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log コマンドライン引数: -Dfile.encoding=UTF-8
2020 年 6 月 3 日 10:31:30.940 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log コマンドライン引数: -Dcom.sun.management.jmxremote=
2020 年 6 月 3 日 10:31:30.940 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log コマンドライン引数: -Dcom.sun.management.jmxremote.port=1099
2020 年 6 月 3 日 10:31:30.940 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log コマンドライン引数: -Dcom.sun.management.jmxremote.ssl=false
2020 年 6 月 3 日 10:31:30.940 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log コマンドライン引数: -Dcom.sun.management.jmxremote.password.file=C:\Users\Administrator\.IntelliJIdea2018.3\system\tomcat\Unnamed_spring-shiro-training\jmxremote.password
2020 年 6 月 3 日 10:31:30.940 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log コマンドライン引数: -Dcom.sun.management.jmxremote.access.file=C:\Users\Administrator\.IntelliJIdea2018.3\system\tomcat\Unnamed_spring-shiro-training\jmxremote.access
2020 年 6 月 3 日 10:31:30.940 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log コマンドライン引数: -Djava.rmi.server.hostname=127.0.0.1
2020 年 6 月 3 日 10:31:30.940 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log コマンドライン引数: -Djdk.tls.ephemeralDHKeySize=2048
2020 年 6 月 3 日 10:31:30.940 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log コマンドライン引数: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources
2020 年 6 月 3 日 10:31:30.941 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log コマンドライン引数: -Dignore.endorsed.dirs=
2020 年 6 月 3 日 10:31:30.941 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log コマンドライン引数: -Dcatalina.base=C:\Users\Administrator\.IntelliJIdea2018.3\system\tomcat\Unnamed_spring-shiro-training
2020 年 6 月 3 日 10:31:30.941 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log コマンドライン引数: -Dcatalina.home=D:\tomcat8.5.55\apache-tomcat-8.5.55
2020 年 6 月 3 日 10:31:30.941 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log コマンドライン引数: -Djava.io.tmpdir=D:\tomcat8.5.55\apache-tomcat-8.5.55\temp

上記は基本的な環境設定であり、これで Tomcat サービスにリンクする準備が整いました。

2020 年 6 月 3 日 10:31:30.941 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR バージョン [1.7.0] を使用して APR ベースの Apache Tomcat ネイティブ ライブラリ [1.2.24] をロードしました。
2020 年 6 月 3 日 10:31:30.941 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR 機能: IPv6[true]、sendfile[true]、accept フィルター[false]、random[true]。
2020 年 6 月 3 日 10:31:30.941 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR/OpenSSL 構成: useAprConnector [false]、useOpenSSL [true]
2020 年 6 月 3 日 10:31:30.944 INFO [main] org.apache.catalina.core.AprLifecycleListener.initializeSSL OpenSSL が正常に初期化されました [OpenSSL 1.1.1g 2020 年 4 月 21 日]
2020 年 6 月 3 日 10:31:31.032 INFO [main] org.apache.coyote.AbstractProtocol.init プロトコル ハンドラー ["http-nio-8080"] を初期化しています
2020 年 6 月 3 日 10:31:31.046 INFO [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector サーブレットの書き込み/読み取りに共有セレクターを使用する
2020 年 6 月 3 日 10:31:31.055 INFO [main] org.apache.catalina.startup.Catalina.load 初期化が 175489 ミリ秒で処理されました
2020 年 6 月 3 日 10:31:31.080 INFO [main] org.apache.catalina.core.StandardService.startInternal サービスを開始しています [Catalina]
2020 年 6 月 3 日 10:31:31.080 INFO [main] org.apache.catalina.core.StandardEngine.startInternal サーブレット エンジンを起動しています: Apache Tomcat/8.5.55
2020 年 6 月 3 日 10:31:31.089 INFO [main] org.apache.coyote.AbstractProtocol.start プロトコル ハンドラーを開始しています ["http-nio-8080"]
2020 年 6 月 3 日 10:31:31.102 INFO [main] org.apache.catalina.startup.Catalina.start サーバーの起動に 47 ミリ秒かかりました

トマトのスタートアップは主にカタリナ島にあります

ここに画像の説明を挿入
ここに画像の説明を挿入

それから

ここに画像の説明を挿入

起動する

/**
* 待機してシャットダウンします。
*/
パブリックvoid待機() {

 getServer() を待機します。


}

実際、Tomcat の起動は本質的には単なるソケット サーバーです。

@オーバーライド
パブリックvoid待機() {
 // 負の値 - ポートを待機しない - Tomcat が埋め込まれているか、ポートが気に入らないだけです
 if (ポート == -2) {
 // まだ文書化されていません - 稼働中のアプリを埋め込むためのものです。
 戻る;
 }
 ポート==-1の場合{
 試す {
  現在のスレッドを待機します。
  while(!stopAwait) {
  試す {
   スレッド.スリープ(10000);
  } キャッチ(InterruptedException ex) {
   // 続行してフラグをチェックする
  }
  }
 ついに
  待機スレッド = null;
 }
 戻る;
 }


 // 待機するサーバーソケットを設定する
 試す {
 awaitSocket = 新しい ServerSocket(ポート, 1,
  InetAddress.getByName(アドレス));
 } キャッチ (IOException e) {
 log.error("StandardServer.await: create[" + アドレス
    + ":" + ポート
    + "]: ", e);
 戻る;
 }


 試す {
 現在のスレッドを待機します。


 // 接続と有効なコマンドを待つループ
 while (!stopAwait) {
  サーバーソケット serverSocket = awaitSocket;
  (serverSocket == null)の場合{
  壊す;
  }


  // 次の接続を待つ
  ソケット socket = null;
  StringBuilder コマンド = new StringBuilder();
  試す {
  InputStream ストリーム;
  長い acceptStartTime = System.currentTimeMillis();
  試す {
   socket = serverSocket.accept(); // acceptすると、次のコードが実行されます socket.setSoTimeout(10 * 1000); // 10秒
   ストリーム = socket.getInputStream();
  } catch (SocketTimeoutException ste) {
   // これは決して起こらないはずであるが、バグ56684は、
   // そうです。
   log.warn(sm.getString("standardServer.accept.timeout",
    Long.valueOf(System.currentTimeMillis() - acceptStartTime)), ste);
   続く;
  } キャッチ (AccessControlException ace) {
   log.warn(sm.getString("standardServer.accept.security"), ace);
   続く;
  } キャッチ (IOException e) {
   停止待ちの場合
   // socket.close() により待機が中止されました
   壊す;
   }
   ログエラー(sm.getString("standardServer.accept.error"), e);
   壊す;
  }


  // ソケットから文字セットを読み取ります
  int expected = 1024; // DoS攻撃を避けるためにカットオフ
  while (期待値 < シャットダウン長さ()) {
   if (ランダム == null)
   ランダム = 新しい Random();
   予想 += (random.nextInt() % 1024);
  }
  (期待値 > 0) {
   整数ch = -1;
   試す {
   ch = ストリーム.read();
   } キャッチ (IOException e) {
   log.warn(sm.getString("standardServer.accept.readError"), e);
   ch = -1;
   }
   // 制御文字またはEOF (-1) でループを終了します
   ch < 32 || ch == 127 の場合
   壊す;
   }
   コマンド.append((char) ch);
   期待される - ;
  }
  ついに
  // 作業が終わったのでソケットを閉じます
  試す {
   ソケットが null の場合
   ソケットを閉じます。
   }
  } キャッチ (IOException e) {
   // 無視する
  }
  }


  // コマンド文字列と一致
  ブール値 match = command.toString().equals(shutdown);
  (一致)の場合{
  ログ情報(sm.getString("standardServer.shutdownViaPort"));
  壊す;
  } それ以外
  log.warn(sm.getString("standardServer.invalidShutdownCommand", command.toString()));
 }
 ついに
 サーバーソケット serverSocket = awaitSocket;
 スレッドを待機 = null;
 ソケットを待機 = null;


 // サーバーソケットを閉じて戻ります
 if (serverSocket != null) {
  試す {
  serverSocket.close();
  } キャッチ (IOException e) {
  // 無視する
  }
 }
 }
} 

ここに画像の説明を挿入

tomcatコンテナが起動すると、Springmvcモジュールの内容は次のようになります。

ここに画像の説明を挿入
ここに画像の説明を挿入

Idea で tomcat のソース コードのデバッグを開始し、デバッグのために tomcat に入る方法については、これでこの記事は終わりです。Idea で tomcat のソース コードのデバッグを開始する方法の詳細については、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • アイデアクラスを実装するためのクイックインターフェース生成方法の例
  • IDEA でソース コードをデバッグするためのヒント: 抽象クラスまたはインターフェイスの複数の実装クラスの正しいパスを特定する

<<:  伝説的な VUE 構文シュガーは何をするのでしょうか?

>>:  MySQL インデックスの一般的な問題の概要

推薦する

React Native スキャフォールディングの基本的な使い方の詳細な説明

プロジェクトを構築する対応するパスでコマンドラインを実行します: react-native init...

レム適応の一般的なパッケージ3つについて

序文以前、rem適応についての記事を書きましたが、具体的なパッケージは紹介しませんでした。今日は、よ...

テーブルの追加と削除の操作を実装する js

この記事の例では、テーブルを追加および削除するためのjsの具体的なコードを参考までに共有しています。...

ウェブサイトのパフォーマンス: 画像とCookieの最適化、モバイルアプリケーションの最適化

前のセクションでは、コンテンツ、サーバー、JavaScript、CSS など、Web サイトのパフォ...

DevUI で独自の Angular コンポーネント ライブラリを構築する方法

目次序文コンポーネントライブラリの作成主要な構成の変更ディレクトリレイアウトの調整ライブラリ構築のた...

Vue lazyload 画像遅延読み込み例の詳細な説明

ドキュメント: https://github.com/hilongjw/vue-lazyload 1...

CSS3は遷移を高速化し、遅延させる

1. 速度制御機能を使用して、トランジション効果(加速、減速など)の速度曲線を制御します。速度制御機...

シンプルなカルーセルの最も完全なコード分析を実装するJavaScript(ES6オブジェクト指向)

この記事では、シンプルなカルーセルを実装するためのJavaScriptの具体的なコードを参考までに紹...

mysql のインデックスと FROM_UNIXTIME に関する問題

ゼロ、背景今週の木曜日にたくさんのアラートを受け取りました。DBA に確認を依頼したところ、遅いクエ...

Node.js における path.join() の利点の分析

文字列連結ではなく path.join() メソッドを使用する必要があるのはなぜか疑問に思うかもしれ...

HTML CSS JS はタブページのサンプルコードを実装します

コードをコピーコードは次のとおりです。 <html xmlns="">...

Linux における SUID、SGID、SBIT の素晴らしい使い方の詳細な説明

序文Linux のファイル権限管理はとにかく素晴らしいです。SUID、SGID、SBIT の機能を確...

HTML での位置の使用に関する簡単な紹介

昨日 HTML を少し学んだばかりで、JD.com の検索バーを作るのが待ちきれませんでした。 作っ...

Vue で Google サードパーティ ログインを実装するためのサンプル コード

目次1. 開発者プラットフォームの構成問題を解決する1. 開発者プラットフォームの構成1. 開発者プ...

Docker で hyperf を開発する完全な使用例の詳細な説明

ハイパーフ公式サイトHyperf 公式ドキュメントのインストール1. Dockerの使用docker...