您的位置:首页 > 移动开发 > Objective-C

object is not an instance of dec…

2015-12-24 10:29 357 查看
 
package com.lrq.framework;

import java.io.ByteArrayOutputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.IOException;

import java.lang.reflect.Method;

import java.util.Map;

import java.util.concurrent.ConcurrentHashMap;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.lrq.annotation.Controller;

import com.lrq.annotation.RequestMapping;

import com.lrq.loader.MyClassLoader;

public class DispatcherServlet extends HttpServlet {

private Map<String, Object> beans = new ConcurrentHashMap<String, Object>();

//  射路径和方法的匹配;这个记得要去重复;

private Map<String, String> urlMapping = new ConcurrentHashMap<String, String>();

@Override

public void init() throws ServletException {

// 获取到字节 文件对象的路径,并找到对应的.class文件;

// 这需要用到递归的思想, 想啊, 怎么知道下面有没有路径呢?

String realPath = this.getServletContext().getRealPath(

"/WEB-INF/classes");

File file = new File(realPath);

try {

this.treeWalk(file);

} catch (Exception e) {

throw new RuntimeException(e);

}

}

private void treeWalk(File file) throws Exception {

if (file.isDirectory()) {

// 如果存在并且是一个目录,就获取该目录下的所有东东

File[] listFiles = file.listFiles();

for (File file2 : listFiles) {

treeWalk(file2);

}

} else {

if (file.exists()) {

// 判断是否是.class文件开头的;判断是否需要更 严谨;

if (file.getName().endsWith(".class")) {

// 创建文件读取流读取;

FileInputStream fileStream = new FileInputStream(file);

byte[] buf = new byte[1024];

ByteArrayOutputStream byteOut = new ByteArrayOutputStream();

int len = 0;

while ((len = fileStream.read(buf)) != -1) {

byteOut.write(buf, 0, len);

}

MyClassLoader loader = new MyClassLoader(this.getClass()

.getClassLoader());// 这个父类装载器,挂到装载器 上;

// 这个类 载器的双亲委托 载机制有关;

byte[] byteArray = byteOut.toByteArray();

Class<?> clazz = loader.loadClass(null, byteArray, 0,

byteArray.length);

Controller controller = clazz

.getAnnotation(Controller.class);

if (controller != null) {

beans.put(controller.value(), clazz.newInstance());

Method[] methods = clazz.getMethods();

if (methods != null && methods.length > 0) {

for (Method method : methods) {

RequestMapping requestMapping = method

.getAnnotation(RequestMapping.class);

if (requestMapping != null) {

// 匹配路径;

String value = requestMapping.value();

String actionMethod = clazz.getName() + "+"

+ method.getName();

urlMapping.put(value, actionMethod);

}

}

}

}

}

}

}

}

@SuppressWarnings({ "unchecked", "rawtypes" })

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

// 解析uri; heima/login.action

String uri = request.getRequestURI();

uri = uri.substring(uri.lastIndexOf("/") + 1).replace(".do", "");

String urlValue = this.urlMapping.get(uri);

if (urlValue != null && urlValue.length() > 0) {

String[] urlValues = urlValue.split("[+]");

String className = urlValues[0];

String methodName = urlValues[1];

String simpleClassName = className.substring(className

.lastIndexOf(".") + 1);

try {

} catch (Exception e) {

throw new RuntimeException(e);

}

}

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doGet(request, response);

}

}

注意里面带颜色的代码:

1 我的Object
object对象是由自定义的类装载器装载的;

2
class.forname对象是由tomcat服务器的webappclassloader进行加载的;

而我尝试着用webappclassloader的类装载器加载的字节码文件对象去获取他身上的method对象,然后调用method.invoke(object);

这个object对象是由另外一个类装载器装载的字节码文件对象创建的实例,这样肯定就会出问题;

这是我这个异常的根源

或者说一个字节码对象的唯一性有三部分确定:相同虚拟机+相同类加载器+相同的完整类名



转发至微博
 



转发至微博
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: