Since classes generated by dynamic proxies are loaded directly into memory in binary mode, there is no corresponding.class file generated, so if you want to view the code generated by dynamic proxies using a decompile tool, you need to handle it in a special way.

Plan a

Set the runtime variables to generate class files in the classpath directory

/ / dynamic proxy class is generated file System. The getProperties (), put (" sun. Misc. ProxyGenerator. SaveGeneratedFiles ", "true");Copy the code

The downside is that it only works with JDK dynamic proxies

Scheme 2

With ClassDump, you can dump all loaded classes in the JVM. ClassDump is stored in $JAVA_HOME/lib/sa-jdi.jar (note: the Windows JDK only has this tool since 1.7) and is executed directly from the command line.

E:\work\Test\bin> JPS # Default output to./ directory E:\work\Test\bin> java-classpath. ./bin; %JAVA_HOME%/lib/sa-jdi.jar" sun.jvm.hotspot.tools.jcore.ClassDump <PID>Copy the code
// Import the sa-jdi.jar package to implement the ClassFilter interface. Public class MyFilter implements ClassFilter{@override public Boolean canInclude(InstanceKlass arg0) { return arg0.getName().asString().startsWith("com/sun/proxy/$Proxy0"); }}Copy the code
E:\work\Test\bin> java-classpath ". ./bin; %JAVA_HOME%/lib/sa-jdi.jar" -Dsun.jvm.hotspot.tools.jcore.filter=proxy.MyFilter -Dsun.jvm.hotspot.tools.jcore.outputDir=e:/dump sun.jvm.hotspot.tools.jcore.ClassDump <PID>Copy the code

This solution is based on the JVM layer ClassDump, so it can support javassist, Cglib, asm dynamically generated classes.

Finally, post the decompiled JDK dynamic proxy code

package com.sun.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.UndeclaredThrowableException; import proxy.Run; Public final class $Proxy0 extends Proxy implements Run {private static Method m1; private static Method m3; private static Method m0; private static Method m2; public $Proxy0(InvocationHandler paramInvocationHandler) { super(paramInvocationHandler); } static { try { m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") }); M3 = class.forname (" proxy.run ").getMethod(" Run", new Class[0]); m3 = class.forname (" proxy.run "). m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]); m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]); return; } catch (NoSuchMethodException localNoSuchMethodException) { throw new NoSuchMethodError(localNoSuchMethodException.getMessage()); } catch (ClassNotFoundException localClassNotFoundException) { throw new NoClassDefFoundError(localClassNotFoundException.getMessage()); }} public final String Run () {try {//this.h is an implementation of the InvocationHandler class. Return (String)this.h.invoke(this, m3, null); } catch (Error|RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final boolean equals(Object paramObject) { try { return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue(); } catch (Error|RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final String toString() { try { return (String)this.h.invoke(this, m2, null); } catch (Error|RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final int hashCode() { try { return ((Integer)this.h.invoke(this, m0, null)).intValue(); } catch (Error|RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); }}}Copy the code

reference

rednaxelafx.iteye.com/blog/727938

This article was first published on my blog: monkeywie.cn. Share the knowledge of JAVA, Golang, front-end, Docker, K8S and other dry goods from time to time.