※ ChatGPTを利用し、要約された質問です(原文:重複jarの調査の仕方)
バージョン違いの重複するjarの調査方法
このQ&Aのポイント
Javaプロジェクトでバージョン違いの重複するjarを調査する方法について説明します。
mavenを利用していれば依存関係階層を調べて適宜excludeすることができますが、純粋なJavaプロジェクトの場合は手動でjarのクラスパスをチェックする方法があります。
テストケースやJavaコードを使用してjarの定義を調べる方法もあります。
お世話になります。Javaでプログラミングの勉強をしています。
mavenなど、Jarの依存関係を解決してくれるツールがありますが、
バージョンが違うlog4jなどが複数の依存ライブラリで利用されていて、
実行時にエラーが出てしまうことがあります。(コンパイル時にはエラーは出ない)
例)
dev_project ->log4j v1.2.4に依存
+-depend_project_a -> log4j v1.1.3に依存
+-depend_project_b -> log4j v1.1.4に依存
+-depend_project_c -> log4j v0.9.1に依存
こういった場合、mavenを利用していれば、依存関係階層を調べて
適宜excludeしていけばよいと思います。
しかしそのようなツールを使っていない(純粋なjavaプロジェクト)場合、
どのようにバージョン違いの重複するjarを調べたら良いかわかりません。
私が試してみたのは、jarのクラスパスをひとつずつチェックして
log4j-****.jarの定義をひとつずつ探すという方法です。
これは大変手間がかかります。
テストケースなどJavaコード内で調べる方法はありますでしょうか。
どうぞ宜しくお願い致します。
■参考環境
OS:windows8.1
Java:oracle-java1.8
eclipse: 4.4
maven: 3.2
お礼
回答頂きましてありがとうございます。 私の質問の仕方が悪かったのですが、 どのjarのどのクラスが重複しているかわからない状態から調べる方法を知りたかったのです。 質問内の例ではlog4jが競合していることがわかってる風にとれるので、 その場合はteketonさんの方法で代表的なクラスからどのjarが読み込まれているか調べることが可能ですね。
補足
解決しました。 クラスパスを取得し、jar内のクラスを取得していけば 実際にクラスがロードされているかどうかに関わらず、 重複するパッケージ・クラスを調査することができました。 サンプルプロジェクト構成ここから testprj │ .classpath │ .project │ ├─.settings │ org.eclipse.jdt.core.prefs ├─lib │ log4j-1.2.14.jar │ log4j-1.2.15.jar │ log4j-1.2.16.jar │ log4j-1.2.17.jar │ └─src └─jp └─co └─testprj DependJarDetectTest.java サンプルプロジェクト構成ここまで サンプルコード(DependJarDetectTest.java)ここから package jp.co.testprj; import java.io.File; import java.util.Enumeration; import java.util.Properties; import java.util.TreeSet; import java.util.jar.JarEntry; import java.util.jar.JarFile; public class DependJarDetectTest { private TreeSet<String> resultSet = new TreeSet<String>(); public static void main(String[] args) { try { new DependJarDetectTest().execDetect(); } catch (Exception e) { e.printStackTrace(); } } private void execDetect() throws Exception { Properties prop = System.getProperties(); String javaclasspath = prop.getProperty("java.class.path", null); String[] classPathArray = javaclasspath.split(";"); for (int i = 0; i < classPathArray.length; i++) { System.out.println("java.class.path [" + i + "] = " + classPathArray[i]); getJarFileClassListFromClassPath(classPathArray[i]); } } private void getJarFileClassListFromClassPath(String classPath) throws Exception { File file = new File(classPath); if (file.isDirectory()) return; JarFile jarFile = new JarFile(file); for (Enumeration<?> e = jarFile.entries(); e.hasMoreElements();) { JarEntry entry = (JarEntry) e.nextElement(); if(entry.isDirectory() || entry.getName().indexOf(".class") < 0) continue; if(resultSet.contains(entry.getName())) { System.out.println("\t[競合]: " + entry.getName()); } else { System.out.println("\t" + entry.getName()); resultSet.add(entry.getName()); } } jarFile.close(); } } サンプルコードここまで ご協力頂きましてありがとうございました。