Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The proxy class EnhancerByCGLIB constructors have wrong Exception table #189

Open
hengyunabc opened this issue Feb 23, 2021 · 0 comments
Open

Comments

@hengyunabc
Copy link

demo

public class Hello {
    public Hello() {
        try {
            this.getClass().getMethods()[0].invoke(null);
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }
}

javap -v Hello.class result:

  public Hello();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=3, locals=2, args_size=1
         0: aload_0
         1: invokespecial #8                  // Method java/lang/Object."<init>":()V
         4: aload_0
         5: invokevirtual #10                 // Method java/lang/Object.getClass:()Ljava/lang/Class;
         8: invokevirtual #14                 // Method java/lang/Class.getMethods:()[Ljava/lang/reflect/Method;
        11: iconst_0
        12: aaload
        13: aconst_null
        14: iconst_0
        15: anewarray     #3                  // class java/lang/Object
        18: invokevirtual #20                 // Method java/lang/reflect/Method.invoke:(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
        21: pop
        22: goto          30
        25: astore_1
        26: aload_1
        27: invokevirtual #26                 // Method java/lang/Throwable.printStackTrace:()V
        30: return
      Exception table:
         from    to  target type
             4    22    25   Class java/lang/Throwable

Exception table star from 4.

cglib demo

public class CglibDemo implements MethodInterceptor {

    public static <T> T newInstance(Class<T> clazz) {
        try {
            CglibDemo interceptor = new CglibDemo();
            Enhancer e = new Enhancer();

            UndeclaredThrowableStrategy ss = new UndeclaredThrowableStrategy(
                    java.lang.reflect.UndeclaredThrowableException.class);
            e.setStrategy(ss);
            e.setSuperclass(clazz);
            e.setCallback(interceptor);
            return (T) e.create();
        } catch (Throwable e) {
            e.printStackTrace();
            throw new Error(e.getMessage());
        }
    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.err.println("xxx");
        return null;
    }

    public static class Person {

        public Person() {
            System.err.println("xxx");
        }

        public String getName() {
            return "Hans Hansen";
        }

        public boolean isEmployee() {
            return true;
        }
    }

    public static void main(String[] args) throws IOException {
        Person callsToPersonRegistrant = newInstance(Person.class);
        System.in.read();
    }

}

Use arthas dump command to dump cglib class:

./as.sh --select CglibDemo
[arthas@83698]$ dump CglibDemo$Person$$EnhancerByCGLIB*
 HASHCODE  CLASSLOADER                                    LOCATION
 2a139a55  +-sun.misc.Launcher$AppClassLoader@2a139a55    /Users/hengyunabc/logs/arthas/classdump/sun.misc.Launcher$AppClassLoader-2a139a55/CglibDemo$Person$$EnhancerByCGLIB$$
             +-sun.misc.Launcher$ExtClassLoader@6c819144  49b2ccd2.class

The cglib proxy class star from 0:

  public CglibDemo$Person$$EnhancerByCGLIB$$49b2ccd2();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=3, locals=1, args_size=1
         0: aload_0
         1: dup
         2: invokespecial #200                // Method CglibDemo$Person."<init>":()V
         5: invokestatic  #44                 // Method CGLIB$BIND_CALLBACKS:(Ljava/lang/Object;)V
         8: return
         9: athrow
        10: new           #66                 // class java/lang/reflect/UndeclaredThrowableException
        13: dup_x1
        14: swap
        15: invokespecial #69                 // Method java/lang/reflect/UndeclaredThrowableException."<init>":(Ljava/lang/Throwable;)V
        18: athrow
      Exception table:
         from    to  target type
             0     9     9   Class java/lang/RuntimeException
             0     9     9   Class java/lang/Error
             0     9    10   Class java/lang/Throwable

The CglibDemo works in cglib 3.2.12, error in cglib 3.3.0:

java.lang.IllegalStateException: Unable to load cache item
	at net.sf.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:79)
	at net.sf.cglib.core.internal.LoadingCache.get(LoadingCache.java:34)
	at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:119)
	at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:294)
	at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:480)
	at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:305)
	at CglibDemo2.newInstance(CglibDemo2.java:22)
	at CglibDemo2.main(CglibDemo2.java:51)
Caused by: java.lang.VerifyError: Stack map does not match the one at exception handler 9
Exception Details:
  Location:
    CglibDemo2$Person$$EnhancerByCGLIB$$21a4f41d.<init>()V @9: athrow
  Reason:
    Current frame's flags are not assignable to stack map frame's.
  Current Frame:
    bci: @0
    flags: { flagThisUninit }
    locals: { uninitializedThis }
    stack: { 'java/lang/RuntimeException' }
  Stackmap Frame:
    bci: @9
    flags: { }
    locals: { }
    stack: { 'java/lang/Throwable' }
  Bytecode:
    0x0000000: 2a59 b700 c6b8 002c b1bf bb00 425a 5fb7
    0x0000010: 0045 bf                                
  Exception Handler Table:
    bci [0, 9] => handler: 9
    bci [0, 9] => handler: 9
    bci [0, 9] => handler: 10
  Stackmap Table:
    full_frame(@9,{},{Object[#64]})
    same_locals_1_stack_item_frame(@10,Object[#64])

	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:348)
	at net.sf.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:467)
	at net.sf.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:339)
	at net.sf.cglib.proxy.Enhancer.generate(Enhancer.java:492)
	at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:96)
	at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:94)
	at net.sf.cglib.core.internal.LoadingCache$2.call(LoadingCache.java:54)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at net.sf.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:61)
	... 7 more
Exception in thread "main" java.lang.Error: Unable to load cache item
	at CglibDemo2.newInstance(CglibDemo2.java:25)
	at CglibDemo2.main(CglibDemo2.java:51)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant