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

推薦する

Windows 10 に Linux サブシステムをインストールする 2 つの方法 (画像とテキスト付き)

Windows 10 は Linux サブシステムをサポートするようになり、面倒なデュアル システ...

MySQL をデプロイするときに発生する「テーブル mysql.plugin が存在しません」という問題の解決方法

今日、MySQL の無料インストール版をデプロイしたところ、テーブル 'mysql.plug...

60件のページング事例と優れた実践例を推奨

<br />構造と階層により複雑さが軽減され、読みやすさが向上します。記事やサイトが整理...

NestJsはMongooseを使用してMongoDBを操作する

最近、NestJs フレームワークを学び始めました。学習コストは他のフレームワークよりもはるかに高く...

Vue+js 矢印をクリックして画像を切り替える

この記事の例では、矢印をクリックして画像を切り替えるVue + jsの具体的なコードを共有しています...

JavaScript でプロパティハイジャックを実装する方法 defineProperty

目次序文記述子getとsetの詳細な説明オブジェクトの属性の乗っ取りオブジェクトのすべてのプロパティ...

MySQL InnoDBエンジンのインデックスとストレージ構造の詳細な説明

序文Oracle や SQL Server などのデータベースには、ストレージ エンジンが 1 つだ...

HTML テーブルの空白セル補完を実装する方法

私が初めて Web 開発を独学で学んだ頃は、いわゆる DIV/CSS レイアウトはなく、テーブル レ...

Vueは州、都市、地区のカスケード選択を実現します

最近、省、市、地区のカスケード選択効果を実装する必要があります。省、市、地区のデータはすべてローカル...

WeChatアプレットの入力レベルとテキストエリアレベルの浸透率が高すぎる問題の解決策

WeChat ミニプログラムのネイティブ コンポーネントであるカメラ、キャンバス、入力 (フォーカス...

ウェブデザインのグラフィック構成と組版機能の紹介

すべてには基礎が必要です。家を建てるには基礎が必要です。方程式を解くには、まず九九を覚える必要があり...

Springboot+Vue-Cropperでアバターの切り取りとアップロードの効果を実現

アバターをアップロードするにはVue-Cropperコンポーネントを使用します。参考までに具体的な内...

Vueシングルページアプリケーションの事前レンダリング方法の例

目次序文vue-cli 2.0 バージョンvue-cli 3.0 バージョン要約する序文vue-cl...

Linux ネットワーク システムの紹介

目次ネットワーク情報ホスト名を変更するDNSドメイン名解決ネットワーク関連コマンドファイアウォール暗...