私たちはその理由を診断し、JAR地獄で生き残ります。私たちは硫黄を吸わず、ボイラーで沸騰しません

jvmで実行されている大規模なプロジェクトでは、プロジェクトの依存関係を更新しても、アプリケーションが動作せず、起動さえしないように思われます。 アプリケーションのクラスパス内のライブラリの順序を変更した他のイベントにより、同じことが可能です。







この現象の原因についての叙情的な余談は、すべてがとてつもなく単純です。 jvmでは、すぐにジグソープロジェクトを実装する前に、1つのjvmで、異なるjarファイルから一致する名前パック+クラス(完全修飾名)を持つ同じクラスの複数の異なるバージョンを同時にロードすることはできませんでした。 J2EEクラスローダー、自己記述型クラスローダーまたはその構成、OSGIコンテナーがありましたが、これは別の出版物とまったく異なる世界のトピックです...その結果、これらのクラスの1つだけがロードされ、すべての結果に必要なクラスではありませんでした。



そのため、何かが発生した場合、アプリケーションは、NoSuchMethodError / ClassNotFoundExceptionの突風を注いだり、プロジェクトのソースコードを1つも変更せずに奇妙な動作を開始したりします。 ローダーとリソースの重複クラスに関するレポートは、 jHadesライブラリを使用して実行できます



アプリケーションコードを変更できる場合は、 org.jhades:jhades:1.0.4アーティファクトとMavenに応じたコードスニペットを追加するだけです。

new org.jhades.JHades() .dumpClassloaderInfo() .printClasspath() .overlappingJarsReport() .multipleClassVersionsReport();
      
      







それをアプリケーションのアセンブリに含めることが困難な場合、または変更管理要件がそのような変更を禁止する場合、それは不運です。 この場合、アスペクト指向プログラミングは再び急いで助けになります。



この例では、 hawt.io / h2jdbcロギング 、およびCRaSH-sshに関する記事のように、テストプログラムはSonarQubeのままです。 hawt.io/h2に関する出版物で、ソナーと仮想マシンエージェントのインストールと構成の詳細を読むことができます。



アプリケーションの場合、jvmの起動時に2つの追加パラメーターのみを渡す必要があります。ファイル:classpath.xml



Classpath.xml構成の内容:



 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <configuration> <aspects> <name>com.github.igorsuhorukov.JarhellInfo</name> <type>BEFORE</type> <pointcut>execution(* org.sonar.server.app.WebServer.main(..))</pointcut> <artifacts> <artifact>org.jodd:jodd:3.2</artifact> <classRefs> <variable>ClassLoaderUtil</variable> <className>jodd.util.ClassLoaderUtil</className> </classRefs> </artifacts> <process> <expression> libs = com.github.smreed.dropship.MavenClassLoader.forMavenCoordinates("org.jhades:jhades:1.0.4").getURLs(); java.net.URLClassLoader systemClassLoader = java.lang.ClassLoader.getSystemClassLoader(); for(lib: libs){ ClassLoaderUtil.addFileToClassPath(lib.getFile(), systemClassLoader); } new org.jhades.JHades() .dumpClassloaderInfo() .printClasspath() .overlappingJarsReport() .multipleClassVersionsReport(); </expression></process> </aspects> </configuration>
      
      





プログラムでは、ポイントカットをプログラム内の対応するレポート生成ポイントに変更する必要があります。



私の場合、レポートの一部を提供します。



報告書
>> jHades-重複するjarのクラスパスをスキャンする:

...

ファイル:/home/igor/dev/projects/sonar-demo/sonarqube-5.1.2/lib/server/xml-apis-1.4.01.jarは次と重複します

ファイル:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rt.jar-重複するクラスの合計:342-異なるクラスローダー。



ファイル:/home/igor/dev/projects/sonar-demo/sonarqube-5.1.2/lib/server/aspectj-scripting-1.0-agent.jarは次と重複します

ファイル:/home/igor/dev/projects/sonar-demo/sonarqube-5.1.2/lib/server/plexus-classworlds-2.5.1.jar-重複するクラスの合計:37-同じクラスローダー! これはエラーです!



ファイル:/home/igor/dev/projects/sonar-demo/sonarqube-5.1.2/lib/server/xml-apis-1.4.01.jarは次と重複します

ファイル:/home/igor/dev/projects/sonar-demo/sonarqube-5.1.2/lib/server/stax-api-1.0-2.jar-重複するクラスの合計:34-同じクラスローダー! これはエラーです!



ファイル:/home/igor/dev/projects/sonar-demo/sonarqube-5.1.2/lib/server/stax-api-1.0-2.jarは次と重複します

ファイル:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rt.jar-重複するクラスの合計:34-異なるクラスローダー。



ファイル:/home/igor/dev/projects/sonar-demo/sonarqube-5.1.2/lib/server/commons-collections-3.2.1.jarは次と重複します

