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.blogjava.net/Files/xylz/xylz-classfinder.zip
这里还有一个我使用过的exe程序(Windows 版)。http://www.blogjava.net/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 阅读(20873) 评论(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