javassist와 annotation을 이용하여class의 특정method의classbytecode를 수정합니다

6748 단어 F#
package xuliangjun;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtField;
import javassist.CtMethod;
import javassist.NotFoundException;
import javassist.bytecode.AnnotationsAttribute;
import javassist.bytecode.MethodInfo;
import javassist.bytecode.annotation.Annotation;

public class ExceptionLog {

	private static String rootPath = ClassLoader.getSystemResource(".").getPath();
	private static File rootFile = new File(rootPath.replace("%20", " "));// bin    
	private static File tmp = new File(rootPath.replace("%20", " ")
			.substring(0, rootPath.indexOf("bin")).concat("tmp"));//     
	private static ArrayList<String> fileList = new ArrayList<String>();// bin          

	/**
	 *   bin         
	 * 
	 * @param rootFile
	 * @param fileList
	 * @throws IOException
	 */
	private static ArrayList<String> listFiles(File rootFile,
			ArrayList<String> fileList) throws IOException {
		File[] allFiles = rootFile.listFiles();
		for (File file : allFiles) {
			if (file.isDirectory()) {
				listFiles(file, fileList);
			} else {
				String path = file.getCanonicalPath();
				String clazz = path.substring(path.indexOf("bin") + 4);
				fileList.add(clazz.replace("\\", ".").substring(0,clazz.lastIndexOf(".")));
			}
		}
		return fileList;
	}

	private static void InsertingExceptionHandleMethod() throws IOException {

		ExceptionLog.copy(rootFile, tmp);
		fileList = ExceptionLog.listFiles(rootFile, fileList);

		ClassPool cp = ClassPool.getDefault();
		CtClass cc = null;
		CtField ctf = null;
		CtClass[] cte = null;

		for (int i = 0; i < fileList.size(); i++) {

			try {
				cc = cp.get(fileList.get(i));

				// System.out.println(cc);
			} catch (NotFoundException e) {
				System.out.println("         ,             ");
				e.printStackTrace();
			}

			try {
				//       insert
				ctf = cc.getField("ExceptionCheckingCount");
				if (ctf != null)
					continue;
			} catch (NotFoundException e1) {

				CtMethod[] ctms = cc.getMethods();
				// System.out.println(ctms);
				for (CtMethod m : ctms) {

					// System.out.println(m);

					MethodInfo minfo = m.getMethodInfo();
					// System.out.println(minfo);

					AnnotationsAttribute attr = (AnnotationsAttribute) minfo
							.getAttribute(AnnotationsAttribute.visibleTag);
					// System.out.println(attr);
					if (attr != null) {
						Annotation an = attr
								.getAnnotation("xuliangjun.ExceptionChecking");
						if (an != null) {
							// System.out.println(an);
							try {

								m.insertBefore("System.out.println(\"Enter [ "
										+ m.getLongName() + " ] \");");
								m.insertAfter("System.out.println(\"Leave [ "
										+ m.getLongName() + " ] \");");

								ctf = CtField.make(
										"private int ExceptionCheckingCount;",
										cc);
								cc.addField(ctf);

								try {
									cte = m.getExceptionTypes();
									if (cte != null) {
										for (CtClass ctel : cte) {
											m.addCatch("    ", ctel);
										}
									}
									m.setExceptionTypes(cte);
								} catch (NotFoundException e) {

								}

							} catch (CannotCompileException e) {
								System.out.println("       ,         ");
								e.printStackTrace();
							}
							//    bin   
							try {
								cc.writeFile("bin");
								cc.defrost();
							} catch (CannotCompileException e) {
								System.out.println("       ,         ");
								e.printStackTrace();
							}
						}

					}

				}

			}

		}
	}

	private static void copy(File resFile, File objFolderFile)
			throws IOException {
		if (!resFile.exists())
			return;
		if (!objFolderFile.exists())
			objFolderFile.mkdirs();
		if (resFile.isFile()) {
			File objFile = new File(objFolderFile.getPath() + File.separator
					+ resFile.getName());
			//         
			InputStream ins = new FileInputStream(resFile);
			FileOutputStream outs = new FileOutputStream(objFile);
			byte[] buffer = new byte[1024 * 512];
			int length;
			while ((length = ins.read(buffer)) != -1) {
				outs.write(buffer, 0, length);
			}
			ins.close();
			outs.flush();
			outs.close();
		} else {
			String objFolder = objFolderFile.getPath() + File.separator
					+ resFile.getName();
			File _objFolderFile = new File(objFolder);
			_objFolderFile.mkdirs();
			for (File sf : resFile.listFiles()) {
				copy(sf, new File(objFolder));
			}
		}
	}

	private static void delete(File file) {
		if (!file.exists())
			return;
		if (file.isFile()) {
			file.delete();
		} else {
			for (File f : file.listFiles()) {
				delete(f);
			}
			file.delete();
		}
	}

	private static void removingExceptionHandleMethod() {

		try {
			String path = tmp.getPath().concat("bin");
			tmp = new File(path);
			path = rootFile.getParent();
			rootFile = new File(path);
			copy(tmp, rootFile);
			tmp = new File(rootPath.replace("%20", " ")
					.substring(0, rootPath.indexOf("bin")).concat("tmp"));
			delete(tmp);
		} catch (IOException e) {

			e.printStackTrace();
		}
	}

	public static void init() {
		try {
			ExceptionLog.InsertingExceptionHandleMethod();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void close() {
		removingExceptionHandleMethod();
	}
}

좋은 웹페이지 즐겨찾기