xylz,imxylz

          關注后端架構、中間件、分布式和并發編程

             :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            111 隨筆 :: 10 文章 :: 2680 評論 :: 0 Trackbacks
          以前有段時間需要知道某些類在什么jar包中,這樣當出現ClassNotFoundException或者NoClassDefFoundError的時候我們就可以去找這個類在什么jar包中然后去引用此jar包即可。在我們的系統很小的時候我恨不能都將jar包放入eclipse中,這樣借助eclipse平臺查找類就非常方便了。包括非常有用的Ctrl+Shift+T,Ctrl+T,Reference search等等,但是當工程多了大了的時候,上百個jar包放入eclipse中那個速度完全不是我能忍受的,稍微動一下就看到CPU一直在那抖動。好吧,用maven,更慢,簡直受不了,所以大多數時候Maven是一個比較好的批處理工具,和UI結合起來還不是很好用。

          我發現我非常需要這個從jar包中尋找類的功能,我只需要看看我的類在什么地方而已,僅次而已!于是自己就寫了一個類查找器。非常簡單就是遍歷所有的jar包中的類,當匹配類名稱的時候就顯示類所在的jar包。
          有以下幾個特性:
          • 允許添加jar包,zip包
          • 允許匹配包名稱
          • 允許匹配類名稱
          • 允許區分大小寫
          • 支持模糊查找(包括*和?)
          • 自動匹配(輸入完成后就匹配)
          • 關閉后保存所有jar包結果(下次啟動無需再次掃描)
          • 完全內存查找,速度飛快
          看下面的幾張截圖。








          這個是4個多月前臨時的東西,花了一個下午,用了幾天解決了問題后就基本不用了,所以一直沒有維護,于是就放出來了。有需要的同學就可以看看。由于當初只是臨時用用,所以就寫得非常亂,湊合著用了。

          分析幾段源碼吧。完整的源碼在附件中。
          http://www.aygfsteel.com/Files/xylz/xylz-classfinder.zip
          這里還有一個我使用過的exe程序(Windows 版)。http://www.aygfsteel.com/Files/xylz/xylzcf_0.0.1.0011.zip

          下面是一段字符串匹配的代碼(這段代碼應該是前幾年我從apache ant中摘取出來的,后來移到我的工具包中了,我覺得這對邏輯太復雜,所以一直沒怎么研究,但是確實效率不錯,而且沒有發現使用錯誤。)
            1     public static boolean match(String pattern, String str, boolean isCaseSensitive) {
            2         char[] patArr = pattern.toCharArray();
            3         char[] strArr = str.toCharArray();
            4         int patIdxStart = 0;
            5         int patIdxEnd = patArr.length - 1;
            6         int strIdxStart = 0;
            7         int strIdxEnd = strArr.length - 1;
            8         char ch;
            9 
           10         boolean containsStar = false;
           11         for (int i = 0; i < patArr.length; i++) {
           12             if (patArr[i] == '*') {
           13                 containsStar = true;
           14                 break;
           15             }
           16         }
           17 
           18         if (!containsStar) {
           19             // No '*'s, so we make a shortcut
           20             if (patIdxEnd != strIdxEnd) {
           21                 return false// Pattern and string do not have the same size
           22             }
           23             for (int i = 0; i <= patIdxEnd; i++) {
           24                 ch = patArr[i];
           25                 if (ch != '?') {
           26                     if (isCaseSensitive && ch != strArr[i]) {
           27                         return false// Character mismatch
           28                     }
           29                     if (!isCaseSensitive
           30                             && Character.toUpperCase(ch) != Character.toUpperCase(strArr[i])) {
           31                         return false// Character mismatch
           32                     }
           33                 }
           34             }
           35             return true// String matches against pattern
           36         }
           37 
           38         if (patIdxEnd == 0) {
           39             return true// Pattern contains only '*', which matches anything
           40         }
           41 
           42         // Process characters before first star
           43         while ((ch = patArr[patIdxStart]) != '*' && strIdxStart <= strIdxEnd) {
           44             if (ch != '?') {
           45                 if (isCaseSensitive && ch != strArr[strIdxStart]) {
           46                     return false// Character mismatch
           47                 }
           48                 if (!isCaseSensitive
           49                         && Character.toUpperCase(ch) != Character.toUpperCase(strArr[strIdxStart])) {
           50                     return false// Character mismatch
           51                 }
           52             }
           53             patIdxStart++;
           54             strIdxStart++;
           55         }
           56         if (strIdxStart > strIdxEnd) {
           57             // All characters in the string are used. Check if only '*'s are
           58             // left in the pattern. If so, we succeeded. Otherwise failure.
           59             for (int i = patIdxStart; i <= patIdxEnd; i++) {
           60                 if (patArr[i] != '*') {
           61                     return false;
           62                 }
           63             }
           64             return true;
           65         }
           66 
           67         // Process characters after last star
           68         while ((ch = patArr[patIdxEnd]) != '*' && strIdxStart <= strIdxEnd) {
           69             if (ch != '?') {
           70                 if (isCaseSensitive && ch != strArr[strIdxEnd]) {
           71                     return false// Character mismatch
           72                 }
           73                 if (!isCaseSensitive
           74                         && Character.toUpperCase(ch) != Character.toUpperCase(strArr[strIdxEnd])) {
           75                     return false// Character mismatch
           76                 }
           77             }
           78             patIdxEnd--;
           79             strIdxEnd--;
           80         }
           81         if (strIdxStart > strIdxEnd) {
           82             // All characters in the string are used. Check if only '*'s are
           83             // left in the pattern. If so, we succeeded. Otherwise failure.
           84             for (int i = patIdxStart; i <= patIdxEnd; i++) {
           85                 if (patArr[i] != '*') {
           86                     return false;
           87                 }
           88             }
           89             return true;
           90         }
           91 
           92         // process pattern between stars. padIdxStart and patIdxEnd point
           93         // always to a '*'.
           94         while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) {
           95             int patIdxTmp = -1;
           96             for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
           97                 if (patArr[i] == '*') {
           98                     patIdxTmp = i;
           99                     break;
          100                 }
          101             }
          102             if (patIdxTmp == patIdxStart + 1) {
          103                 // Two stars next to each other, skip the first one.
          104                 patIdxStart++;
          105                 continue;
          106             }
          107             // Find the pattern between padIdxStart & padIdxTmp in str between
          108             // strIdxStart & strIdxEnd
          109             int patLength = (patIdxTmp - patIdxStart - 1);
          110             int strLength = (strIdxEnd - strIdxStart + 1);
          111             int foundIdx = -1;
          112             strLoop: for (int i = 0; i <= strLength - patLength; i++) {
          113                 for (int j = 0; j < patLength; j++) {
          114                     ch = patArr[patIdxStart + j + 1];
          115                     if (ch != '?') {
          116                         if (isCaseSensitive && ch != strArr[strIdxStart + i + j]) {
          117                             continue strLoop;
          118                         }
          119                         if (!isCaseSensitive
          120                                 && Character.toUpperCase(ch) != Character
          121                                         .toUpperCase(strArr[strIdxStart + i + j])) {
          122                             continue strLoop;
          123                         }
          124                     }
          125                 }
          126 
          127                 foundIdx = strIdxStart + i;
          128                 break;
          129             }
          130 
          131             if (foundIdx == -1) {
          132                 return false;
          133             }
          134 
          135             patIdxStart = patIdxTmp;
          136             strIdxStart = foundIdx + patLength;
          137         }
          138 
          139         // All characters in the string are used. Check if only '*'s are left
          140         // in the pattern. If so, we succeeded. Otherwise failure.
          141         for (int i = patIdxStart; i <= patIdxEnd; i++) {
          142             if (patArr[i] != '*') {
          143                 return false;
          144             }
          145         }
          146         return true;
          147     }
          148 
          149     static void print(File jarFile) throws Exception {
          150         JarFile file = new JarFile(jarFile);
          151         for (JarEntry e : Collections.list(file.entries())) {
          152             System.out.println(e.getName());
          153         }
          154     }

          java swing中當光標定位文本框時自動選中其內容的代碼。
          1         cnameText.addFocusListener(new FocusAdapter() {
          2             @Override
          3             public void focusGained(FocusEvent e) {
          4              if(cnameText.getText().length()>0) {
          5                  cnameText.setSelectionStart(0);
          6                  cnameText.setSelectionEnd(cnameText.getText().length());
          7              }
          8             }
          9         });

          當文本框中有輸入變化時觸發更新列表動作。早期的做法是將doText放入線程中這樣防止GUI卡死,但是在這個例子中由于太快了,所以就沒有新起線程。
           1         cnameText.getDocument().addDocumentListener(new DocumentListener() {
           2 
           3             @Override
           4             public void changedUpdate(DocumentEvent e) {
           5                 doText(cnameText.getText());
           6             }
           7 
           8             @Override
           9             public void insertUpdate(DocumentEvent e) {
          10                 doText(cnameText.getText());
          11             }
          12 
          13             @Override
          14             public void removeUpdate(DocumentEvent e) {
          15                 doText(cnameText.getText());
          16             }
          17         });

          遍歷一個jar包中所有類的過程。
           1 List<JarEntry> list = Collections.list(new JarFile(jarFile).entries());
           2                 List<String> fullNames = new ArrayList<String>();
           3                 for (JarEntry e : list) {
           4                     String n = e.getName();
           5                     if (n.endsWith(".class")) {
           6                         n=n.substring(0,n.length()-6);
           7                         fullNames.add(n.replace('/''.'));
           8                     }
           9                 }
          10                 classCount = fullNames.size();
          11                 classNames = fullNames.toArray(new String[classCount]);


          大概這么多吧,寫得很亂,看的也很累!!!



          ©2009-2014 IMXYLZ |求賢若渴
          posted on 2009-12-31 17:07 imxylz 閱讀(20881) 評論(11)  編輯  收藏 所屬分類: J2EE

          評論

          # re: 一個查找jar包中類的小工具 2009-12-31 21:28 99讀書人俱樂部
          阿經濟的技術監督  回復  更多評論
            

          # re: 一個查找jar包中類的小工具 2009-12-31 21:34 羅萊家紡官方網
          文章不錯!支持~  回復  更多評論
            

          # re: 一個查找jar包中類的小工具[未登錄] 2010-01-01 03:23 小毅
          沒必要重新造輪子。。。告訴你兩個網站:

          英文的: www.findjar.com
          中文的: www.jar114.com

          都比你做得好得多。。。功能更全
            回復  更多評論
            

          # re: 一個查找jar包中類的小工具 2010-01-01 10:53 xylz
          @小毅
          如果能上網的話直接去Google好了,基本上都能找到!  回復  更多評論
            

          # re: 一個查找jar包中類的小工具 2010-01-02 15:26 rox
          呵呵,我也在寫一個類似的東西。
          不過,需求有點不一樣,是要查出所有jar中重復的jar包和jar包中的重復類。
          當然JBoss Tattletale已經基本滿足要求,只是報表不太適合領導的要求。  回復  更多評論
            

          # re: 一個查找jar包中類的小工具 2010-07-14 09:04 zhong
          我一般就是用eclipse的 ctrl+shift+t的方式來找  回復  更多評論
            

          # re: 一個查找jar包中類的小工具 2010-07-14 14:25 xylz
          @zhong
          如果你有幾百個jar包的時候你就不容易查找某個類了。將所有jar包加入一個空白的eclipse工程?這也會非常慢,而且eclipse也會有緩存的概念,這會導致那些使用maven一天發布N個SNAPSHOT包的非常痛苦。  回復  更多評論
            

          # re: 一個查找jar包中類的小工具 2012-01-10 21:42 chennan
          @小毅
          傻逼 別人做的是找自己jar包里面的類
          你是根據類找別人服務器的jar包.....
          如果這個jar包是你自己寫的. 114服務器沒有這個jar. 你找個吊毛啊  回復  更多評論
            

          # re: 一個查找jar包中類的小工具[未登錄] 2014-02-27 07:29 程序員
          www.findmaven.net,根據class名和jar名查找jar和maven gav,還提供maven依賴樹,jar結構等  回復  更多評論
            

          # re: 一個查找jar包中類的小工具 2014-02-27 20:45 imxylz
          @程序員
          網站不錯。我當年是為了搜索本地,我們自己的類而使用的。我們最開始一直用ant,沒有使用maven,主要是我們內網無法上外網。  回復  更多評論
            

          # re: 一個查找jar包中類的小工具[未登錄] 2015-03-12 14:04 jiajia
          這東西做得不錯,確實是用來找自定義的jar(第三方公司,不是開源項目)包中class的利器。感謝樓主  回復  更多評論
            


          ©2009-2014 IMXYLZ
          主站蜘蛛池模板: 石楼县| 茂名市| 黄冈市| 贞丰县| 阿克苏市| 邢台县| 红安县| 二连浩特市| 九江县| 崇文区| 宝丰县| 化州市| 将乐县| 新竹市| 博湖县| 忻城县| 古蔺县| 疏附县| 蒙山县| 黄冈市| 桃园市| 昆山市| 邢台县| 津南区| 辉南县| 石台县| 通江县| 贵德县| 宜兴市| 邛崃市| 马边| 卢龙县| 五常市| 白玉县| 托克逊县| 思茅市| 长岛县| 浦城县| 延庆县| 开江县| 集贤县|