importjava.io.ByteArrayOutputStream;importjava.io.File;importjava.io.FileFilter;importjava.io.FileInputStream;importjava.nio.ByteBuffer;importjava.nio.channels.Channels;importjava.nio.channels.FileChannel;importjava.nio.channels.WritableByteChannel;importjava.util.ArrayList;importjava.util.List;importcom.sea.common.util.Resource;importcom.sea.common.util.StrStream;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;/*** 编译任意class文件,需要保证class文件可用,否则ERROR
*
*@authorChenSS 2017年8月25日上午10:04:38
**/@Deprecatedpublic class MyClassLoader extendsClassLoader{private static Logger logger = LoggerFactory.getLogger(ClassLoader.class);publicMyClassLoader() {super(Resource.getClassLoader());
}public static void main(String[] args) throwsClassNotFoundException {
MyClassLoader loader= newMyClassLoader();try{
List> clazz = loader.load("C:/Users/ChenSS/Desktop/代码测试/build/classes/", "com.css.common.util");
System.out.println(clazz);
}catch(Exception e) {
e.printStackTrace();
}
}public List>load(String location, String pkg) {return load(newFile(location), pkg);
}public List>load(File file, String pkg) {//StrStream是自定义的字符串校验工具,用于查找前缀是pkg(包名)、并且不包含美元符的文件
StrStream stream = new StrStream().prefix(pkg).notExists('$');returnload(file, stream);
}public List>load(File file, StrStream stream) {
List> classes = new ArrayList<>();if (file.exists() &&file.isDirectory()) {for (File dir : likeFile(file, "", stream)) {if(dir.isDirectory()) {
traverseFile(dir, dir.getName(), classes, stream);
}else{//根目录的class
}
}
}returnclasses;
}/*** 递归搜索全部文件,查找全部.class文件
*@paramdir
*@parampkg
*@paramclasses
*@paramstream*/
public void traverseFile(File dir, String pkg, List>classes, StrStream stream) {for(File file : likeFile(dir, pkg, stream)) {if(file.isDirectory()) {//文件夹就遍历下一级目录
traverseFile(file, pkg + '.' +file.getName(), classes, stream);
}else{//根据.class文件直接生成Class>
String className = null;try{
String fileName=file.getName();
className= pkg + '.' + fileName.substring(0, fileName.length() - 6);
Class> clazz =format(file, className);
logger.debug(clazz.toString());
classes.add(clazz);
}catch(Exception e) {
e.printStackTrace();
logger.error(className+ " : load error");continue;
}
}
}
}public Class> format(String fileName, String className) throwsException {return format(newFile(fileName), className);
}/*** 从.class文件直接生成Class>,从IO到对象的转换,IO是未经过检查的;
* 因此,如果想要使用此类,必须保证全部的.class文件可以创建Java类;
* 手动编码、并且编译通过的.class文件不会有问题;
* 扫描自己不熟悉的.class文件时,如果.class文件内容是错误的,有可能产生强制中断主函数的Error。*/
public Class> format(File file, String className) throwsException {
FileInputStream fis= newFileInputStream(file);
FileChannel fileC=fis.getChannel();
ByteArrayOutputStream baos= newByteArrayOutputStream();
WritableByteChannel wbc=Channels.newChannel(baos);
ByteBuffer buffer= ByteBuffer.allocateDirect(1024);while (fileC.read(buffer) > 0) {
buffer.flip();
wbc.write(buffer);
buffer.clear();
}byte[] b =baos.toByteArray();
IOUtils.closeQuietly(baos, wbc, fileC, fis);return defineClass(className, b, 0, b.length);
}/***
*@paramdir 文件夹
*@paramstring 路径名
*@paramstream 字符串校验类
*@return
*/
public staticFile[] likeFile(File dir, String string, StrStream stream) {return dir.listFiles(newFileFilter() {
@Overridepublic booleanaccept(File file) {return stream.string(string).like() ||file.isFile();
}
});
}
}