例如有个类使用了java.lang.reflect.Proxy类,怎么调试这个类,只需要看里面的变量就可以了。
或者也可以使用其它办法,只要可以单步调试,例如我自己想了下面的办法:
写了一个跟java.lang.reflect.Proxy类代码一样的类,只是包名改为了proxy.Proxy,但是很奇怪的是,如果使用java.lang.reflect.Proxy类,程序是完全正常了,如果换为我写的proxy.Proxy类就报如下异常:
Exception in thread "main" java.lang.UnsatisfiedLinkError: defineClass0
at proxy.Proxy.defineClass0(Native Method)
at proxy.Proxy.getProxyClass(Proxy.java:509)
at proxy.Proxy.newProxyInstance(Proxy.java:586)
at proxy.MyInvocationHandler.main(MyInvocationHandler.java:23)
是不是类库中类加载到了虚拟机,也自写的类没有就报如上的异常,应该怎么解决。
下面是全部的程序:接口类Mammal 
package proxy;public interface Mammal {
  public void eat(String aa);
  String say();
}
实现接口类Monkey 
package proxy;public class Monkey implements Mammal {
public void eat(String aa) {
System.out.println("monkey eat" + aa);
}
final public String say() {
return "gua,gua";
}
public void byb() {
System.out.println("哈哈");
}
}InvocationHandler类
package proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
//import java.lang.reflect.Proxy; 如果这里不注释掉,使用类库的类,是可以运行的,现在我使用自写的Proxy类就报错public class MyInvocationHandler implements InvocationHandler {
private Object obj; public MyInvocationHandler(Object obj) {
this.obj = obj;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("Invoke method Before!");
Object returnObject = method.invoke(obj, args);
System.out.println("Invoke method After!");
return returnObject;
}

public static void main(String[] args) {
Object proxy = Proxy.newProxyInstance(Monkey.class.getClassLoader(),
 Monkey.class.getInterfaces(), new MyInvocationHandler(
new Monkey()));
Class<?> proxyClass = Proxy.getProxyClass(
Monkey.class.getClassLoader(),
Monkey.class.getInterfaces());

Mammal mammal = (Mammal) proxy;
mammal.eat("香蕉");

}
}Proxy类,代码跟java.lang.reflect.Proxy是一样的,只是改了包名。package proxy;import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;import sun.misc.ProxyGenerator;public class Proxy implements java.io.Serializable {    private static final long serialVersionUID = -2222568056686623797L;    private final static String proxyClassNamePrefix = "$Proxy";    private final static Class[] constructorParams =
{ InvocationHandler.class };    private static Map loaderToCache = new WeakHashMap();    private static Object pendingGenerationMarker = new Object();    private static long nextUniqueNumber = 0;
    private static Object nextUniqueNumberLock = new Object();    private static Map proxyClasses =
Collections.synchronizedMap(new WeakHashMap());    protected InvocationHandler h;    /**
     * Prohibits instantiation.
     */
    private Proxy() {
    }    protected Proxy(InvocationHandler h) {
this.h = h;
    }    public static Class<?> getProxyClass(ClassLoader loader, 
                                         Class<?>... interfaces)
throws IllegalArgumentException
    {
if (interfaces.length > 65535) {
    throw new IllegalArgumentException("interface limit exceeded");
} Class proxyClass = null; String[] interfaceNames = new String[interfaces.length]; Set interfaceSet = new HashSet(); for (int i = 0; i < interfaces.length; i++) {     String interfaceName = interfaces[i].getName();
    Class interfaceClass = null;
    try {
interfaceClass = Class.forName(interfaceName, false, loader);
    } catch (ClassNotFoundException e) {
    }
    if (interfaceClass != interfaces[i]) {
throw new IllegalArgumentException(
    interfaces[i] + " is not visible from class loader");
    }     if (!interfaceClass.isInterface()) {
throw new IllegalArgumentException(
    interfaceClass.getName() + " is not an interface");
    }
    if (interfaceSet.contains(interfaceClass)) {
throw new IllegalArgumentException(
    "repeated interface: " + interfaceClass.getName());
    }
    interfaceSet.add(interfaceClass);     interfaceNames[i] = interfaceName;
} Object key = Arrays.asList(interfaceNames);
Map cache;
synchronized (loaderToCache) {
    cache = (Map) loaderToCache.get(loader);
    if (cache == null) {
cache = new HashMap();
loaderToCache.put(loader, cache);
    }
} synchronized (cache) {
    do {
Object value = cache.get(key);
if (value instanceof Reference) {
    proxyClass = (Class) ((Reference) value).get();
}
if (proxyClass != null) {
    return proxyClass;
} else if (value == pendingGenerationMarker) {
    try {
cache.wait();
    } catch (InterruptedException e) {
    }
    continue;
} else {
    cache.put(key, pendingGenerationMarker);
    break;
}
    } while (true);
} try {
    String proxyPkg = null;
    for (int i = 0; i < interfaces.length; i++) {
int flags = interfaces[i].getModifiers();
if (!Modifier.isPublic(flags)) {
    String name = interfaces[i].getName();
    int n = name.lastIndexOf('.');
    String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
    if (proxyPkg == null) {
proxyPkg = pkg;
    } else if (!pkg.equals(proxyPkg)) {
throw new IllegalArgumentException(
    "non-public interfaces from different packages");
    }
}
    }     if (proxyPkg == null) {
proxyPkg = ""; // use the unnamed package
    }     {
long num;
synchronized (nextUniqueNumberLock) {
    num = nextUniqueNumber++;
}
String proxyName = proxyPkg + proxyClassNamePrefix + num;
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
    proxyName, interfaces);
try {
    proxyClass = defineClass0(loader, proxyName,
proxyClassFile, 0, proxyClassFile.length);
} catch (ClassFormatError e) {
    throw new IllegalArgumentException(e.toString());
}
    }
    proxyClasses.put(proxyClass, null); } finally {
    synchronized (cache) {
if (proxyClass != null) {
    cache.put(key, new WeakReference(proxyClass));
} else {
    cache.remove(key);
}
cache.notifyAll();
    }
}
return proxyClass;
    }        public static Object newProxyInstance(ClassLoader loader,
  Class<?>[] interfaces,
  InvocationHandler h)
