vendredi 2 décembre 2016

How to instanciate a class created at runtime with javassist?

I've just started to use javassist and I can't seem to figure out how to instantiate a class made at runtime.

The makeNewClass() method makes the NewClass class like that:

public bin.objetos.base.NewClass {
    public int quantity = 5;
    private float weight = 30.25f;

    public float getWeight() { return weight; }
    public void setWeight(float weight) { this.weight = weight; }
    public float totalWeight() { return quantity * getWeight(); }
}

This method works just fine:

public void makeNewClass() throws NotFoundException, IOException, CannotCompileException {
        // ClassMaker maker holds the CtClass object and handles all the "making"
        ClassMaker maker = new ClassMaker("bin.objetos.base.NewClass");

        maker.addField(CtClass.intType, "quantity", "5", Modifier.PUBLIC);
        maker.addField(CtClass.floatType, "weight", "30.25f", Modifier.PRIVATE);

        maker.addMethod(Modifier.PUBLIC, CtClass.floatType, "totalWeight", null, null, 
                "{ return quantidade * getPeso(); }", null, MethodType.standard);
        maker.getCtClass().writeFile();
    }

Now begins the problem. This method is supposed to instantiate the NewClass, access it's fields e call it's methods.

    public void testNewClass() 
            throws Throwable {
        CtClass ctclass =  ClassPool.getDefault().get("bin.objetos.base.NovaClasse");

        Object testClass = ctclass.toClass(new Loader(), null);

        // Throws NoSuchFieldException
        Field q = testClass .getClass().getDeclaredField("quantity");
        int quantidade = (int) q.get(testClass);

        Class[] cArg = new Class[1];
        cArg[0] = Float.class;

        // Throws NoSuchMethodException
        Method m = testClass.getClass().getDeclaredMethod("getWeight", cArg);
        float weight = (float) m.invoke(testClass, null);

        // Throws NoSuchMethodException
        m = testClass.getClass().getDeclaredMethod("pesoTotal", cArg);
        float totalWeight = (float) m.invoke(testClass, null);

        System.out.println("quantity = " + quantity +
                "weight = " + weight +
                "totalWeight = " + totalWeight);
    }

Now, I already figured out that testClass it's actually initialized as an instance of java.lang.Class, not bin.objetos.base.NewClass. So, obviously, it will not find the fields and methods of NewClass.

The question is how do I solve that? I tried using the java.lang.Class.cast() method, but had no success.





Aucun commentaire:

Enregistrer un commentaire