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_TACT=105AGX02&S_CMP=EDU

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#4222922

Reply to the post : 
http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=4222922
_______________________________________________
jboss-user mailing list
jboss-user@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/jboss-user

Reply via email to