]
Eric Nielsen closed JASSIST-239.
--------------------------------
Resolution: Done
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?