Tomcat内のlibディレクトリからjarファイルがロードされる順序を説明できる人はいますか?アルファベット順ですか?無作為に?または他の注文?
それはすべて TomcatのClassLoading HOW-TO で説明されています。必ずしもアルファベット順ではありません。その動作を観察した場合、Webアプリをサーバー間で移植可能にする場合は、絶対に信頼しないでください。たとえば、Tomcat 6は「偶然」注文しますが、Tomcat 8は注文しません。
要約すると、読み込み順序は次のとおりです。
JRE/lib
、次にserver.loader
)WEB-INF/classes
、次にWEB-INF/lib
)common.loader
、次にTomcat/lib
)shared.loader
)JAR Xがロードされることを保証したい場合after JAR Yの場合、上記のリストにlaterが現れる場所の1つにJAR Xを配置する必要があります。 。
ただし、例外があります Tomcat docs
最後に、Webアプリケーションクラスローダーは、Tomcatによって実装される仕様(サーブレット、JSP、EL、WebSocket)のJavaEE APIクラスの最初に常に委任します。 Tomcatの他のすべてのクラスローダーは、通常の委任パターンに従います。
つまり、webappにJavaEEクラス(javax.*
)、Tomcatは無視します。
ローダーごとに、クラスはインポート/実行する必要があり、まだロードされていない場合は常にJVMによって順番にロードされます。
実際、それはisアルファベット順です! (特定のディレクトリ内、たとえば元の投稿者が言及している「lib」ディレクトリ内)
具体的には、Tomcat 6のソースをクラスFileDirContext
で見ると、メソッドlist()
は、見つかったjarのファイル名の配列でArrays.sort()
を呼び出します。
私もこれを手動でテストしました。 HelloWorld.getGreeting()
を呼び出すJSPでwarを作成し、わずかに異なるバージョンのHelloWorld
を含む2つのほぼ同一のjarをWEB-INF/libディレクトリに配置します。 1つは「こんにちは、世界」、もう1つは「さようなら、残酷な世界」と言います。
「Hello、world」バージョンにa.jar、「goodbye」バージョンにb.jarという名前を付け、Tomcatを再起動すると、「Hello」テキストが表示されます。 jarに別の方法で名前を付けてTomcatを再起動すると、「Goodbye」テキストが表示されます。
私が判断できた限り、この動作は文書化されておらず、指定されていないため、これに依存すべきではありません。しかし、今のところはアルファベット順になっています。
WEb-INF/libフォルダーにロードされたjarの順序。
Tomcat 5-7の場合、順序はアルファベット順です。ソートを使用します。
Tomcat 8の場合、基礎となるファイルシステムによってランダムに決定されます。
BalusCの回答に完全に同意します。追加する唯一のポイントは、それぞれのクラスローダーからJARをロードするときにアルファベット順をチェックすることです。
Webアプリケーションに「XSSFWorkbook」をロードしてExcelシートからデータを読み取る状況があり、2つのJARS「poi-ooxml-3.9.jar」と「org.Eclipse.birt.runtime_4.3.1.v20130918-1142.jar」がありました同じクラス名とパッケージ構造を持つ。私は単に後者を差し戻したので、アルファベット順で以前のものの隣になり、それは私のためにトリックをしました。同じものを共有したかっただけです。
幸運を
WebSphere環境では、異なるマシンが異なる順序でjarをロードします。したがって、私はuser2193008に同意します。本番環境でクラスローダーの問題が発生し、同じコードが下位環境で正常に機能します。 lib内の重複するjarを削除することで問題を修正しました。たとえば、spring jarにはspring_v1.jarとspring_v2.jarの2つのバージョンがあります。