jboss-javassist / javassist

Java bytecode engineering toolkit
www.javassist.org
Other
4.11k stars 700 forks source link

Different behaviors against lambda expressions #76

Open SaeedMasoumi opened 8 years ago

SaeedMasoumi commented 8 years ago

I want to injecting a class to another class. I tried to convert this class to a CtClass and find foo CtMethod and insert it to another CtClass

public class Template{
   void foo(){
           Runnable r = () -> {
            System.out.println("Hello world two!");
        };
   }
}

So it works properly.

But If I move r declaration to field statement , javassist throws CannotCompileException

public class Template{
           Runnable r = () -> {
            System.out.println("Hello world two!");
        }; 
}

So why this happens?

chibash commented 8 years ago

What did you actual do for moving r?

SaeedMasoumi commented 8 years ago

I didn't do anything, it's a plain java class. I mean If i have a class like second Template class and do something like this.

CtClass template = pool.get(Template.class.getName());
CtClass anotherClass= pool.get(AnotherClass.class.getName());
anotherClass.addField(template.getField("r"));
anotherClass.writeFile();

It will throw:

javassist.CannotCompileException: cannot add
    at javassist.CtClassType.addField(CtClassType.java:1283)
    at javassist.CtClass.addField(CtClass.java:1089)
chibash commented 8 years ago

No, you cannot add a CtField created for another class. Please read the javadoc of CtClass.addField(). Maybe you should write:

CtClass runnable = pool.get(..);
anotherClass.addField(new CtField(runnable, "r", anotherClass), "Template.bar()");

bar() is a static method in Template:

public class Template{
    public static Runnable bar() {
           Runnable r = () -> {
            System.out.println("Hello world two!");
           }; 
           return r;
    }
}