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

Private non-static method can not debug and get "this" field #111

Open
924060929 opened this issue Feb 15, 2020 · 1 comment
Open

Private non-static method can not debug and get "this" field #111

924060929 opened this issue Feb 15, 2020 · 1 comment

Comments

@924060929
Copy link

the code is

class MyTest {
  private int value = 10;
  private void test() {
    System.out.println(value);
  }
}

When I generate the code by Janino and copy the code to a file MyTest.java,and step into the test function,I can't look the variable this and value in Intellij IDEA.

Then I debug the Janino 3.0.0,and find the logical in UnitCompiler#compile(FunctionDeclarator, ClassFile) is change the private non-static method to package static method, and add the "this" to the method's first argument.

"This" in IDEA is this object, but in Janino is the first augument, this cause the problem.

Can U support this debug function :)

@aunkrig
Copy link
Member

aunkrig commented Feb 26, 2020

Hey Mrs. or Mr. Anonymous,

modeling non-static private methods with static default-accessible methods is a trick of JANINO:

    if (fd.getAccess() == Access.PRIVATE) {
        if (fd instanceof MethodDeclarator && !((MethodDeclarator) fd).isStatic()) {

            // To make the non-static private method invocable for enclosing types, enclosed types and types
            // enclosed by the same type, it is modified as follows:
            //  + Access is changed from PRIVATE to PACKAGE
            //  + The name is appended with "$"
            //  + It is made static
            //  + A parameter of type "declaring class" is prepended to the signature
            short accessFlags = UnitCompiler.changeAccessibility(this.accessFlags(fd.getModifiers()), Mod.PACKAGE);
            accessFlags |= Mod.STATIC;

            mi = classFile.addMethodInfo(
                accessFlags,   // accessFlags
                fd.name + '$', // methodName
                (              // methodMd
                    this.toIMethod((MethodDeclarator) fd)
                    .getDescriptor()
                    .prependParameter(this.resolve(fd.getDeclaringType()).getDescriptor())
                )
            );

It is not enough to change accessibility from PRIVATE to PACKAGE, because PRIVATE-accessible methods are non-virtual, and PACKAGE-accessible methods are not.

Sorry it breaks IDEA!

The idea behind this is to avoid those ridiculous "access$000()" methods that Java generates to make private methods accessible for enclosing and enclosed classes. A very questionable concept anyway, because it pollutes the generated classes, the call stacks, and also adds security vulnerabilities.

But I see your point and will think of a way to get around this problem. Stay tuned.

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

2 participants