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

推薦する

MySQL の一般的な日付比較および計算関数

MySql での時間比較の実装unix_timestamp() unix_timestamp 関数は...

JS ES 新機能テンプレート文字列

目次1. テンプレート文字列とは何ですか? 2. 複数行のテンプレート文字列2.1 式付きテンプレー...

Ubuntu 16.04 で MySQL マスター スレーブ同期を設定する方法

準備1. マスターとスレーブのデータベースのバージョンは一致している必要があります2. マスターデー...

読み取り専用と無効の微妙な違いの詳細な説明

「読み取り専用」と「無効」はどちらも、ユーザーがフォーム フィールドの内容を変更できないようにします...

Tomcat の構成と最適化ソリューションの詳細な説明

サービス.xml Server.xml 構成ファイルは、コンテナー全体を構成するために使用されます。...

JavaScriptのURLオブジェクトとは何かについて話しましょう

目次概要ハッシュプロパティホストプロパティホスト名属性Href属性起源のプロパティユーザー名とパスワ...

Docker を使用した nGrinder パフォーマンス テスト プラットフォームの導入プロセスの分析

nGrinderとは何ですか? nGrinder は、スクリプトの作成、テストの実行、監視、結果レポ...

CSSとJSでロマンチックな流星群アニメーションを実現

1. レンダリング 2. ソースコードhtml < 本文 > < div クラス ...

Linux システムでキャッシュをクリアする方法の概要

1) キャッシュメカニズムの紹介Linux システムでは、ファイルシステムのパフォーマンスを向上させ...

テキストエリアの disabled 属性と readonly 属性の具体的な使用法

障害者の定義と使用法disabled 属性はブール属性です。 disabled 属性は、テキスト領域...

MySQL 最適化チュートリアル: 大規模なページングクエリ

目次背景制限の最適化最適化方法1. カバーインデックスを使用する2. サブクエリの最適化3. 遅延連...

SQLでEXPLAINコマンドを使用する方法

日常業務では、実行に時間のかかる SQL ステートメントを記録するために、スロー クエリを実行するこ...

CentOS 7 ブートカーネルの切り替えとブートモードの切り替えの説明

Centos7 スイッチブートカーネル注: 必要に応じて、最初にyum update -yを実行して...

数ステップでサイバーパンク2077風の視覚効果を実現するCSS

背景記事を始める前に、賽博朋克とは何か、賽博朋克2077とは何かを簡単に理解しましょう。サイバーパン...

実用的な MySQL + PostgreSQL バッチ挿入更新 insertOrUpdate

目次1. 百度百科事典1. MySQL 2. PostgreSQL 3. MySQL に対する Po...