ファイル:/home/igor/dev/projects/sonar-demo/sonarqube-5.1.2/lib/server/commons-beanutils-1.8.3.jar-重複するクラスの合計:10-同じクラスローダー! これはエラーです!



ファイル:/home/igor/dev/projects/sonar-demo/sonarqube-5.1.2/lib/server/tomcat-embed-core-8.0.18.jarは次と重複します

ファイル:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rt.jar-重複するクラスの合計:8-異なるクラスローダー。



ファイル:/home/igor/dev/projects/sonar-demo/sonarqube-5.1.2/lib/server/ejb3-persistence-1.0.2.GA.jarは次と重複します

ファイル:/home/igor/dev/projects/sonar-demo/sonarqube-5.1.2/lib/server/tomcat-embed-core-8.0.18.jar-重複するクラスの合計:6-同じクラスローダー! これはエラーです!



ファイル:/home/igor/dev/projects/sonar-demo/sonarqube-5.1.2/lib/server/geronimo-spec-jta-1.0-M1.jarは次と重複します

ファイル:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rt.jar-重複するクラスの合計:6-異なるクラスローダー。



ファイル:/home/igor/dev/projects/sonar-demo/sonarqube-5.1.2/lib/server/sonar-server-5.1.2.jarは次と重複します

ファイル:/home/igor/dev/projects/sonar-demo/sonarqube-5.1.2/lib/server/sonar-core-5.1.2.jar-重複するクラスの合計:1-同じクラスローダー! これはエラーです!



ファイル:/home/igor/dev/projects/sonar-demo/sonarqube-5.1.2/lib/server/sonar-plugin-api-5.1.2.jarは次と重複します

ファイル:/home/igor/dev/projects/sonar-demo/sonarqube-5.1.2/lib/server/sonar-core-5.1.2.jar-重複するクラスの合計:1-同じクラスローダー! これはエラーです!

...



>> jHades multipleClassVersionsReport >>クラスパスリソースレポートの重複:



/javax/xml/xpath/SecuritySupport$4.classには、これらのクラスパスの場所に2つのバージョンがあります。



sun.misc.Launcher $ AppClassLoader-ファイル:/home/igor/dev/projects/sonar-demo/sonarqube-5.1.2/lib/server/xml-apis-1.4.01.jar-クラスファイルサイズ= 495

ブートストラップクラスローダー-ファイル:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rt.jar-クラスファイルサイズ= 896



/javax/xml/transform/sax/SAXResult.classには、これらのクラスパスの場所に2つのバージョンがあります。



sun.misc.Launcher $ AppClassLoader-ファイル:/home/igor/dev/projects/sonar-demo/sonarqube-5.1.2/lib/server/xml-apis-1.4.01.jar-クラスファイルサイズ= 971

ブートストラップクラスローダー-ファイル:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rt.jar-クラスファイルサイズ= 1397



/org/w3c/dom/NameList.classには、これらのクラスパスの場所に2つのバージョンがあります。



sun.misc.Launcher $ AppClassLoader-ファイル:/home/igor/dev/projects/sonar-demo/sonarqube-5.1.2/lib/server/xml-apis-1.4.01.jar-クラスファイルサイズ= 272

ブートストラップクラスローダー-ファイル:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rt.jar-クラスファイルサイズ= 309



/org/w3c/dom/html/HTMLStyleElement.classには、これらのクラスパスの場所に2つのバージョンがあります。



sun.misc.Launcher $ AppClassLoader-ファイル:/home/igor/dev/projects/sonar-demo/sonarqube-5.1.2/lib/server/xml-apis-1.4.01.jar-クラスファイルサイズ= 299

ブートストラップクラスローダー-ファイル:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rt.jar-クラスファイルサイズ= 344



/javax/xml/xpath/SecuritySupport$3.classには、これらのクラスパスの場所に2つのバージョンがあります。



sun.misc.Launcher $ AppClassLoader-ファイル:/home/igor/dev/projects/sonar-demo/sonarqube-5.1.2/lib/server/xml-apis-1.4.01.jar-クラスファイルサイズ= 482

ブートストラップクラスローダー-ファイル:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rt.jar-クラスファイルサイズ= 908



/org/xml/sax/helpers/XMLReaderAdapter.classには、これらのクラスパスの場所に2つのバージョンがあります。



sun.misc.Launcher $ AppClassLoader-ファイル:/home/igor/dev/projects/sonar-demo/sonarqube-5.1.2/lib/server/xml-apis-1.4.01.jar-クラスファイルサイズ= 3251

ブートストラップクラスローダー-ファイル:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rt.jar-クラスファイルサイズ= 5005

...





アスペクト指向プログラミングとAspectJスクリプティングのアプリケーションの詳細については、habrの出版物に慣れることができます。





Wikipediaからこの記事のイラストを地獄の門について取り上げましたが、JARはありません



この記事の情報が、クラスパスアプリケーションの問題の診断に役立つことを願っています。



All Articles