Dear all,
I'm using javassist to generate access class for reflection, following this tutorial:
http://www.ibm.com/developerworks/java/library/j-dyn0610/index.html?S_TAC...
Everything works fine with my version, but it is not working with field without
getter/setter. I need my generated access class to be able to access field directly in
some case.
So I wrote the following piece of code:
| ....
| protected static byte[] createAccess(final Class targetJavaClass, final String field,
final String generatedClassName)
| throws Exception {
|
| //... code to get read/write method
|
| String targetName = targetJavaClass.getName();
| ClassPool pool = ClassPool.getDefault();
| CtClass accessClass = pool.makeClass(generatedClassName);
| CtClass targetClass = pool.get(targetName);
| final CtClass ctFieldClass = pool.get("java.lang.Object");
| final CtClass[] ctFieldClassParam = new CtClass[]{ctFieldClass};
| CtMethod meth;
|
| // add target object field to class
| accessClass.addField(new CtField(targetClass, "target",
accessClass));
|
| // add public default constructor method to class
| CtConstructor cons = new CtConstructor(CT_NO_ARGS, accessClass);
| cons.setBody(";");
| accessClass.addConstructor(cons);
|
| // add public <code>setTarget</code> method
| meth = new CtMethod(CtClass.voidType, "setTarget",
ctFieldClassParam, accessClass);
| meth.setBody("target = (" + targetJavaClass.getName() + ")
$1;");
| accessClass.addMethod(meth);
|
|
| String src;
|
| // add public <code>setValue</code> method
| meth = new CtMethod(CtClass.voidType, "setValue", ctFieldClassParam,
accessClass);
| final Class<?> fieldType = writer.getParameterTypes()[0];
| String cast$1 = "(" + fieldType.getName() + ") $1";
| if(directWriteField) src = "target." + field + " = " +
" $1;";
| else src = "target." + writer.getName() + "(" + cast$1 +
");";
| meth.setBody(src);
| accessClass.addMethod(meth);
|
| // add public <code>getValue</code> method
| meth = new CtMethod(ctFieldClass, "getValue", CT_NO_ARGS,
accessClass);
| if(directReadField) src = field;
| else src = reader.getName() + "()";
| meth.setBody("return (java.lang.Object) target." + src +
";");
| accessClass.addMethod(meth);
|
| // return binary representation of completed class
| accessClass.addInterface(pool.get(IAccess.class.getName()));
| accessClass.writeFile();
| return accessClass.toBytecode();
| }
| ...
|
Execution of this code throws an exception after class generation, when calling
newInstance on it:
| java.lang.VerifyError: (class:
Accessor$com/bnpparibas/eqd/fish/fwk/introspection/TestCachedIntrospectionInfo$SampleBean_secret,
method: setValue signature: (Ljava/lang/Object;)V) Bad type in
| putfield/putstatic
| at java.lang.Class.getDeclaredConstructors0(Native Method)
| at java.lang.Class.privateGetDeclaredConstructors(Class.java:2357)
| at java.lang.Class.getConstructor0(Class.java:2671)
| at java.lang.Class.newInstance0(Class.java:321)
| at java.lang.Class.newInstance(Class.java:303)
|
The part of the code responsible of this is the following part of code:
| f(directWriteField) src = "target." + field + " = " + "
$1;";
|
If I remove this line, there are no error.
Here is the decompiled code of the faulty generated class:
| package Accessor$com.bnpparibas.eqd.fish.fwk.introspection;
|
| import com.bnpparibas.eqd.fish.fwk.introspection.IAccess;
| import com.bnpparibas.eqd.fish.fwk.introspection.SampleBean;
|
| public class SampleBean_directAccessField
| implements IAccess {
|
| SampleBean target = null;
|
| public SampleBean_directAccessField() {
| }
|
| public void setTarget(Object obj) {
| target = (SampleBean)obj;
| }
|
| public void setValue(Object obj) {
| target.directAccessField = ((java.util.Date) (obj));
| }
|
| public Object getValue() {
| return (Object)target.directAccessField;
| }
| }
|
And the directAccesField of the target object is a java.util.Date.
I've spend to much time on this problem and I can't figure what the problem is.
Thanks for any help you can provide.
Regards.
K.
View the original post :
http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4222922#...
Reply to the post :
http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&a...