xylz,imxylz

          關(guān)注后端架構(gòu)、中間件、分布式和并發(fā)編程

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

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








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

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

          下面是一段字符串匹配的代碼(這段代碼應(yīng)該是前幾年我從apache ant中摘取出來的,后來移到我的工具包中了,我覺得這對(duì)邏輯太復(fù)雜,所以一直沒怎么研究,但是確實(shí)效率不錯(cuò),而且沒有發(fā)現(xiàn)使用錯(cuò)誤。)
            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中當(dāng)光標(biāo)定位文本框時(shí)自動(dòng)選中其內(nèi)容的代碼。
          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         });

          當(dāng)文本框中有輸入變化時(shí)觸發(fā)更新列表動(dòng)作。早期的做法是將doText放入線程中這樣防止GUI卡死,但是在這個(gè)例子中由于太快了,所以就沒有新起線程。
           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         });

          遍歷一個(gè)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 閱讀(20897) 評(píng)論(11)  編輯  收藏 所屬分類: J2EE

          評(píng)論

          # re: 一個(gè)查找jar包中類的小工具 2009-12-31 21:28 99讀書人俱樂部
          阿經(jīng)濟(jì)的技術(shù)監(jiān)督  回復(fù)  更多評(píng)論
            

          # re: 一個(gè)查找jar包中類的小工具 2009-12-31 21:34 羅萊家紡官方網(wǎng)
          文章不錯(cuò)!支持~  回復(fù)  更多評(píng)論
            

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

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

          都比你做得好得多。。。功能更全
            回復(fù)  更多評(píng)論
            

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

          # re: 一個(gè)查找jar包中類的小工具 2010-01-02 15:26 rox
          呵呵,我也在寫一個(gè)類似的東西。
          不過,需求有點(diǎn)不一樣,是要查出所有jar中重復(fù)的jar包和jar包中的重復(fù)類。
          當(dāng)然JBoss Tattletale已經(jīng)基本滿足要求,只是報(bào)表不太適合領(lǐng)導(dǎo)的要求。  回復(fù)  更多評(píng)論
            

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

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

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

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

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

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


          ©2009-2014 IMXYLZ
          主站蜘蛛池模板: 南丹县| 奉节县| 云龙县| 兴山县| 岐山县| 玛曲县| 贞丰县| 报价| 株洲市| 嘉定区| 政和县| 双峰县| 札达县| 台东市| 文成县| 兴义市| 资溪县| 赞皇县| 乌拉特后旗| 河曲县| 焉耆| 娄烦县| 苍溪县| 阳山县| 榆树市| 镇康县| 辉县市| 五大连池市| 洛宁县| 新昌县| 体育| 海口市| 连山| 大田县| 同心县| 瓦房店市| 连城县| 上栗县| 六枝特区| 商南县| 遵义市|