throws IllegalArgumentException
    {
if (h == null) {
    throw new NullPointerException();
}
Class cl = getProxyClass(loader, interfaces);
try {
    Constructor cons = cl.getConstructor(constructorParams);
    return (Object) cons.newInstance(new Object[] { h });
} catch (NoSuchMethodException e) {
    throw new InternalError(e.toString());
} catch (IllegalAccessException e) {
    throw new InternalError(e.toString());
} catch (InstantiationException e) {
    throw new InternalError(e.toString());
} catch (InvocationTargetException e) {
    throw new InternalError(e.toString());
}
    }        public static boolean isProxyClass(Class<?> cl) {
if (cl == null) {
    throw new NullPointerException();
} return proxyClasses.containsKey(cl);
    }       public static InvocationHandler getInvocationHandler(Object proxy)
throws IllegalArgumentException
    { if (!isProxyClass(proxy.getClass())) {
    throw new IllegalArgumentException("not a proxy instance");
} Proxy p = (Proxy) proxy;
return p.h;
    }
    private static native Class defineClass0(ClassLoader loader, String name,
     byte[] b, int off, int len);
}
大家帮忙看看,为什么会报错,怎么调试类库中的类。

解决方案 »

  1.   

    楼主试试把jdk安装文件夹中的src.zip解压到项目的src下,debug时应该就能走到那了。
    eclipse似乎有源码定位的设置,就不用这么麻烦了。
      

  2.   

    补充一下:
    更改到jdk目录,即可以如愿跟进jdk的核心类。路径:preferences-->java-->install jre
    我本机myeclipse6.5ga可以正常跟进。
      

  3.   

    楼主试试把jdk安装文件夹中的src.zip解压到项目的src下,debug时应该就能走到那了。我设置后,老是调试出.class的文件,它不走java文件.更改到jdk目录,即可以如愿跟进jdk的核心类。路径:preferences-->java-->install jre 
    你是说installed jres 界面里面ADD jdk吗,这个我也增加了,请详细指点一下,谢谢!
      

  4.   

    eclipse或者是myeclipse不是可以关联代码么 ,你debug,单步执行,走到相应的代码的时候你看debug的内容不就是了
      

  5.   

    debug的内容都是loader cannot be resolved之类的,你有没有具体调试过啊
      

  6.   

    Proxy类的代码不需要看,就是类库里的类,我只是例出来而已
      

  7.   

    可能是Java的安全机制引起的。
    java class loader的工作原理,去找找。