2009-09-16 4 views
12

私は古いフレームワークのためにいくつかのユニットテストを実装しようとしています。私はデータベース層を模擬しようとしています。残念ながら、私たちのフレームワークはちょっと古く、ベストプラクティスをあまり使用していないので、懸念が明確に分離されていません。私は、データベース層を模倣しようとすると、JVMが使用されることのない膨大な数のクラスをロードするかもしれないと心配しています。ClassLoaderがロードしたクラスを取得する方法はありますか?

クラスローダーはよく分かりませんが、これは問題ではないかもしれません。特定のClassLoaderがロードされているすべてのクラスをピークにして、フードの下で何が起こっているかを証明する方法はありますか?

+0

「どのようにJVMには使用されないクラスが膨大な量でロードされるのですか」 –

答えて

15

java -verbose 

を使用すると、出力の膨大な量を生産することを警告すること。出力をファイルに記録し、grepを使います。あなたは「ティー」フィルタを使用している場合、あなたはこれを試みることができる:

java -verbose | tee classloader.log 
grep class classloader.log 
2

わかりません。しかし、私はそれを行うことができると見る方法があります。しかし、それはおそらくあまりにもばかげている。 aspectを試して、loadclassのポイントカットを置くことができます。 また、jvm引数-verboseが役に立つかもしれません。

35

独自のクラスローダーを作成して、ユニットテスト中にロードすることができます。あなた自身のカスタムClassloaderが何をしているのかを印刷します。

それともあなただけのクラスがロードされているかを知りたい場合は、操作を行います。

java -verbose:class 
1

を別の方法として、あなたが言及したように、特定のクラスローダーのために、あなたは、このコードスニペットを使用することができます。必要に応じてobj変数の値を変更するだけです。

Object obj = this; 
ClassLoader classLoader = obj.getClass().getClassLoader(); 
File file = new File("classloderClasses.txt"); 
if (file.exists()) { 
    file.delete(); 
} 
if (classLoader != null) { 
    try { 
     Class clClass = classLoader.getClass(); 
     while (clClass != ClassLoader.class) { 
      clClass = clClass.getSuperclass(); 
     } 
     java.lang.reflect.Field classesField = clClass.getDeclaredField("classes"); 
     classesField.setAccessible(true); 
     Vector classes = (Vector) classesField.get(classLoader); 
     FileOutputStream fos = new FileOutputStream("classloderClasses.txt", true); 
     fos.write(("******************** " + classLoader.toString() + " ******************** " + "\n").getBytes()); 
     fos.write(Arrays.toString(classes.toArray()).getBytes()); 
     fos.close(); 
    } catch (Exception exception) { 
     exception.printStackTrace(); 
     // TODO 
    } 
}