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 インデックスの一般的な問題の概要

推薦する

nginx で正規表現を使用してワイルドカードドメイン名を自動的に一致させる方法

Nginxは正規表現を使用して、ワイルドカードドメイン名をディレクトリに自動的に一致させます。 Ng...

Vueはズームイン、ズームアウト、ドラッグ機能を実装しています

この記事では、参考までに、ズームインとズームアウトのドラッグ機能を実現するためのVueの具体的なコー...

Vue3 ドラッグ可能な左パネルと右パネルの分割コンポーネントの実装

目次コンポーネントの分解左パネル右パネル入力パラメータの分解小道具スロット具体的な実装ドラッグする方...

ベンダー プレフィックス: ブラウザ エンジン プレフィックスが必要なのはなぜですか?

ベンダープレフィックスとは何ですか?ベンダー プレフィックス - ブラウザー エンジン プレフィック...

MySQLデータベースイベントスケジュール実行タスクの詳細な説明

1. 背景プロジェクトの業務が進むにつれて、データベース テーブルの数がどんどん大きくなり、ハードデ...

JS 関数のアンチシェイクと関数スロットリングを理解する方法

目次概要1. 関数デバウンス2. 機能スロットリング(スロットル)概要関数アンチシェイクと関数スロッ...

MySQL のグループ分けの例

mysql のような php switch case ステートメント。 xxフィールドを選択、ケース...

要素複数フォーム検証の実装

プロジェクトでは、フォーム テストが頻繁に発生します。単一のフォーム テストについては、詳細な紹介が...

Vue ページをリフレッシュするために provide と injection を適用する

目次方法1: 関数を直接呼び出す方法2: provide / inject (静的更新) を使用する...

CSS3 @mediaの基本的な使い方のまとめ

//文法: @media mediatype and | not | only (メディア機能) ...

トップに戻るボタンの例の JavaScript 実装

この記事では、トップに戻るボタンを実装するためのJavaScriptの具体的なコードを参考までに紹介...

CSS3はアニメーション効果を実現するためにvar()とcalc()関数を使用する。

ナレッジポイントをプレビューします。アニメーションフレーム背景グラデーションvar() と calc...

MySQL の厄介な Aborted 警告をケーススタディで分析する

この記事では主に、MySQL の Aborted アラームに関する関連コンテンツを紹介し、参考と学習...

CSS XTHML の記述標準とよくある問題の概要 (ページ最適化)

プロジェクトドキュメントディレクトリDiv+CSS 命名規則 - 4 - Div+css 命名規則 ...

JS+AJAX は、州、市、地区のドロップダウン リストのリンクを実現します。

この記事では、州、市、地区のドロップダウンリストのリンクを実現するためのJS + AJAXの具体的な...