S_a_k_Uの日記みたいなDB

~サクゥーと呼ばないで~

serialVersionUIDの重複チェック

みんなね。
クラスをコピーしてもね。
serialVersionUIDを生成してくれないんだよ。
別に要件で必要じゃないんだけど、念のため全てのクラスにSerializable付けてるんだけなんだけどね。
コメントもちゃんと書いて?変えて?くれんし(涙


ということで、serialVersionUIDの重複チェックをするコードを書いてみた。
ついでに
・Serializableをimplementしてないクラス
・serialVersionUIDが未定義のクラス
も検出できるようにしてみる。
ClassViewerクラスはこちら
(2009/02/04 id:hhelibexさんのコメントより、Serializableをimplementしているかどうかのチェックを、asSubclassメソッドからisAssignableFromメソッドに変更)

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class SerialVersionUidChecker implements Serializable {

    private static final long serialVersionUID = -2738454501799301164L;

    public SerialVersionUidChecker() {
        super();
    }
    
    public static void main(String [] args) {
        new SerialVersionUidChecker().check("jp.co.");
    }
    
    public void check(String packageName) {
        ClassViewer viewer = new ClassViewer();
        viewer.setup();
        List classList = viewer.getAllClassList();
        List errList = new ArrayList();
        List noserialList = new ArrayList();
        List undefIdList = new ArrayList();
        Map idMap = new Hashtable();
        for ( int i = 0 ; i < classList.size() ; i++ ) {
            String className = (String) classList.get(i);
            // 指定されたパッケージのみを対象とする
            if ((packageName != null) && (className.startsWith(packageName) == false)) {
                continue;
            }
            try {
                // クラスを取得
                Class c = Class.forName(className);
                if (c.isInterface() == true) {
                    continue;
                }
                // SerialVersionUIDを取得
                String id = null;
                try {
                    // Serializableをimplementしているかどうか(2009/02/04変更)
                    //c.asSubclass(Serializable.class);
                    if (Serializable.class.isAssignableFrom(c) == false) {
                        System.out.println(className + ": Serializableがimplementされていません。");
                        noserialList.add(className);
                        continue;
                    }
                    // 「private static final long serialVersionUID」を取得
                    Field f = c.getDeclaredField("serialVersionUID");
                    f.setAccessible(true);
                    id = String.valueOf(f.get(null));
                } catch (NoSuchFieldException noSuchFieldException) {
                    System.out.println(className + ": SerialVersionUIDが未定義です。");
                    undefIdList.add(className);
                    continue;
                } catch (SecurityException securityException) {
                    System.out.println(className + ": SerialVersionUIDが未定義です。");
                    undefIdList.add(className);
                    continue;
                } catch (IllegalAccessException illegalAccessException) {
                    System.out.println(className + ": SerialVersionUIDが未定義です。");
                    undefIdList.add(className);
                    continue;
                }
                // SerialVersionUIDのマップの有無を確認
                if (idMap.get(id) == null) {
                 	idMap.put(id, new ArrayList());
                } else {
                    System.out.println(className + ": SerialVersionUIDが重複しています。");
                }
                // リストにクラス名を追加
                List list = (List) idMap.get(id);
                list.add(className);
            } catch (ClassNotFoundException classNotFoundException) {
                System.out.println(className + ": ClassNotFoundExceptionです。");
                errList.add(className);
            } catch (NoClassDefFoundError noClassDefFoundError) {
                System.out.println(className + ": NoClassDefFoundErrorです。");
                errList.add(className);
            } catch (UnsatisfiedLinkError unsatisfiedLinkError) {
                System.out.println(className + ": UnsatisfiedLinkErrorです。");
                errList.add(className);
            }
        }

        System.out.println("\n【エラーとなったクラス】");
        for ( int i = 0 ; i < errList.size() ; i++ ) {
            System.out.println((String) errList.get(i));
        }
        System.out.println("\n【Serializableがimplementされていないクラス】");
        for ( int i = 0 ; i < noserialList.size() ; i++ ) {
            System.out.println((String) noserialList.get(i));
        }
        System.out.println("\n【SerialVersionUIDが未定義のクラス】");
        for ( int i = 0 ; i < undefIdList.size() ; i++ ) {
            System.out.println((String) undefIdList.get(i));
        }
        System.out.println("\n【SerialVersionUIDが重複しているクラス】");
        Iterator ite = idMap.entrySet().iterator();
        while (ite.hasNext()) {
            Entry entry = (Entry) ite.next();
            String id = (String) entry.getKey();
            List list = (List) idMap.get(id);
            if (list.size() > 1) {
                System.out.println("[" + id + "]");
                for ( int i = 0 ; i < list.size() ; i++ ) {
                    System.out.println((String) list.get(i));
                }        
            }
        }
        
    }
    
}