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

Replacing a method call to a private static function of an outer class from within an inner class leads to NoSuchMethodError #479

Open
SamuelMotal opened this issue Jan 5, 2024 · 0 comments

Comments

@SamuelMotal
Copy link

Hello,
I think I encountered a bug in Javassist.
The problem is reproducable with the following code snippet:

package org.example;




public class TestClass{

    static {
        System.out.println("static block 1");
    }

    static {
        System.out.println("static block 2");
    }

    enum TEST{
        TEST1,TEST2,TEST3;
    }

    private final int x;
    private final int y;
    public TestClass(){
        super();
        x=10;
        y=10;
    }

    private static void print(){
        System.out.println("hello");
    }
    public void run() {
        TEST t = TEST.TEST1;

        switch (t){
            case TEST1:
                System.out.println("test1");
                break;
            case TEST2:
                System.out.println("test2");
                break;
            case TEST3:
                System.out.println("test3");
                break;
            default:
                throw new RuntimeException("error");
        }
        new MyInnerClass().isX0();
    }

    private class MyInnerClass {
        private final int x;

        private MyInnerClass(){
            x=0;
        }

        public boolean isX0(){
            print();
            return x==0;
        }
    }

}

If in the given example code the method call to print() within MyInnerClass is replaced via the use of ExpressionEditor it leads reproduceable to a NoSuchMethodError when running the code afterwards. An Exception will look like this:

java.lang.NoSuchMethodError: 'void jforecaster.testData.TestClass.access$1()'
	at jforecaster.testData.TestClass$MyInnerClass.isX0(TestClass.java:56)
	at jforecaster.testData.TestClass.run(TestClass.java:45)
	at jforecaster.testData.CoverageTest.test_coverage(CoverageTest.java:10)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.junit.runners.Suite.runChild(Suite.java:128)
	at org.junit.runners.Suite.runChild(Suite.java:27)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:105)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:94)
	at jforecaster.codeCoverage.RunWithCoverage.main(RunWithCoverage.java:25)

To replace the method call the following logic was used:

        final String statement=  newStatement+"{$_= $proceed($$);}";
        @Override
	public void edit(final MethodCall e) throws CannotCompileException {
	    	e.replace(statement);
	}

JDK: 17
Javassist: 3.30.2-GA

Please let me know if you can reproduce this error, if I did do something wrong, or if you need additional information which of course I am happy to provide if possible.

Kind regards,
Samuel

P.S. Thanks a lot for the great library you provide!

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