[jboss-jira] [JBoss JIRA] (JASSIST-239) javassist.CannotCompileException: [source error] Method m is private

Eric Nielsen (JIRA) issues at jboss.org
Mon Dec 15 16:54:29 EST 2014


Eric Nielsen created JASSIST-239:
------------------------------------

             Summary: javassist.CannotCompileException: [source error] Method m is private
                 Key: JASSIST-239
                 URL: https://issues.jboss.org/browse/JASSIST-239
             Project: Javassist
          Issue Type: Enhancement
    Affects Versions: 3.18.2-GA
            Reporter: Eric Nielsen
            Assignee: Shigeru Chiba


Given these classes:

{code}
public abstract class A {
    public static void m() {
        return m(aClass());
    }
    private static void m(Class<? extends A> aClass) {
        // some logic here
    }
    private static Class<? extends A> aClass() {
        // some logic here, subclasses will have own implementation
    }
}

public class B extends A {
}
{code}

I'm writing instrumentation for subclasses of {{A}} (like {{B}} above). The code is something like:
{code}
// source is class A, target is subclass of A
private void instrument(CtClass source, CtClass target) 
        throws NotFoundException, CannotCompileException {
    CtMethod[] sourceMethods = source.getDeclaredMethods();
    for (CtMethod method : sourceMethods) {
        int modifiers = method.getModifiers();
        if (Modifier.isStatic(modifiers)) {
            CtMethod newMethod;
            if (Modifier.isPublic(modifiers) 
                    || Modifier.isProtected(modifiers)) {
                newMethod = CtNewMethod.copy(method, target, null);
                StringBuilder body = new StringBuilder().append("{ ");
                if (!CtClass.voidType.equals(method.getReturnType())) {
                    body.append("return ");
                }
                body.append(method.getName()).append("(aClass()");
                if (method.getParameterTypes().length > 0) {
                    body.append(", $$");
                }
                body.append("); }");
                newMethod.setBody(body.toString());
            } else if ("aClass".equals(method.getName())) {
                newMethod = CtNewMethod.copy(method, target, null);
                newMethod.setBody("{ return " 
                        + target.getName() + ".class; }");
            } else {
                newMethod = CtNewMethod.delegator(method, target);
            }
            // include the generic signature
            for (Object attr : method.getMethodInfo().getAttributes()) {
                if (attr instanceof SignatureAttribute) {
                    newMethod.getMethodInfo().addAttribute(
                            (SignatureAttribute) attr);
                }
            }
            target.addMethod(newMethod);
        }
    }
}
{code}

I want to achieve the result below with the instrumentation:

{code}
public class B extends A {
    public static void m() {
        return m(aClass()); // a copy of superclass code
    }
    private static void m(Class<? extends A> aClass) {
        super.m(aClass); // delegates to superclass
    }
    private static Class<? extends A> aClass() {
        return B.class; // returns this class
    }
}
{code}

So when calling {{B.m()}}, the logic in the {{m(Class)}} superclass method will run receiving {{B.class}} as parameter.

When running instrumentation, I get the following error message:

{code}
javassist.CannotCompileException: [source error] Method m is private
{code}

What's wrong?






--
This message was sent by Atlassian JIRA
(v6.3.11#6341)


More information about the jboss-jira mailing list