上次在写完那篇文章后,可以顺利的进行开发了,很多地方通过这种形式进行了回调。直到最近,提交svn打WAR包,部署出现了问题!开始还想着,不可能出问题,结果还是出乎意料。
中间件使用的是weblogic,weblogic处理war包机制没有太多了解,不像tomcat之类的将war包全部解压到目录下,如果是这样,那么原来的写法是没有问题的。但现在weblogic不知道是如何实现的,我再跟了代码以后,发现它是通过将代码打成了一个jar包实现的,在原先代码中,获取路径为:
D:/Oracle/Middleware/user_projects/domains/exp_domain/servers/AdminServer/tmp/_WL_user/_appsdir_bgt_war/4btz9w/war/
WEB-INF/lib/_wl_cls_gen.jar!/com/tjhq/synch2/callback
明显就已经错误了,所以后台一直在报空指针错误,因为怎么可能通过文件路径访问到jar包里呢!问了问同事,都告诉我,weblogic处理比较特殊,只能通过流的形式获取文件“内容”,但问题是我需要获取的是某个包下,所有接口的名称,以及class文件啊,我通过流的形式只能取读取文件内容,我要文件没有一分钱的作用。之后,网上搜了不少文章,大部分都是针对jar包的,对此我一直怀疑,最后还是抱着尝试的态度,试了一下果然可以了,通过JarFile这个类定位到jar包,之后通过这个类的遍历文件的方法就可以正常获得文件的名字等信息了。
private static List<Class> processForJar(URL resource,String packagePath,boolean needInterface){
try{
List<Class> classes = new ArrayList<Class>();
String tempPath = resource.getPath();
String jarPath = tempPath.substring(0, tempPath.indexOf(".jar")) + ".jar";
JarFile jf = new JarFile(jarPath);
Enumeration<JarEntry> entries = jf.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String name = entry.getName();
if (name.startsWith(packagePath) && name.endsWith(".class")) {
String className = name.substring(0,name.length() - 6).replace("/", ".");
Class cl = Class.forName(className);
if(needInterface){
if(cl.isInterface()){
classes.add(cl);
}else{
logger.warn("初始化加载时,该"+cl.getName()+"类不是一个接口,跳过加载该对象!");
}
}else{
if(!cl.isInterface()){
classes.add(cl);
}
}
}
}
return classes;
}catch(Exception e){
e.printStackTrace();
}
return null;
}