public class Example {
public void run ( String name ) {
try {
Thread . sleep ( 5 ) ;
System . out . println ( "Currennt time is " + new Date ( System . currentTimeMillis ( ) ) ) ;
} catch ( InterruptedException e ) {
e . printStackTrace ( ) ;
}
System . out . println ( name ) ;
}
}
public class Test extends Example {
@Override
public void run ( String name ) {
long l = System . currentTimeMillis ( ) ;
super . run ( name ) ;
System . out . println ( ( System . currentTimeMillis ( ) - l ) ) ;
}
}
ClassWriter cw = new ClassWriter ( ClassWriter . COMPUTE_MAXS ) ;
cw . visit ( Opcodes . V1_5 , Opcodes . ACC_PUBLIC , "org/Test" , null , "org/example/Example" , null ) ;
cw . visitField ( Opcodes . ACC_PRIVATE , "name" , "Ljava/lang/String;" , null , null ) . visitEnd ( ) ;
MethodVisitor methodVisitor = cw . visitMethod ( Opcodes . ACC_PUBLIC , "<init>" , "()V" , null , null ) ;
methodVisitor . visitCode ( ) ;
methodVisitor . visitVarInsn ( Opcodes . ALOAD , 0 ) ;
methodVisitor . visitMethodInsn ( Opcodes . INVOKESPECIAL , "org/example/Example" , "<init>" , "()V" ) ;
methodVisitor . visitInsn ( Opcodes . RETURN ) ;
methodVisitor . visitMaxs ( 1 , 1 ) ;
methodVisitor . visitEnd ( ) ;
methodVisitor = cw . visitMethod ( Opcodes . ACC_PUBLIC , "run" , "(Ljava/lang/String;)V" , null , null ) ;
methodVisitor . visitCode ( ) ;
methodVisitor . visitMethodInsn ( Opcodes . INVOKESTATIC , "java/lang/System" , "currentTimeMillis" , "()J" ) ;
methodVisitor . visitVarInsn ( Opcodes . LSTORE , 2 ) ;
methodVisitor . visitVarInsn ( Opcodes . ALOAD , 0 ) ;
methodVisitor . visitVarInsn ( Opcodes . ALOAD , 1 ) ;
methodVisitor . visitMethodInsn ( Opcodes . INVOKESPECIAL , "org/example/Example" , "run" , "(Ljava/lang/String;)V" ) ;
methodVisitor . visitFieldInsn ( Opcodes . GETSTATIC , "java/lang/System" , "out" , "Ljava/io/PrintStream;" ) ;
methodVisitor . visitMethodInsn ( Opcodes . INVOKESTATIC , "java/lang/System" , "currentTimeMillis" , "()J" ) ;
methodVisitor . visitVarInsn ( Opcodes . LLOAD , 2 ) ;
methodVisitor . visitInsn ( Opcodes . LSUB ) ;
methodVisitor . visitMethodInsn ( Opcodes . INVOKEVIRTUAL , "java/io/PrintStream" , "println" , "(J)V" ) ;
methodVisitor . visitInsn ( Opcodes . RETURN ) ;
methodVisitor . visitMaxs ( 5 , 4 ) ;
methodVisitor . visitEnd ( ) ;
cw . visitEnd ( ) ;
return cw . toByteArray ( ) ;
class MyClassLoader extends ClassLoader {
public Class defineClass ( String name , byte [ ] b ) {
return defineClass ( name , b , 0 , b . length ) ;
}
}
MyClassLoader myClassLoader = new MyClassLoader ( ) ;
Class bClass = myClassLoader . defineClass ( "org.Test" , Generator . getBytecodeForClass ( ) ) ;
Constructor constructor = bClass . getConstructor ( ) ;
Object o = constructor . newInstance ( ) ;
Example e = ( Example ) o ;
e . run ( "test" ) ;
ClassReader cr = new ClassReader ( "org.example.Example" ) ;
ClassWriter cw = new ClassWriter ( cr , ClassWriter . COMPUTE_MAXS ) ;
ClassVisitor cv = new ReplaceStaticMethodClassAdapter ( cw ) ;
cr . accept ( cv , ClassReader . SKIP_DEBUG | ClassReader . SKIP_FRAMES ) ;
return cw . toByteArray ( ) ;
//----------------------------------------------------------------------------
private static class ReplaceStaticMethodClassAdapter extends ClassAdapter {
public RepaleStaticMethodClassAdapter ( ClassVisitor classVisitor ) {
super ( classVisitor ) ;
}
@Override
public MethodVisitor visitMethod ( int i , String s , String s1 , String s2 , String [ ] strings ) {
return new RepalceStaticMethodAdapter ( super . visitMethod ( i , s , s1 , s2 , strings ) ) ;
}
private class RepalceStaticMethodAdapter extends MethodAdapter {
public RepalceStaticMethodAdapter ( MethodVisitor methodVisitor ) {
super ( methodVisitor ) ;
}
@Override
public void visitMethodInsn ( int i , String s , String s1 , String s2 ) {
if ( i = = Opcodes . INVOKESTATIC & & "java/lang/System" .equals ( s ) & & "currentTimeMillis" .equals ( s1 ) & & "()J" .equals ( s2 ) ) {
super . visitMethodInsn ( Opcodes . INVOKESTATIC , "org/example/Generator" , "myTime" , "()J" ) ;
} else {
super . visitMethodInsn ( i , s , s1 , s2 ) ;
}
}
}
}
MyClassLoader myClassLoader = new MyClassLoader ( ) ;
Class aClass = myClassLoader . defineClass ( "org.example.Example" , Generator . getModifedClass ( ) ) ;
Constructor constructor = aClass . getConstructor ( ) ;
Object o = constructor . newInstance ( ) ;
Method method = aClass . getMethod ( "run" , String . class ) ;
method . invoke ( o , "test" ) ;
Source: https://habr.com/ru/post/72409/
All Articles