例如有个类使用了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);
}
大家帮忙看看,为什么会报错,怎么调试类库中的类。
或者也可以使用其它办法,只要可以单步调试,例如我自己想了下面的办法:
写了一个跟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);
}
大家帮忙看看,为什么会报错,怎么调试类库中的类。
eclipse似乎有源码定位的设置,就不用这么麻烦了。
更改到jdk目录,即可以如愿跟进jdk的核心类。路径:preferences-->java-->install jre
我本机myeclipse6.5ga可以正常跟进。
你是说installed jres 界面里面ADD jdk吗,这个我也增加了,请详细指点一下,谢谢!
java class loader的工作原理,去找找。