首页 > 代码库 > 解决javaassist 出现的类没找到异常ClassNotFoundException,获取工程下任意class对象

解决javaassist 出现的类没找到异常ClassNotFoundException,获取工程下任意class对象

项目中要对工程下任意class文件进行解析,但是使用javaassist中经常出现类没找到异常。当然最主要的还是ClassPool()没找到这东西,而搜索范围是整个项目的class,

所以就做了一个处理,通过,项目下的classpath这个文件,获取所有jar路径在,再通过文件递归搜索获取所有java编译后的class文件路径,将所有路径都添加到对象池中。当然这一步是很费时的,所以最好只初始化一次。

/***

* 静态存储
*/
private static ClassPool pool;


public ReflectUtil() {
// 初始化对象池
if(pool==null){
initClassPool();}
}

根据calsspath文件得到里面的内容并且获取到所有jar路径。

有些方法就没写了。自己网上查下


/**
* 环境变量过滤器

* @author litao

*/
private interface ClasspathEntryFilter<T> {
/**
* 环境变量处理

* @param classpathEntry
* @return 处理后的环境变量,{@code null}表示忽略
*/
public T accept(IClasspathEntry classpathEntry);
}


/**
* 过滤环境变量实体集合

* @param project
* @param filter
*            过滤器
* @return
*/
private <T> List<T> listClasspathEntries(IJavaProject project,
ClasspathEntryFilter<T> filter) {
IClasspathEntry[] currEntries;
List<T> finalEntry = new ArrayList<T>();
try {
currEntries = project.getRawClasspath();
for (IClasspathEntry ce : currEntries) {
T newCE = filter.accept(ce);
if (newCE != null) {
finalEntry.add(newCE);
}
}
} catch (JavaModelException e) {


}
return finalEntry;
}

/**
* 获取所有jar路径
* jarPath=D:\studio_dev\deploycontent\WebRoot\WEB-INF\runlib\servlet
* -api.jar

* @param project
* @return
*/
private List<String> getListJar(IProject project) {
return listClasspathEntries(JavaCore.create(project),
new ClasspathEntryFilter<String>() {
String workPath = Platform.getInstallLocation().getURL()
.getPath().substring(1).replace("/", "\\");


@Override
public String accept(IClasspathEntry classpathEntry) {
// TODO Auto-generated method stub
if (classpathEntry.getEntryKind() == IClasspathEntry.CPE_VARIABLE)
return workPath
+ (classpathEntry.getPath().toOSString()
.substring(classpathEntry.getPath()
.toOSString().indexOf("\\") + 1));
return null;


}


});
}

工程下的java类编译后的class文件。采用的是工程文件递归获取class文件路径,具体就不写了。

只是注意下路径要跟到class最顶层包,减少循环次数。

最后,将所有jar跟class路径都放入对象池中


/***

* 初始化对象池

* 这里加载了工程所有的jar已经class文件

*/
private void initClassPool() {
try {
pool = new ClassPool();
List<String> jarPath = getListJar(StringUtil.getProject());

//获取class文件的方法。
List<String> classFile = StringUtil.getListClassesFilePath();
// 加载所有类
for (String string : classFile) {
//D:/studio_dev/runtime-Eclipse应用程序(1)/jfids_demo/WebRoot/WEB-INF/classes


pool.appendClassPath(string);


}
// 加载所有jar
for (String string : jarPath) {
pool.appendClassPath(string);


}
} catch (NotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


}

最后。就可以通过直接通过包名反射获取工程下的任意类了。

CtClass claName = new ReflectUtil().getCtClass((pkg));

-------------------------------------


这个是针对我目前的项目写的。可以自行优化。

个人觉得。。

如果需要反射,

。这真的是一个很有用的办法。。一劳永逸。。反正我是用的爽歪歪。。。只是效率上有待优化。。。