[jboss-cvs] JBossAS SVN: r104720 - in projects/jboss-reflect/trunk: src/main/java/org/jboss/reflect/plugins/javassist/bytecode and 1 other directory.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Wed May 12 07:01:34 EDT 2010


Author: kabir.khan at jboss.com
Date: 2010-05-12 07:01:32 -0400 (Wed, 12 May 2010)
New Revision: 104720

Added:
   projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/ClassFileWriterContext.java
   projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/ErrorCheckingMemberFactory.java
Modified:
   projects/jboss-reflect/trunk/pom.xml
   projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/JavassistBehaviorFactory.java
   projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/JavassistConstructorFactory.java
   projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/JavassistFieldFactory.java
   projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/JavassistMemberFactory.java
   projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/JavassistMethodFactory.java
   projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/SecurityActions.java
Log:
[JBREFLECT-122] Make JavassistMemberFactory use the new javassist.bytecode.ClassFileWriter API when creating classes

Modified: projects/jboss-reflect/trunk/pom.xml
===================================================================
--- projects/jboss-reflect/trunk/pom.xml	2010-05-12 10:45:48 UTC (rev 104719)
+++ projects/jboss-reflect/trunk/pom.xml	2010-05-12 11:01:32 UTC (rev 104720)
@@ -21,7 +21,7 @@
     <version.jboss.common.core>2.2.17.GA</version.jboss.common.core>
     <version.jboss.logging.spi>2.2.0.CR1</version.jboss.logging.spi>
     <version.jboss.logging.log4j>2.2.0.CR1</version.jboss.logging.log4j>
-    <version.javassist>3.12.0.GA</version.javassist>
+    <version.javassist>3.12.1-SNAPSHOT</version.javassist>
     <version.org.jboss.test>1.1.5.GA</version.org.jboss.test>
     <version.junit>4.8.1</version.junit>
     <version.jboss.profiler.jvmti>1.0.0.CR5</version.jboss.profiler.jvmti>

Added: projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/ClassFileWriterContext.java
===================================================================
--- projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/ClassFileWriterContext.java	                        (rev 0)
+++ projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/ClassFileWriterContext.java	2010-05-12 11:01:32 UTC (rev 104720)
@@ -0,0 +1,415 @@
+/*
+* JBoss, Home of Professional Open Source.
+* Copyright 2006, Red Hat Middleware LLC, and individual contributors
+* as indicated by the @author tags. See the copyright.txt file in the
+* distribution for a full listing of individual contributors. 
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/ 
+package org.jboss.reflect.plugins.javassist.bytecode;
+
+import java.lang.reflect.InvocationTargetException;
+import java.security.ProtectionDomain;
+
+import javassist.CtClass;
+import javassist.Modifier;
+import javassist.bytecode.Bytecode;
+import javassist.bytecode.ClassFile;
+import javassist.bytecode.ClassFileWriter;
+import javassist.bytecode.Descriptor;
+import javassist.bytecode.MethodInfo;
+import javassist.bytecode.Opcode;
+import javassist.bytecode.ClassFileWriter.ConstPoolWriter;
+import javassist.bytecode.ClassFileWriter.MethodWriter;
+
+/**
+ * Wrapper around the {@link ClassFileWriter} with some utility methods
+ * 
+ * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
+ * @version $Revision: 1.1 $
+ */
+class ClassFileWriterContext<T>
+{
+   private static final java.lang.reflect.Method defineClass1, defineClass2;
+
+   static {
+       try {
+           Class<?> cl = Class.forName("java.lang.ClassLoader");
+           defineClass1 = SecurityActions.getDeclaredMethod(
+                       cl,
+                       "defineClass",
+                       new Class[] { String.class, byte[].class,
+                                     int.class, int.class });
+
+           defineClass2 = SecurityActions.getDeclaredMethod(
+                       cl,
+                       "defineClass",
+                       new Class[] { String.class, byte[].class,
+                             int.class, int.class, ProtectionDomain.class });
+       }
+       catch (Exception e) {
+           throw new RuntimeException("cannot initialize");
+       }
+       
+       SecurityActions.setAccessible(defineClass1);
+       SecurityActions.setAccessible(defineClass2);
+   }
+   
+   /** The class of the interface we are implementing */
+   final Class<T> type;
+   
+   /** The name of the class we are creating */
+   final String name;
+   
+   /** The underlying class file writer */
+   final ClassFileWriter fileWriter;
+   
+   /** The underlying class pool writer */
+   final ConstPoolWriter poolWriter;
+   
+   /** This class's name index in the const pool */
+   final int thisClass;
+
+   /** This class's superclass name index in the const pool */
+   final int superClass;
+   
+   /** The interfaces */
+   final int[] interfaces;
+   
+   /** The method writer for the methods */
+   final MethodWriter mw;
+   
+   /** The created bytes */
+   byte[] bytes;
+   
+   int stackDepth;
+   
+   int maxStackDepth;
+   
+   ClassFileWriterContext(String name, String superClassName, Class<T> type, String[] interfaceNames)
+   {
+      this.name = name;
+      this.type = type;
+      
+      //FIXME Once we get rid of the old ClassFile stuff we should make the real names look like this 
+      //to start with
+      name = ClassFileWriterContext.jvmClassName(name);
+      superClassName = ClassFileWriterContext.jvmClassName(superClassName);
+      for (int i = 0 ; i < interfaceNames.length ; i++)
+         interfaceNames[i] = ClassFileWriterContext.jvmClassName(interfaceNames[i]);
+      
+      fileWriter = new ClassFileWriter(ClassFile.JAVA_4, 0);
+      poolWriter = fileWriter.getConstPool();
+      thisClass = poolWriter.addClassInfo(name);
+      superClass = poolWriter.addClassInfo(superClassName);
+      interfaces = poolWriter.addClassInfo(interfaceNames);
+      
+      //Add default constructor
+      mw = fileWriter.getMethodWriter();
+      mw.begin(Modifier.PUBLIC, MethodInfo.nameInit, "()V",  null, null);
+      mw.add(Opcode.ALOAD_0);
+      mw.add(Opcode.INVOKESPECIAL);
+      int signature = poolWriter.addNameAndTypeInfo(MethodInfo.nameInit, "()V");
+      mw.add16(poolWriter.addMethodrefInfo(superClass, signature));
+      mw.add(Opcode.RETURN);
+      mw.codeEnd(1, 1);
+      mw.end(null, null);
+   }
+
+   String getSimpleType()
+   {
+      return type.getSimpleName();
+   }
+   
+   String getName()
+   {
+      return name;
+   }
+   
+   void beginMethod(int accessFlags, String name, String descriptor, String[] exceptions) 
+   {
+      mw.begin(Modifier.PUBLIC, name, descriptor, exceptions, null);
+   }
+   
+   void endMethod(int maxLocals)
+   {
+      mw.codeEnd(maxStackDepth, maxLocals);
+      mw.end(null, null);
+   }
+   
+   void addInvokeStatic(String targetClass, String methodName, String descriptor)
+   {
+      mw.addInvoke(Opcode.INVOKESTATIC, targetClass, methodName, descriptor);
+      
+      //Stolen from Bytecode.addInvokestatic()
+      growStack(Descriptor.dataSize(descriptor));   
+   }
+
+   void addInvokeVirtual(String targetClass, String methodName, String descriptor)
+   {
+      mw.addInvoke(Opcode.INVOKEVIRTUAL, targetClass, methodName, descriptor);
+
+      //Stolen from Bytecode.addInvokevirtual()
+      growStack(Descriptor.dataSize(descriptor) - 1);
+   }
+
+   void addInvokeInterface(String targetClass, String methodName, String descriptor, int count)
+   {
+      mw.addInvoke(Opcode.INVOKEINTERFACE, targetClass, methodName, descriptor);
+      mw.add(count);
+      mw.add(0);
+
+      //Stolen from Bytecode.addInvokeinterface()
+      growStack(Descriptor.dataSize(descriptor) - 1);
+   }
+   
+   void addInvokeSpecial(String targetClass, String methodName, String descriptor)
+   {
+      mw.addInvoke(Opcode.INVOKESPECIAL, targetClass, methodName, descriptor);         
+
+      //Stolen from Bytecode.addInvokespecial()
+      growStack(Descriptor.dataSize(descriptor) - 1);
+   }
+
+   void addGetField(String className, String fieldName, String type)
+   {
+      mw.add(Opcode.GETFIELD);
+      addFieldRefInfo(className, fieldName, type);
+      
+      //Stolen from Bytecode.addGetfield()
+      growStack(Descriptor.dataSize(type) - 1);
+   }
+   
+   void addGetStatic(String className, String fieldName, String type)
+   {
+      mw.add(Opcode.GETSTATIC);
+      addFieldRefInfo(className, fieldName, type);
+
+      //Stolen from Bytecode.addGetstatic()
+      growStack(Descriptor.dataSize(type));   
+   }
+   
+   void addPutField(String className, String fieldName, String type)
+   {
+      mw.add(Opcode.PUTFIELD);
+      addFieldRefInfo(className, fieldName, type);
+      
+      //Stolen from Bytecode.addPutfield()
+      growStack(1 - Descriptor.dataSize(type));
+   }
+   
+   void addPutStatic(String className, String fieldName, String type)
+   {
+      mw.add(Opcode.PUTSTATIC);
+      addFieldRefInfo(className, fieldName, type);
+
+      //Stolen from Bytecode.addPutStatic()
+      growStack(-Descriptor.dataSize(type));
+   }
+   
+   void addAReturn()
+   {
+      mw.add(Opcode.ARETURN);
+      
+      //From Opcode.STACK_GROW[] (see test in main())
+      growStack(-1);
+   }
+   
+   void addAConstNull()
+   {
+      mw.add(Opcode.ACONST_NULL);
+
+      //From Opcode.STACK_GROW[] (see test in main())
+      growStack(1);
+   }
+   
+   void addAALoad()
+   {
+      mw.add(Opcode.AALOAD);
+
+      //From Opcode.STACK_GROW[] (see test in main())
+      growStack(-1);
+   }
+   
+   /**
+    * Adds the right bytecode to call ALOAD depending on the 
+    * number of the parameter
+    * 
+    * @param i the number of the parameter
+    * @see Bytecode#addAload(int)
+    */
+   void addAload(int i)
+   {
+      if (i < 4)
+         mw.add(Opcode.ALOAD_0 + i);
+      else if (i < 0x100) 
+      {
+         mw.add(Opcode.ALOAD);           // aload
+         mw.add(i);
+      }
+      else 
+      {
+         mw.add(Opcode.WIDE);
+         mw.add(Opcode.ALOAD);
+         addIndex(i);
+     }
+      //From Opcode.STACK_GROW[] (see test in main())
+      growStack(1);
+   }
+   
+   /**
+    * Adds the right bytecode to load a constant depending on the
+    * size of the constant
+    * 
+    * @param i the number
+    * @see Bytecode#addIconst(int);
+    */
+   void addIconst(int i)
+   {
+      if (i < 6 && -2 < i)
+         mw.add(Opcode.ICONST_0 + i);           // iconst_<i>   -1..5
+      else if (i <= 127 && -128 <= i) {
+         mw.add(Opcode.BIPUSH);              // bipush
+         mw.add(i);
+      }
+      else if (i <= 32767 && -32768 <= i) 
+      {
+         mw.add(Opcode.SIPUSH);              // sipush
+            mw.add(i >> 8);
+            mw.add(i);
+      }
+      else
+      {
+         int ref = poolWriter.addIntegerInfo(i);
+
+         if (i > 0xFF)
+         {
+            mw.add(Opcode.LDC_W);
+            mw.add(i >> 8);
+            mw.add(i);
+         }
+         else
+         {
+            mw.add(Opcode.LDC);
+            mw.add(ref);
+         }
+      }
+      //From Opcode.STACK_GROW[] (see test in main())
+      growStack(1);
+   }
+      
+   void addNew(String className)
+   {
+      mw.add(Opcode.NEW);
+      addIndex(addClassInfo(className));
+      
+      //From Opcode.STACK_GROW[] (see test in main())
+      growStack(1);
+   }
+
+   void addDup()
+   {
+      mw.add(Opcode.DUP);
+      
+      //From Opcode.STACK_GROW[] (see test in main())
+      growStack(1);
+   }
+
+   void addCheckcast(String clazz)
+   {
+      mw.add(Opcode.CHECKCAST);
+      int i = poolWriter.addClassInfo(clazz);
+      addIndex(i);
+
+      //From Opcode.STACK_GROW[] (see test in main())
+      //No change to stack
+   }
+
+   byte[] getBytes()
+   {
+      if (bytes == null)
+         bytes = fileWriter.end(Modifier.PUBLIC, thisClass, superClass, interfaces, null);
+      return bytes;
+   }
+
+   Class<T> toClass(ClassLoader loader, ProtectionDomain domain) throws InvocationTargetException, IllegalAccessException
+   {
+      byte[] bytes = getBytes();
+      if (domain == null)
+         return (Class<T>) SecurityActions.invoke(defineClass1, loader, name, bytes, Integer.valueOf(0), Integer.valueOf(bytes.length));
+      else
+         return (Class<T>) SecurityActions.invoke(defineClass2, loader, name, bytes, Integer.valueOf(0), Integer.valueOf(bytes.length), domain);
+   }
+   
+   private void addIndex(int i)
+   {
+      mw.add(i >> 8);
+      mw.add(i);
+   }
+
+   private void addFieldRefInfo(String className, String fieldName, String type)
+   {
+      addIndex(poolWriter.addFieldrefInfo(poolWriter.addClassInfo(className), poolWriter.addNameAndTypeInfo(fieldName, type)));
+   }
+
+   private int addClassInfo(String className)
+   {
+      return poolWriter.addClassInfo(className.replace('.', '/'));
+   }
+  
+   private void growStack(int i)
+   {
+      stackDepth += i;
+      if (stackDepth > maxStackDepth)
+         maxStackDepth = stackDepth;
+   }
+   
+   static String jvmClassName(CtClass clazz)
+   {
+      return ClassFileWriterContext.jvmClassName(clazz.getName());
+   }
+
+   static String jvmClassName(String name)
+   {
+      return name.replace('.', '/');
+   }
+
+   public static void main (String[] args)
+   {
+      System.out.println("  Opcode.INVOKESTATIC   \t" + Opcode.STACK_GROW[ Opcode.INVOKESTATIC ]);
+      System.out.println("  Opcode.INVOKEVIRTUAL  \t" + Opcode.STACK_GROW[ Opcode.INVOKEVIRTUAL ]);
+      System.out.println("  Opcode.INVOKEINTERFACE\t" + Opcode.STACK_GROW[ Opcode.INVOKEINTERFACE ]);
+      System.out.println("  Opcode.INVOKESPECIAL  \t" + Opcode.STACK_GROW[ Opcode.INVOKESPECIAL ]);
+      System.out.println("  Opcode.GETFIELD       \t" + Opcode.STACK_GROW[ Opcode.GETFIELD ]);
+      System.out.println("  Opcode.GETSTATIC      \t" + Opcode.STACK_GROW[ Opcode.GETSTATIC ]);
+      System.out.println("  Opcode.PUTFIELD       \t" + Opcode.STACK_GROW[ Opcode.PUTFIELD ]);
+      System.out.println("  Opcode.PUTSTATIC      \t" + Opcode.STACK_GROW[ Opcode.PUTSTATIC ]);
+      System.out.println("  Opcode.ARETURN        \t" + Opcode.STACK_GROW[ Opcode.ARETURN ]);
+      System.out.println("  Opcode.ACONST_NULL    \t" + Opcode.STACK_GROW[ Opcode.ACONST_NULL ]);
+      System.out.println("  Opcode.AALOAD         \t" + Opcode.STACK_GROW[ Opcode.AALOAD ]);
+      System.out.println("  Opcode.ALOAD_1        \t" + Opcode.STACK_GROW[ Opcode.ALOAD_1 ]);
+      System.out.println("  Opcode.ALOAD          \t" + Opcode.STACK_GROW[ Opcode.ALOAD ]);
+      System.out.println("  Opcode.WIDE           \t" + Opcode.STACK_GROW[ Opcode.WIDE ]);
+      System.out.println("  Opcode.NEW            \t" + Opcode.STACK_GROW[ Opcode.NEW ]);
+      System.out.println("  Opcode.DUP            \t" + Opcode.STACK_GROW[ Opcode.DUP ]);
+      System.out.println("  Opcode.CHECKCAST      \t" + Opcode.STACK_GROW[ Opcode.CHECKCAST ]);     
+      System.out.println("  Opcode.ICONST_1)      \t" + Opcode.STACK_GROW[ Opcode.ICONST_1 ]);
+      System.out.println("  Opcode.BIPUSH)        \t" + Opcode.STACK_GROW[ Opcode.BIPUSH ]);
+      System.out.println("  Opcode.SIPUSH)        \t" + Opcode.STACK_GROW[ Opcode.SIPUSH ]);
+      System.out.println("  Opcode.LDC_W)         \t" + Opcode.STACK_GROW[ Opcode.LDC_W ]);
+      System.out.println("  Opcode.LDC)           \t" + Opcode.STACK_GROW[ Opcode.LDC ]);
+   }
+ }

Added: projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/ErrorCheckingMemberFactory.java
===================================================================
--- projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/ErrorCheckingMemberFactory.java	                        (rev 0)
+++ projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/ErrorCheckingMemberFactory.java	2010-05-12 11:01:32 UTC (rev 104720)
@@ -0,0 +1,340 @@
+/*
+* JBoss, Home of Professional Open Source.
+* Copyright 2006, Red Hat Middleware LLC, and individual contributors
+* as indicated by the @author tags. See the copyright.txt file in the
+* distribution for a full listing of individual contributors. 
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/ 
+package org.jboss.reflect.plugins.javassist.bytecode;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import javassist.CtClass;
+import javassist.CtConstructor;
+import javassist.CtField;
+import javassist.CtMember;
+import javassist.CtMethod;
+import javassist.Modifier;
+import javassist.NotFoundException;
+
+import org.jboss.reflect.plugins.javassist.JavassistConstructor;
+import org.jboss.reflect.plugins.javassist.JavassistField;
+import org.jboss.reflect.plugins.javassist.JavassistMethod;
+import org.jboss.reflect.plugins.javassist.JavassistUtil;
+import org.jboss.util.Strings;
+
+/**
+ * Class to wrap the generated JavassistMethod, -Constructor and -Field 
+ * implementations with another implementation that checks the parameters
+ * if something went wrong when invoking
+ * 
+ * 
+ * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
+ * @version $Revision: 1.1 $
+ */
+class ErrorCheckingMemberFactory
+{
+   /**
+    * Wraps the generated JavassistMethod in an implementation that checks the 
+    * parameters
+    * 
+    * @param m The wrapped method
+    * @param method the target method for information about the parameters
+    * @return the error checking wrapper 
+    */
+   static JavassistMethod wrapInErrorChecker(JavassistMethod m, CtMethod method)
+   {
+      if (m == null || method == null)
+         throw new IllegalArgumentException("Null method");
+      
+      int numParameters = 0;
+      try
+      {
+         numParameters = method.getParameterTypes().length;
+      }
+      catch(NotFoundException e)
+      {
+         throw new IllegalArgumentException("Could not load the parameters for " + method);
+      }
+      
+      return new ErrorCheckingJavassistMethod(m, method, numParameters);
+   }
+   
+   /**
+    * Wraps the generated JavassistConstructor in an implementation that checks the 
+    * parameters
+    * 
+    * @param c The wrapped constructor
+    * @param constructor the target constructor for information about the parameters
+    * @return the error checking wrapper 
+    */
+   static JavassistConstructor wrapInErrorChecker(JavassistConstructor c, CtConstructor constructor)
+   {
+      if (c == null || constructor == null)
+         throw new IllegalArgumentException("Null constructor");
+      
+      int numParameters = 0;
+      try
+      {
+         numParameters = constructor.getParameterTypes().length;
+      }
+      catch(NotFoundException e)
+      {
+         throw new IllegalArgumentException("Could not load the parameters for " + constructor);
+      }
+      
+      return new ErrorCheckingJavassistConstructor(c, constructor, numParameters);
+   }
+   
+   /**
+    * Wraps the generated JavassistField in an implementation that checks the 
+    * parameters
+    * 
+    * @param f The wrapped field
+    * @param field the target field for information about the parameters
+    * @return the error checking wrapper 
+    */
+   static JavassistField wrapInErrorChecker(JavassistField f, CtField field)
+   {
+      if (f == null)
+         throw new IllegalArgumentException("Null field");
+      
+      return new ErrorCheckingJavassistField(f, field);
+   }
+   
+   private static boolean checkNumberOfParameters(Object[] args, int numParameters)
+   {
+      if (args == null && numParameters > 0)
+         return false;
+      if (args != null && args.length != numParameters)
+         return false;
+      return true;
+   }
+   
+   private static boolean isStatic(CtMember member)
+   {
+      return Modifier.isStatic(member.getModifiers());
+   }
+   
+   private static void handleWrongParameters(String context, String target, Class<?>[] expected, Object[] args)
+   {
+      List<String> actual = new ArrayList<String>();
+      if (args != null)
+      {
+         for (Object argument : args)
+         {
+            if (argument == null)
+               actual.add(null);
+            else
+               actual.add(argument.getClass().getName());
+         }
+      }
+      throw new IllegalArgumentException("Wrong arguments. " + context + " for target " + target + " expected=" + expected + " actual=" + actual);
+      
+   }
+
+   private static void handleWrongTarget(Object target, Class<?> expected, String name)
+   {
+      throw new IllegalArgumentException("Wrong target for " + name + " " + target.getClass().getName() + " is not a " + expected.getName());
+   }
+   
+   private static void handleNullTarget(AccessibleObject ao)
+   {
+      throw new IllegalArgumentException("Null target calling non-static " + ao);      
+   }
+   
+   private static class ErrorCheckingJavassistMethod extends ErrorCheckingMemberFactory implements JavassistMethod
+   {
+      private final JavassistMethod delegate;
+      private final CtMethod ctMethod;
+      private final int numParameters;
+      
+      private ErrorCheckingJavassistMethod(JavassistMethod delegate, CtMethod ctMethod, int numParameters)
+      {
+         this.delegate = delegate;
+         this.ctMethod = ctMethod;
+         this.numParameters = numParameters;
+      }
+
+      public Object invoke(Object target, Object[] args) throws Throwable
+      {
+         if (!checkNumberOfParameters(args, numParameters))
+            throw new IllegalArgumentException("Wrong number of parameters for " + ctMethod.getDeclaringClass() + "." + ctMethod.getName() + ctMethod.getSignature());
+         
+         try
+         {
+            return delegate.invoke(target, args);
+         }
+         catch(ClassCastException e)
+         {
+            Method method = JavassistUtil.ctMethodToMethod(ctMethod); 
+            if (!isStatic(ctMethod))
+            {
+               if (!method.getDeclaringClass().isAssignableFrom(target.getClass()))
+                  handleWrongTarget(target, method.getDeclaringClass(), method.getName());
+            }
+            
+            Class<?>[] params = method.getParameterTypes();
+            for (int i = 0 ; i < args.length ; i++)
+            {
+               if (!params[i].isAssignableFrom(args[i].getClass()))
+                  handleWrongParameters(method.getName(), Strings.defaultToString(target), method.getParameterTypes(), args);
+            }
+            
+            throw e;
+         }
+         catch(NullPointerException e)
+         {
+            Method method = JavassistUtil.ctMethodToMethod(ctMethod); 
+            if (!isStatic(ctMethod) && target == null)
+               handleNullTarget(method);
+            
+            CtClass[] parameters = ctMethod.getParameterTypes();
+            for (int i = 0 ; i < parameters.length ; i++)
+            {
+               if (parameters[i].isPrimitive() && args[i] == null)
+                  handleWrongParameters(method.getName(), Strings.defaultToString(target), method.getParameterTypes(), args);
+            }
+            
+            throw e;
+         }
+      }
+      
+   }
+
+   private static class ErrorCheckingJavassistConstructor extends ErrorCheckingMemberFactory implements JavassistConstructor
+   {
+      private final JavassistConstructor delegate;
+      private final CtConstructor ctConstructor;
+      private final int numParameters;
+      
+      private ErrorCheckingJavassistConstructor(JavassistConstructor delegate, CtConstructor ctConstructor, int numParameters)
+      {
+         this.delegate = delegate;
+         this.ctConstructor = ctConstructor;
+         this.numParameters = numParameters;
+      }
+
+      public Object newInstance(Object[] args) throws Throwable
+      {
+         if (!checkNumberOfParameters(args, numParameters))
+            throw new IllegalArgumentException("Wrong number of parameters for " + ctConstructor.getDeclaringClass() + "." + ctConstructor.getName() + ctConstructor.getSignature());
+         
+         try
+         {
+            return delegate.newInstance(args);
+         }
+         catch(ClassCastException e)
+         {
+            Constructor<?> constructor = JavassistUtil.ctConstructorToConstructor(ctConstructor);
+            Class<?>[] params = constructor.getParameterTypes();
+            for (int i = 0 ; i < args.length ; i++)
+            {
+               if (!params[i].isAssignableFrom(args[i].getClass()))
+                  handleWrongParameters("new", Strings.defaultToString(ctConstructor.getDeclaringClass().getName()), constructor.getParameterTypes(), args);
+            }
+               
+            throw e;
+         }
+         catch(NullPointerException e)
+         {
+            CtClass[] parameters = ctConstructor.getParameterTypes();
+            for (int i = 0 ; i < parameters.length ; i++)
+            {
+               if (parameters[i].isPrimitive() && args[i] == null)
+               {
+                  Constructor<?> constructor = JavassistUtil.ctConstructorToConstructor(ctConstructor);
+                  handleWrongParameters("new", Strings.defaultToString(ctConstructor.getDeclaringClass().getName()), constructor.getParameterTypes(), args);
+               }
+            }
+            
+            throw e;
+         }
+      }
+   }
+
+   private static class ErrorCheckingJavassistField extends ErrorCheckingMemberFactory implements JavassistField
+   {
+      private final JavassistField delegate;
+      private final CtField ctField;
+      
+      private ErrorCheckingJavassistField(JavassistField delegate, CtField ctField)
+      {
+         this.delegate = delegate;
+         this.ctField = ctField;
+      }
+
+      public Object get(Object target) throws Throwable
+      {
+         try
+         {
+            return delegate.get(target);
+         }
+         catch (ClassCastException e)
+         {
+            Field field = JavassistUtil.ctFieldToField(ctField);
+            
+            if (!isStatic(ctField) && !field.getDeclaringClass().isAssignableFrom(target.getClass()))
+               handleWrongTarget(target, field.getDeclaringClass(), field.getName());
+            
+            throw e;
+         }
+         catch(NullPointerException e)
+         {
+            Field field = JavassistUtil.ctFieldToField(ctField);
+            if (!isStatic(ctField) && target == null)
+               handleNullTarget(field);
+            throw e;
+         }
+      }
+
+      public void set(Object target, Object value) throws Throwable
+      {
+         try
+         {
+            delegate.set(target, value);
+         }
+         catch (ClassCastException e)
+         {
+            Field field = JavassistUtil.ctFieldToField(ctField);
+            Class<?> type = field.getType();
+
+            if (!isStatic(ctField) && !field.getDeclaringClass().isAssignableFrom(target.getClass()))
+               handleWrongTarget(target, field.getDeclaringClass(), field.getName());
+
+            if (!type.isAssignableFrom(value.getClass()))
+               throw new IllegalArgumentException("Wrong arguments. Setting " + field.getName() + " for target " + target + " expected=" + field.getType() + " actual=" + value.getClass());
+         }
+         catch(NullPointerException e)
+         {
+            Field field = JavassistUtil.ctFieldToField(ctField);
+            if (!isStatic(ctField) && target == null)
+               handleNullTarget(field);
+            if (ctField.getType().isPrimitive() && value == null)
+               throw new IllegalArgumentException("Null value setting non-static field. " + field);
+            throw e;
+         }
+      }
+   }
+   
+   
+}
\ No newline at end of file

Modified: projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/JavassistBehaviorFactory.java
===================================================================
--- projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/JavassistBehaviorFactory.java	2010-05-12 10:45:48 UTC (rev 104719)
+++ projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/JavassistBehaviorFactory.java	2010-05-12 11:01:32 UTC (rev 104720)
@@ -24,8 +24,6 @@
 import javassist.CtBehavior;
 import javassist.CtClass;
 import javassist.NotFoundException;
-import javassist.bytecode.Bytecode;
-import javassist.bytecode.Opcode;
 
 import org.jboss.reflect.plugins.javassist.JavassistConstructor;
 import org.jboss.reflect.plugins.javassist.JavassistMethod;
@@ -85,19 +83,21 @@
     * Adds the byte code to push the parameters for a method/constructor 
     * on to the stack
     * 
-    * @param code the byte code of the method we are generating
+    * @param cfwc the byte code of the method we are generating
     * @param params the target parameter types
+    * @param the index of the parameter array
     */
-   void addParameters(Bytecode code, CtClass[] params, int parameterIndex)
+   void addParameters(ClassFileWriterContext<?> cfwc, CtClass[] params, int parameterIndex)
    {
       for (int i = 0 ; i < params.length ; i++)
       {
-         code.addAload(parameterIndex);
-         code.addIconst(i);
-         code.addOpcode(Opcode.AALOAD);
+         cfwc.addAload(parameterIndex);
+         cfwc.addIconst(i);
+         cfwc.addAALoad();
+         
          if (!params[i].getName().equals(OBJECT_NAME))
          {
-            castAndUnbox(code, params[i]);
+            castAndUnbox(cfwc, params[i]);
          }
       }
    }

Modified: projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/JavassistConstructorFactory.java
===================================================================
--- projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/JavassistConstructorFactory.java	2010-05-12 10:45:48 UTC (rev 104719)
+++ projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/JavassistConstructorFactory.java	2010-05-12 11:01:32 UTC (rev 104720)
@@ -25,12 +25,7 @@
 
 import javassist.CtConstructor;
 import javassist.Modifier;
-import javassist.bytecode.Bytecode;
-import javassist.bytecode.CodeAttribute;
-import javassist.bytecode.ConstPool;
 import javassist.bytecode.MethodInfo;
-import javassist.bytecode.Opcode;
-import javassist.bytecode.StackMapTable;
 import javassist.util.proxy.RuntimeSupport;
 
 import org.jboss.reflect.plugins.javassist.JavassistConstructor;
@@ -51,11 +46,13 @@
    private static final String[] interfaceNames = new String[] {JavassistConstructor.class.getName()};
    
    /** The methods from the interface that are being implemented */ 
-   private static final Method[] methods;
+   private static final Method[] methods = new Method[1];
    
+   /** The descriptors for the methods */
+   private static final String[] methodDescriptors = new String[1];
+   
    static
    {
-      methods = new Method[1];
       try
       {
          methods[0] = SecurityActions.getDeclaredMethod(JavassistConstructor.class, "newInstance", Object[].class);
@@ -64,6 +61,7 @@
       {
          throw new RuntimeException(e);
       }
+      methodDescriptors[0] = RuntimeSupport.makeDescriptor(methods[0]); 
    }
 
    /** The constructor we are targeting */
@@ -85,51 +83,43 @@
       this.ctConstructor = ctConstructor;
    }
 
+   @Override
    String getGeneratedClassName()
    {
       return className;
    }
    
-
+   @Override
    String[] getInterfaceNames()
    {
       return interfaceNames;
    }
 
    @Override
-   MethodInfo implementMethod(int index, ConstPool cp)
+   boolean implementMethod(int index, ClassFileWriterContext<?> cfwc)
    {
       if (index >= methods.length)
-         return null;
+         return false;
 
       Method method = methods[index]; 
 
-      String desc = RuntimeSupport.makeDescriptor(method);
-      MethodInfo minfo = new MethodInfo(cp, method.getName(), desc);
-      minfo.setAccessFlags(Modifier.PUBLIC);
-      setThrows(minfo, cp, method.getExceptionTypes());
-      Bytecode code = new Bytecode(cp, 0, 0);
-      
-      int pc = code.currentPc();
-      
-      code.addNew(ctConstructor.getDeclaringClass().getName());
-      code.addOpcode(Opcode.DUP);
+      cfwc.beginMethod(Modifier.PUBLIC, method.getName(), methodDescriptors[index], THROWABLE_EXCEPTIONS);
 
-      addParameters(code, getParameterTypes(), 1);
+      cfwc.addNew(ClassFileWriterContext.jvmClassName(ctConstructor.getDeclaringClass()));
+      cfwc.addDup();
       
-      code.addInvokespecial(ctConstructor.getDeclaringClass(), "<init>", ctConstructor.getSignature());
-      code.addOpcode(Opcode.ARETURN);
+      addParameters(cfwc, getParameterTypes(), 1);
       
+      cfwc.addInvokeSpecial(ClassFileWriterContext.jvmClassName(ctConstructor.getDeclaringClass()), MethodInfo.nameInit, ctConstructor.getSignature());
+      cfwc.addAReturn();
+      
       //We need 3 local variable slots.
       //One for 'this', one for the target reference and one for the argument array.
-      //These are all object references and so take one slot each 
-      code.setMaxLocals(3);
-      CodeAttribute ca = code.toCodeAttribute();
-      minfo.setCodeAttribute(ca);
-
-      StackMapTable.Writer writer = new StackMapTable.Writer(32);
-      writer.sameFrame(pc);
-      ca.setAttribute(writer.toStackMapTable(cp));
-      return minfo;
+      //These are all object references and so take one slot each
+      
+      //TODO the max stack
+      cfwc.endMethod(3);
+      
+      return true;
    }
 }
\ No newline at end of file

Modified: projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/JavassistFieldFactory.java
===================================================================
--- projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/JavassistFieldFactory.java	2010-05-12 10:45:48 UTC (rev 104719)
+++ projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/JavassistFieldFactory.java	2010-05-12 11:01:32 UTC (rev 104720)
@@ -27,12 +27,6 @@
 import javassist.CtField;
 import javassist.Modifier;
 import javassist.NotFoundException;
-import javassist.bytecode.Bytecode;
-import javassist.bytecode.CodeAttribute;
-import javassist.bytecode.ConstPool;
-import javassist.bytecode.MethodInfo;
-import javassist.bytecode.Opcode;
-import javassist.bytecode.StackMapTable;
 import javassist.util.proxy.RuntimeSupport;
 
 import org.jboss.reflect.plugins.javassist.JavassistField;
@@ -54,7 +48,10 @@
    
    /** The methods from the interface that are being implemented */ 
    protected static final Method[] methods;
-   
+
+   /** The descriptors for the methods */
+   private static final String[] methodDescriptors = new String[2];
+
    static
    {
       interfaceNames = new String[] {JavassistField.class.getName()};
@@ -68,6 +65,9 @@
       {
          throw new RuntimeException(e);
       }
+      
+      methodDescriptors[0] = RuntimeSupport.makeDescriptor(methods[0]);
+      methodDescriptors[1] = RuntimeSupport.makeDescriptor(methods[1]);
    }
 
    /** The field we are targeting */
@@ -132,28 +132,25 @@
    }
 
    @Override
-   MethodInfo implementMethod(int index, ConstPool cp)
+   boolean implementMethod(int index, ClassFileWriterContext<?> cfwc)
    {
       if (index >= methods.length)
-         return null;
+         return false;
 
-      String desc = RuntimeSupport.makeDescriptor(methods[index]);
-      MethodInfo minfo = new MethodInfo(cp, methods[index].getName(), desc);
-      minfo.setAccessFlags(Modifier.PUBLIC);
-      setThrows(minfo, cp, methods[index].getExceptionTypes());
-      Bytecode code = new Bytecode(cp, 0, 0);
-      
-      int pc = code.currentPc();
+      Method method = methods[index]; 
+
+      cfwc.beginMethod(Modifier.PUBLIC, method.getName(), methodDescriptors[index], THROWABLE_EXCEPTIONS);
+
       boolean isStatic = Modifier.isStatic(ctField.getModifiers());
 
       int maxLocals = 0;
       if (index == 0)
       {
          //We need 2 local variable slots.
-         //One for 'this' and one for the target reference
+         //One for 'this' and one for the argument array
          //These are all object references and so take one slot each 
          maxLocals = 2;
-         makeGetMethod(code, methods[index], cp, isStatic);
+         makeGetMethod(cfwc, isStatic);
       }
       else
       {
@@ -161,59 +158,55 @@
          //One for 'this', one for the target reference and one for the argument array.
          //These are all object references and so take one slot each 
          maxLocals = 3;
-         makeSetMethod(code, methods[index], cp, isStatic);
+         makeSetMethod(cfwc, isStatic);
       }
-      
-      code.setMaxLocals(maxLocals);
-      CodeAttribute ca = code.toCodeAttribute();
-      minfo.setCodeAttribute(ca);
 
-      StackMapTable.Writer writer = new StackMapTable.Writer(32);
-      writer.sameFrame(pc);
-      ca.setAttribute(writer.toStackMapTable(cp));
-      return minfo;
+      cfwc.endMethod(maxLocals);
+      
+      return true;
    }
+
    
-   private void makeGetMethod(Bytecode code, Method method, ConstPool cp, boolean isStatic)
+   private void makeGetMethod(ClassFileWriterContext<?> cfwc, boolean isStatic)
    {
       if (isStatic)
       {
-         code.addGetstatic(ctField.getDeclaringClass().getName(), ctField.getName(), ctField.getSignature());
+         cfwc.addGetStatic(ClassFileWriterContext.jvmClassName(ctField.getDeclaringClass()), ctField.getName(), ctField.getSignature());
       }
       else
       {
+         String targetClassName = ClassFileWriterContext.jvmClassName(ctField.getDeclaringClass());
          //push and cast the target object
-         code.addAload(1);
-         code.addCheckcast(ctField.getDeclaringClass());
-         code.addGetfield(ctField.getDeclaringClass(), ctField.getName(), ctField.getSignature());
+         cfwc.addAload(1);
+         cfwc.addCheckcast(targetClassName);
+         cfwc.addGetField(targetClassName, ctField.getName(), ctField.getSignature());
       }
-      boxReturnValue(code, getFieldType());
-      code.addOpcode(Opcode.ARETURN);
-         
+      boxReturnValue(cfwc, getFieldType());
+      cfwc.addAReturn();
    }
    
-   private void makeSetMethod(Bytecode code, Method method, ConstPool cp, boolean isStatic)
+   private void makeSetMethod(ClassFileWriterContext<?> cfwc, boolean isStatic)
    {
       if (!isStatic)
       {
          //push and cast the target object
-         code.addAload(1);
-         code.addCheckcast(ctField.getDeclaringClass());
+         cfwc.addAload(1);
+         cfwc.addCheckcast(ClassFileWriterContext.jvmClassName(ctField.getDeclaringClass()));
       }
 
       //push and cast the value
-      code.addAload(2);
-      castAndUnbox(code, getFieldType());
+      cfwc.addAload(2);
+      castAndUnbox(cfwc, getFieldType());
       
       if (isStatic)
       {
-         code.addPutstatic(ctField.getDeclaringClass().getName(), ctField.getName(), ctField.getSignature());
+         cfwc.addPutStatic(ClassFileWriterContext.jvmClassName(ctField.getDeclaringClass()), ctField.getName(), ctField.getSignature());
       }
       else
       {
-         code.addPutfield(ctField.getDeclaringClass(), ctField.getName(), ctField.getSignature());
+         cfwc.addPutField(ClassFileWriterContext.jvmClassName(ctField.getDeclaringClass()), ctField.getName(), ctField.getSignature());
       }
 
-      code.addOpcode(Opcode.RETURN);
+      cfwc.addAReturn();
    }
 }
\ No newline at end of file

Modified: projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/JavassistMemberFactory.java
===================================================================
--- projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/JavassistMemberFactory.java	2010-05-12 10:45:48 UTC (rev 104719)
+++ projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/JavassistMemberFactory.java	2010-05-12 11:01:32 UTC (rev 104720)
@@ -21,50 +21,30 @@
 */ 
 package org.jboss.reflect.plugins.javassist.bytecode;
 
-import java.io.DataOutputStream;
+import java.io.BufferedOutputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
-import java.util.ArrayList;
+import java.security.ProtectionDomain;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import javassist.CannotCompileException;
 import javassist.CtClass;
 import javassist.CtConstructor;
 import javassist.CtField;
-import javassist.CtMember;
 import javassist.CtMethod;
-import javassist.Modifier;
-import javassist.NotFoundException;
-import javassist.bytecode.AccessFlag;
-import javassist.bytecode.Bytecode;
-import javassist.bytecode.ClassFile;
-import javassist.bytecode.CodeAttribute;
-import javassist.bytecode.ConstPool;
 import javassist.bytecode.Descriptor;
 import javassist.bytecode.DuplicateMemberException;
-import javassist.bytecode.ExceptionsAttribute;
-import javassist.bytecode.MethodInfo;
-import javassist.bytecode.Opcode;
-import javassist.bytecode.StackMapTable;
-import javassist.util.proxy.FactoryHelper;
 import javassist.util.proxy.RuntimeSupport;
 
 import org.jboss.reflect.plugins.javassist.JavassistConstructor;
 import org.jboss.reflect.plugins.javassist.JavassistField;
 import org.jboss.reflect.plugins.javassist.JavassistMethod;
-import org.jboss.reflect.plugins.javassist.JavassistUtil;
-import org.jboss.util.Strings;
 import org.jboss.util.UnreachableStatementException;
 
 /**
@@ -80,38 +60,33 @@
  */
 public abstract class JavassistMemberFactory
 {
+   /** Object class name */
    protected static final String OBJECT_NAME = Object.class.getName();
 
-   protected static final String ILLEGAL_ARGUMENT_EXCEPTION_NAME = IllegalArgumentException.class.getName();
+   /** The jvm class name of Short */
+   private static final String SHORT_NAME = ClassFileWriterContext.jvmClassName(Short.class.getName());
 
-   private static final String SHORT_NAME = Short.class.getName();
+   /** The jvm class name of Long */
+   private static final String LONG_NAME = ClassFileWriterContext.jvmClassName(Long.class.getName());
 
-   private static final String LONG_NAME = Long.class.getName();
+   /** The jvm class name of Integer */
+   private static final String INTEGER_NAME = ClassFileWriterContext.jvmClassName(Integer.class.getName());
 
-   private static final String INTEGER_NAME = Integer.class.getName();
+   /** The jvm class name of Float */
+   private static final String FLOAT_NAME = ClassFileWriterContext.jvmClassName(Float.class.getName());
 
-   private static final String FLOAT_NAME = Float.class.getName();
+   /** The jvm class name of Double */
+   private static final String DOUBLE_NAME = ClassFileWriterContext.jvmClassName(Double.class.getName());
 
-   private static final String DOUBLE_NAME = Double.class.getName();
+   /** The jvm class name of Character */
+   private static final String CHARACTER_NAME = ClassFileWriterContext.jvmClassName(Character.class.getName());
 
-   private static final String CHARACTER_NAME = Character.class.getName();
+   /** The jvm class name of Byte */
+   protected static final String BYTE_NAME = ClassFileWriterContext.jvmClassName(Byte.class.getName());
 
-   protected static final String BYTE_NAME = Byte.class.getName();
+   /** The jvm class name of Boolean */
+   protected static final String BOOLEAN_NAME = ClassFileWriterContext.jvmClassName(Boolean.class.getName());
 
-   protected static final String BOOLEAN_NAME = Boolean.class.getName();
-
-   /** Descriptor for new IllegalArgumentException(String) */
-   protected static final String ILLEGAL_ARGUMENT_EXCEPTION_CONSTRUCTOR_DESCRIPTOR = RuntimeSupport.makeDescriptor(new Class<?>[] {String.class}, Void.TYPE);
-
-   /** Descriptor for StringBuilder.toString() */
-   protected static final String STRINGBUILDER_TOSTRING_DESCRIPTOR = RuntimeSupport.makeDescriptor(new Class<?>[0], String.class);
-
-   /** Descriptor for StringBuilder.append(Object) */
-   protected static final String STRINGBUILDER_APPEND_DESCRIPTOR = RuntimeSupport.makeDescriptor(new Class<?>[] {Object.class}, StringBuilder.class);
-
-   /** Descriptor for new StringBuilder(String) */
-   protected static final String STRINGBUILDER_CONSTRUCTOR_DESCRIPTOR = RuntimeSupport.makeDescriptor(new Class[]{String.class}, Void.TYPE);
-
    /** Descriptor for Boolean.booleanValue() */
    private final static String BOOLEAN_VALUE_DESCRIPTOR = RuntimeSupport.makeDescriptor(new Class[0], Boolean.TYPE);
    
@@ -159,6 +134,9 @@
 
    /** Descriptor for Short.valueOf */
    private final static String SHORT_VALUE_OF_DESCRIPTOR = RuntimeSupport.makeDescriptor(new Class[] {Short.TYPE}, Short.class);
+
+   /** Array of exceptions containing jvm name of Throwable */
+   protected final static String[] THROWABLE_EXCEPTIONS = new String[] {"java/lang/Throwable"};
    
    /** The method class counter */
    protected static final AtomicInteger counter = new AtomicInteger(0);
@@ -227,7 +205,7 @@
    {
       JavassistMemberFactory factory = new JavassistMethodFactory(superClass, ctMethod, debug);
       Class<JavassistMethod> member = factory.makeClass(JavassistMethod.class, ctMethod.getDeclaringClass());
-      return wrapInErrorChecker(factory.instantiate(member), ctMethod);
+      return ErrorCheckingMemberFactory.wrapInErrorChecker(factory.instantiate(member), ctMethod);
    }
 
    /**
@@ -243,7 +221,7 @@
    {
       JavassistMemberFactory factory = new JavassistConstructorFactory(superClass, ctConstructor, debug);
       Class<JavassistConstructor> member = factory.makeClass(JavassistConstructor.class, ctConstructor.getDeclaringClass());
-      return wrapInErrorChecker(factory.instantiate(member), ctConstructor);
+      return ErrorCheckingMemberFactory.wrapInErrorChecker(factory.instantiate(member), ctConstructor);
    }
 
    /**
@@ -259,7 +237,7 @@
    {
       JavassistMemberFactory factory = new JavassistFieldFactory(superClass, ctField, debug);
       Class<JavassistField> member = factory.makeClass(JavassistField.class, ctField.getDeclaringClass());
-      return wrapInErrorChecker(factory.instantiate(member), ctField);
+      return ErrorCheckingMemberFactory.wrapInErrorChecker(factory.instantiate(member), ctField);
    }
 
    /**
@@ -291,20 +269,21 @@
    protected <T> Class<T> makeClass(Class<T> expected, CtClass target)
    {
       //Create a new public class
-      final ClassFile cf = new ClassFile(false, getGeneratedClassName(), superClass.getName());
-      cf.setAccessFlags(AccessFlag.PUBLIC);
-      cf.setInterfaces(getInterfaceNames());
+      String name = getGeneratedClassName();
+      final ClassFileWriterContext<T> cfwc = new ClassFileWriterContext<T>(name, superClass.getName(), expected, getInterfaceNames());
 
       try
       {
-         //Add the constructors from the super class 
-         makeConstructors(cf);
-   
          //implement the methods from the interfaces
-         implementMethods(cf);
-   
+         implementMethods(cfwc);
+         
+         
          if (debug)
-            debugWriteFile(cf);
+         {
+            debugWriteFile(cfwc);
+         }
+         
+         
       }
       catch(Exception e)
       {
@@ -316,51 +295,51 @@
       if (cl == null)
          cl = SecurityActions.getContextClassLoader();
       
-      return toClass(expected, target, cf, cl);
+      return toClass(cfwc, target, cl, null);
    }
    
-   private <T> Class<T> toClass(final Class<T> expected, final CtClass target, final ClassFile cf, final ClassLoader cl) 
+   /**
+    * Create a class from the class file writer context 
+    * 
+    *  @param cfwc the class file writer context
+    *  @param target the target class
+    *  @param cl the classloader
+    *  @param domain the protection domain
+    *  @return the class
+    * 
+    */
+   private <T> Class<T> toClass(ClassFileWriterContext<T> cfwc, final CtClass target, ClassLoader cl, ProtectionDomain domain)
    {
       final ClassLoader actualLoader = PARENT_LOADER_HANDLER.getActualLoader(cl);
       Throwable t = null;
+      
       try
       {
-         if (System.getSecurityManager() == null)
-            return FactoryHelper.toClass(cf, actualLoader);
-         else
-            return AccessController.doPrivileged(new PrivilegedExceptionAction<Class<T>>()
-                  {
-                  public Class<T> run() throws Exception
-                  {
-                     return FactoryHelper.toClass(cf, actualLoader);
-                  }
-               });
+         return cfwc.toClass(actualLoader, domain);
       }
-      catch(CannotCompileException e)
+      catch (InvocationTargetException e)
       {
          t = e;
       }
-      catch (PrivilegedActionException e)
+      catch (IllegalAccessException e)
       {
-         t = e.getCause();
+         t = e;
       }
-      throw new RuntimeException("Error creating " + expected.getSimpleName() + " for " + target.getName() + " with classloader " + actualLoader + "(" + cl + ")", t);
+      throw new RuntimeException("Error creating " + cfwc.getSimpleType() + " for " + target.getName() + " with classloader " + actualLoader + "(" + cl + ")", t);
    }
    
    /**
     * Implements the methods of the interface
     * 
-    * @param cf the class file of the class we are creating
+    * @param cfcw the class file of the class we are creating
     */
-   void implementMethods(ClassFile cf) throws DuplicateMemberException
+   void implementMethods(ClassFileWriterContext<?> cfcw) throws DuplicateMemberException
    {
       int i = 0;
       while (true)
       {
-         MethodInfo minfo = implementMethod(i++, cf.getConstPool());
-         if (minfo == null)
+         if (!implementMethod(i++, cfcw))
             break;
-         cf.addMethod(minfo);
       }
    }
    
@@ -382,10 +361,10 @@
     * Create the method 
     * 
     * @param index the current index (starting at 0)
-    * @param cp the constant pool
-    * @return the created method, or null if there was no method with that index
+    * @param cfwc the class file writer context
+    * @return true, or false if there was no method with that index
     */
-   abstract MethodInfo implementMethod(int index, ConstPool cp);
+   abstract boolean implementMethod(int index, ClassFileWriterContext<?> cfwc);
    
    /**
     * Get the names of the interfaces to implement
@@ -428,149 +407,49 @@
    }
    
    /**
-    * Adds the constructors from the super class to the and delegates to them
-    * via super calls
-    * 
-    * @param cf the class file of the class we are creating
-    * @throws CannotCompileException if any of the constructors could not be added
-    */
-   private void makeConstructors(ClassFile cf) throws CannotCompileException
-   {
-      Constructor<?>[] cons = SecurityActions.getDeclaredConstructors(superClass);
-      for (int i = 0; i < cons.length; i++)
-      {
-         Constructor<?> c = cons[i];
-         int mod = c.getModifiers();
-         if (!Modifier.isFinal(mod) && !Modifier.isPrivate(mod))
-         {
-            MethodInfo m = makeConstructor(c, cf.getConstPool());
-            cf.addMethod(m);
-         }
-      }
-   }
-
-   /**
-    * Add a particular constructor from the super class and delegate to it via a 
-    * super call
-    *
-    * @param cons the constructor we are implementing
-    * @param cp the constant pool of the class we are generating
-    * @return the method info for the created constructor 
-    */
-   private MethodInfo makeConstructor(Constructor<?> cons, ConstPool cp)
-   {
-      String desc = RuntimeSupport.makeDescriptor(cons.getParameterTypes(), Void.TYPE);
-      MethodInfo minfo = new MethodInfo(cp, "<init>", desc);
-      minfo.setAccessFlags(Modifier.PUBLIC);
-      setThrows(minfo, cp, cons.getExceptionTypes());
-      Bytecode code = new Bytecode(cp, 0, 0);
-
-      int pc = code.currentPc();
-
-      code.addAload(0);
-      int s = addLoadParameters(code, cons.getParameterTypes(), 1);
-      code.addInvokespecial(superClass.getName(), "<init>", desc);
-      code.addOpcode(Opcode.RETURN);
-      code.setMaxLocals(s + 1);
-      CodeAttribute ca = code.toCodeAttribute();
-      minfo.setCodeAttribute(ca);
-
-      StackMapTable.Writer writer = new StackMapTable.Writer(32);
-      writer.sameFrame(pc);
-      ca.setAttribute(writer.toStackMapTable(cp));
-      return minfo;
-   }
-
-   /**
-    * Adds a throws clause to a method info
-    * 
-    * @param minfo the method info being created
-    * @param cp the constant pool of the class file the minfo will be added to
-    * @param exceptions the exceptions to be added to the throws clause
-    */
-   void setThrows(MethodInfo minfo, ConstPool cp, Class<?>[] exceptions)
-   {
-      if (exceptions.length == 0)
-         return;
-
-      String[] list = new String[exceptions.length];
-      for (int i = 0; i < exceptions.length; i++)
-         list[i] = exceptions[i].getName();
-
-      ExceptionsAttribute ea = new ExceptionsAttribute(cp);
-      ea.setExceptions(list);
-      minfo.setExceptionsAttribute(ea);
-   }
-
-   /**
     * Writes the class file bytes to the local file system so they can be inspected
     * with javap or another decompiler.
     * 
-    * @param cf the class file
+    * @param cfwc the class file writer context
     * @throws IOException if an error occurred writing the file
     */
-   void debugWriteFile(ClassFile cf) throws IOException
+   void debugWriteFile(final ClassFileWriterContext<?> cfwc) throws IOException
    {
-      FileOutputStream fout = new FileOutputStream(cf.getName() + ".class");
-      DataOutputStream out = new DataOutputStream(fout);
-      try 
+      try
       {
-         cf.write(out);
-      }
-      finally {
-         out.close();
-      }
-   }
+         AccessController.doPrivileged(new PrivilegedExceptionAction<Object>()
+         {
 
-   /**
-    * Adds instructions to load all the parameters for a method/constructor
-    * 
-    * @param code the byte code of the method/constructor being constructed
-    * @param params the types of the parameters of the method/constructor
-    * @param offset the offset
-    * @return the stack size
-    */
-   int addLoadParameters(Bytecode code, Class<?>[] params, int offset)
-   {
-      int stacksize = 0;
-      int n = params.length;
-      for (int i = 0; i < n; ++i)
-         stacksize += addLoad(code, stacksize + offset, params[i]);
-
-      return stacksize;
-   }
-
-   /**
-    * Adds the instruction to load a particular parameter for a method constructor
-    * 
-    * @param code the byte code of the method/constructor being constructed
-    * @param index the index of the parameter
-    * @param type the type of the parameter
-    * @return the stack size required for loading the parameter
-    */
-   int addLoad(Bytecode code, int index, Class<?> type)
-   {
-      if (type.isPrimitive())
+            public Object run() throws Exception
+            {
+               FileOutputStream fout = new FileOutputStream(cfwc.getName() + ".class");
+               BufferedOutputStream out = new BufferedOutputStream(fout);
+               try 
+               {
+                  out.write(cfwc.getBytes());
+               }
+               finally 
+               {
+                  try
+                  {
+                     out.close();
+                  }
+                  catch (Exception ignore)
+                  {
+                  }
+               }
+               return null;
+            }
+         });
+      }
+      catch (PrivilegedActionException e)
       {
-         if (type == Long.TYPE)
-         {
-            code.addLload(index);
-            return 2;
-         }
-         else if (type == Float.TYPE)
-            code.addFload(index);
-         else if (type == Double.TYPE)
-         {
-            code.addDload(index);
-            return 2;
-         }
-         else
-            code.addIload(index);
+         if (e.getCause() instanceof IOException)
+            throw (IOException)e.getCause();
+         if (e.getCause() instanceof RuntimeException)
+            throw (RuntimeException)e.getCause();
+         throw new RuntimeException(e.getCause());
       }
-      else
-         code.addAload(index);
-
-      return 1;
    }
 
    /**
@@ -609,138 +488,114 @@
       return type.getName();
    }
 
-   String getArrayType(CtClass type)
-   {
-      StringBuilder buf = new StringBuilder();
-
-      //int dims = 0;
-      while (type.isArray())
-      {
-         buf.append("L");
-         try
-         {
-            type = type.getComponentType();
-         }
-         catch(NotFoundException e)
-         {
-            throw new RuntimeException(e);
-         }
-      }
-      buf.append(type.getName());
-      buf.append(";");
-
-      return buf.toString();
-   }
-   
    /**
     * Casts the value currently on the stack to the target type, and if a primitive
     * unboxes it. The byte code instructions to do this are added to the 
-    * <code>code</code> parameter.
+    * <code>cfwc</code> parameter.
     * 
-    * @param code the byte code of the method/constructor we are creating
+    * @param cfcw the class file writer context of the method/constructor we are creating
     * @param type the target type we want to cast to
     */
-   void castAndUnbox(Bytecode code, CtClass type)
+   void castAndUnbox(ClassFileWriterContext<?> cfwc, CtClass type)
    {
       if (type.getName().equals(OBJECT_NAME))
          return;
 
-      code.addCheckcast(getBoxedType(type));
+      cfwc.addCheckcast(ClassFileWriterContext.jvmClassName(getBoxedType(type)));
       if (type.isPrimitive())
       {
          if (CtClass.booleanType.equals(type))
          {
-            code.addInvokevirtual(BOOLEAN_NAME, "booleanValue", BOOLEAN_VALUE_DESCRIPTOR);
+            cfwc.addInvokeVirtual(BOOLEAN_NAME, "booleanValue", BOOLEAN_VALUE_DESCRIPTOR);
             return;
          }
          else if (CtClass.byteType.equals(type))
          {
-            code.addInvokevirtual(BYTE_NAME, "byteValue", BYTE_VALUE_DESCRIPTOR);
+            cfwc.addInvokeVirtual(BYTE_NAME, "byteValue", BYTE_VALUE_DESCRIPTOR);
             return;
          }
          else if (CtClass.charType.equals(type))
          {
-            code.addInvokevirtual(CHARACTER_NAME, "charValue", CHAR_VALUE_DESCRIPTOR);
+            cfwc.addInvokeVirtual(CHARACTER_NAME, "charValue", CHAR_VALUE_DESCRIPTOR);
             return;
          }
          else if (CtClass.doubleType.equals(type))
          {
-            code.addInvokevirtual(DOUBLE_NAME, "doubleValue", DOUBLE_VALUE_DESCRIPTOR);
+            cfwc.addInvokeVirtual(DOUBLE_NAME, "doubleValue", DOUBLE_VALUE_DESCRIPTOR);
             return;
          }
          else if (CtClass.floatType.equals(type))
          {
-            code.addInvokevirtual(FLOAT_NAME, "floatValue", FLOAT_VALUE_DESCRIPTOR);
+            cfwc.addInvokeVirtual(FLOAT_NAME, "floatValue", FLOAT_VALUE_DESCRIPTOR);
             return;
          }
          else if (CtClass.intType.equals(type))
          {
-            code.addInvokevirtual(INTEGER_NAME, "intValue", INTEGER_VALUE_DESCRIPTOR);
+            cfwc.addInvokeVirtual(INTEGER_NAME, "intValue", INTEGER_VALUE_DESCRIPTOR);
             return;
          }
          else if (CtClass.longType.equals(type))
          {
-            code.addInvokevirtual(LONG_NAME, "longValue", LONG_VALUE_DESCRIPTOR);
+            cfwc.addInvokeVirtual(LONG_NAME, "longValue", LONG_VALUE_DESCRIPTOR);
             return;
          }
          else if (CtClass.shortType.equals(type))
          {
-            code.addInvokevirtual(SHORT_NAME, "shortValue", SHORT_VALUE_DESCRIPTOR);
+            cfwc.addInvokeVirtual(SHORT_NAME, "shortValue", SHORT_VALUE_DESCRIPTOR);
             return;
          }
          throw new UnreachableStatementException();
       }
-      
    }
    
    /**
-    * Adds the byte code instructions to the <code>code</code> paramter to box the value currently on the stack to the target type.
+    * Adds the byte code instructions to the <code>cfcw</code> paramter to box the value currently on the stack to the target type.
     * 
-    * @param code the byte code of the method/constructor we are currently creating
+    * @param cfcw the class file writer context of the method/constructor we are creating
     * @param type the type we want to cast to
     */
-   void boxReturnValue(Bytecode code, CtClass type)
+   void boxReturnValue(ClassFileWriterContext<?> cfwc, CtClass type)
    {
       if (type.isPrimitive())
       {
          if (CtClass.booleanType.equals(type))
          {
-            code.addInvokestatic(BOOLEAN_NAME, "valueOf", BOOLEAN_VALUE_OF_DESCRIPTOR);
+            cfwc.addInvokeStatic(BOOLEAN_NAME, "valueOf", BOOLEAN_VALUE_OF_DESCRIPTOR);
             return;
          }
          else if (CtClass.byteType.equals(type))
          {
-            code.addInvokestatic(BYTE_NAME, "valueOf", BYTE_VALUE_OF_DESCRIPTOR);
+            cfwc.addInvokeStatic(BYTE_NAME, "valueOf", BYTE_VALUE_OF_DESCRIPTOR);
             return;
          }
          else if (CtClass.charType.equals(type))
          {
-            code.addInvokestatic(CHARACTER_NAME, "valueOf", CHARACTER_VALUE_OF_DESCRIPTOR);
+            cfwc.addInvokeStatic(CHARACTER_NAME, "valueOf", CHARACTER_VALUE_OF_DESCRIPTOR);
             return;
          }
          else if (CtClass.doubleType.equals(type))
          {
-            code.addInvokestatic(DOUBLE_NAME, "valueOf", DOUBLE_VALUE_OF_DESCRIPTOR);
+            cfwc.addInvokeStatic(DOUBLE_NAME, "valueOf", DOUBLE_VALUE_OF_DESCRIPTOR);
             return;
          }
          else if (CtClass.floatType.equals(type))
          {
-            code.addInvokestatic(FLOAT_NAME, "valueOf", FLOAT_VALUE_OF_DESCRIPTOR);
+            cfwc.addInvokeStatic(FLOAT_NAME, "valueOf", FLOAT_VALUE_OF_DESCRIPTOR);
             return;
          }
          else if (CtClass.intType.equals(type))
          {
-            code.addInvokestatic(INTEGER_NAME, "valueOf", INTEGER_VALUE_OF_DESCRIPTOR);
+            cfwc.addInvokeStatic(INTEGER_NAME, "valueOf", INTEGER_VALUE_OF_DESCRIPTOR);
             return;
          }
          else if (CtClass.longType.equals(type))
          {
-            code.addInvokestatic(LONG_NAME, "valueOf", LONG_VALUE_OF_DESCRIPTOR);
+            cfwc.addInvokeStatic(LONG_NAME, "valueOf", LONG_VALUE_OF_DESCRIPTOR);
             return;
          }
          else if (CtClass.shortType.equals(type))
          {
-            code.addInvokestatic(SHORT_NAME, "valueOf", SHORT_VALUE_OF_DESCRIPTOR);
+            cfwc.addInvokeStatic(SHORT_NAME, "valueOf", SHORT_VALUE_OF_DESCRIPTOR);
             return;
          }
          throw new UnreachableStatementException();
@@ -748,293 +603,11 @@
    }
 
    /**
-    * Wraps the generated JavassistMethod in an implementation that checks the 
-    * parameters
+    * In AS the JavassistMethod, -Constructor and -Field classloaders are not deployed in 
+    * the system classpath. When generating an accessor for something from the system classpath
+    * we need to make sure it happens at the level that can see the implemented interfaces
     * 
-    * @param m The wrapped method
-    * @param method the target method for information about the parameters
-    * @return the error checking wrapper 
     */
-   private static JavassistMethod wrapInErrorChecker(JavassistMethod m, CtMethod method)
-   {
-      if (m == null || method == null)
-         throw new IllegalArgumentException("Null method");
-      
-      int numParameters = 0;
-      try
-      {
-         numParameters = method.getParameterTypes().length;
-      }
-      catch(NotFoundException e)
-      {
-         throw new IllegalArgumentException("Could not load the parameters for " + method);
-      }
-      
-      return new ErrorCheckingJavassistMethod(m, method, numParameters);
-   }
-   
-   /**
-    * Wraps the generated JavassistConstructor in an implementation that checks the 
-    * parameters
-    * 
-    * @param c The wrapped constructor
-    * @param constructor the target constructor for information about the parameters
-    * @return the error checking wrapper 
-    */
-   private static JavassistConstructor wrapInErrorChecker(JavassistConstructor c, CtConstructor constructor)
-   {
-      if (c == null || constructor == null)
-         throw new IllegalArgumentException("Null constructor");
-      
-      int numParameters = 0;
-      try
-      {
-         numParameters = constructor.getParameterTypes().length;
-      }
-      catch(NotFoundException e)
-      {
-         throw new IllegalArgumentException("Could not load the parameters for " + constructor);
-      }
-      
-      return new ErrorCheckingJavassistConstructor(c, constructor, numParameters);
-   }
-   
-   /**
-    * Wraps the generated JavassistField in an implementation that checks the 
-    * parameters
-    * 
-    * @param f The wrapped field
-    * @param field the target field for information about the parameters
-    * @return the error checking wrapper 
-    */
-   private static JavassistField wrapInErrorChecker(JavassistField f, CtField field)
-   {
-      if (f == null)
-         throw new IllegalArgumentException("Null field");
-      
-      return new ErrorCheckingJavassistField(f, field);
-   }
-   
-   private static class ErrorChecker
-   {
-      protected boolean checkNumberOfParameters(Object[] args, int numParameters)
-      {
-         if (args == null && numParameters > 0)
-            return false;
-         if (args != null && args.length != numParameters)
-            return false;
-         return true;
-      }
-      
-      protected boolean isStatic(CtMember member)
-      {
-         return Modifier.isStatic(member.getModifiers());
-      }
-      
-      protected void handleWrongParameters(String context, String target, Class<?>[] expected, Object[] args)
-      {
-         List<String> actual = new ArrayList<String>();
-         if (args != null)
-         {
-            for (Object argument : args)
-            {
-               if (argument == null)
-                  actual.add(null);
-               else
-                  actual.add(argument.getClass().getName());
-            }
-         }
-         throw new IllegalArgumentException("Wrong arguments. " + context + " for target " + target + " expected=" + expected + " actual=" + actual);
-         
-      }
-
-      protected void handleWrongTarget(Object target, Class<?> expected, String name)
-      {
-         throw new IllegalArgumentException("Wrong target for " + name + " " + target.getClass().getName() + " is not a " + expected.getName());
-      }
-      
-      protected void handleNullTarget(AccessibleObject ao)
-      {
-         throw new IllegalArgumentException("Null target calling non-static " + ao);      
-      }
-      
-   }
-   
-   private static class ErrorCheckingJavassistMethod extends ErrorChecker implements JavassistMethod
-   {
-      private final JavassistMethod delegate;
-      private final CtMethod ctMethod;
-      private final int numParameters;
-      
-      private ErrorCheckingJavassistMethod(JavassistMethod delegate, CtMethod ctMethod, int numParameters)
-      {
-         this.delegate = delegate;
-         this.ctMethod = ctMethod;
-         this.numParameters = numParameters;
-      }
-
-      public Object invoke(Object target, Object[] args) throws Throwable
-      {
-         if (!checkNumberOfParameters(args, numParameters))
-            throw new IllegalArgumentException("Wrong number of parameters for " + ctMethod.getDeclaringClass() + "." + ctMethod.getName() + ctMethod.getSignature());
-         
-         try
-         {
-            return delegate.invoke(target, args);
-         }
-         catch(ClassCastException e)
-         {
-            Method method = JavassistUtil.ctMethodToMethod(ctMethod); 
-            if (!isStatic(ctMethod))
-            {
-               if (!method.getDeclaringClass().isAssignableFrom(target.getClass()))
-                  handleWrongTarget(target, method.getDeclaringClass(), method.getName());
-            }
-            
-            Class<?>[] params = method.getParameterTypes();
-            for (int i = 0 ; i < args.length ; i++)
-            {
-               if (!params[i].isAssignableFrom(args[i].getClass()))
-                  handleWrongParameters(method.getName(), Strings.defaultToString(target), method.getParameterTypes(), args);
-            }
-            
-            throw e;
-         }
-         catch(NullPointerException e)
-         {
-            Method method = JavassistUtil.ctMethodToMethod(ctMethod); 
-            if (!isStatic(ctMethod) && target == null)
-               handleNullTarget(method);
-            
-            CtClass[] parameters = ctMethod.getParameterTypes();
-            for (int i = 0 ; i < parameters.length ; i++)
-            {
-               if (parameters[i].isPrimitive() && args[i] == null)
-                  handleWrongParameters(method.getName(), Strings.defaultToString(target), method.getParameterTypes(), args);
-            }
-            
-            throw e;
-         }
-      }
-      
-   }
-
-   private static class ErrorCheckingJavassistConstructor extends ErrorChecker implements JavassistConstructor
-   {
-      private final JavassistConstructor delegate;
-      private final CtConstructor ctConstructor;
-      private final int numParameters;
-      
-      private ErrorCheckingJavassistConstructor(JavassistConstructor delegate, CtConstructor ctConstructor, int numParameters)
-      {
-         this.delegate = delegate;
-         this.ctConstructor = ctConstructor;
-         this.numParameters = numParameters;
-      }
-
-      public Object newInstance(Object[] args) throws Throwable
-      {
-         if (!checkNumberOfParameters(args, numParameters))
-            throw new IllegalArgumentException("Wrong number of parameters for " + ctConstructor.getDeclaringClass() + "." + ctConstructor.getName() + ctConstructor.getSignature());
-         
-         try
-         {
-            return delegate.newInstance(args);
-         }
-         catch(ClassCastException e)
-         {
-            Constructor<?> constructor = JavassistUtil.ctConstructorToConstructor(ctConstructor);
-            Class<?>[] params = constructor.getParameterTypes();
-            for (int i = 0 ; i < args.length ; i++)
-            {
-               if (!params[i].isAssignableFrom(args[i].getClass()))
-                  handleWrongParameters("new", Strings.defaultToString(ctConstructor.getDeclaringClass().getName()), constructor.getParameterTypes(), args);
-            }
-               
-            throw e;
-         }
-         catch(NullPointerException e)
-         {
-            CtClass[] parameters = ctConstructor.getParameterTypes();
-            for (int i = 0 ; i < parameters.length ; i++)
-            {
-               if (parameters[i].isPrimitive() && args[i] == null)
-               {
-                  Constructor<?> constructor = JavassistUtil.ctConstructorToConstructor(ctConstructor);
-                  handleWrongParameters("new", Strings.defaultToString(ctConstructor.getDeclaringClass().getName()), constructor.getParameterTypes(), args);
-               }
-            }
-            
-            throw e;
-         }
-      }
-   }
-
-   private static class ErrorCheckingJavassistField extends ErrorChecker implements JavassistField
-   {
-      private final JavassistField delegate;
-      private final CtField ctField;
-      
-      private ErrorCheckingJavassistField(JavassistField delegate, CtField ctField)
-      {
-         this.delegate = delegate;
-         this.ctField = ctField;
-      }
-
-      public Object get(Object target) throws Throwable
-      {
-         try
-         {
-            return delegate.get(target);
-         }
-         catch (ClassCastException e)
-         {
-            Field field = JavassistUtil.ctFieldToField(ctField);
-            
-            if (!isStatic(ctField) && !field.getDeclaringClass().isAssignableFrom(target.getClass()))
-               handleWrongTarget(target, field.getDeclaringClass(), field.getName());
-            
-            throw e;
-         }
-         catch(NullPointerException e)
-         {
-            Field field = JavassistUtil.ctFieldToField(ctField);
-            if (!isStatic(ctField) && target == null)
-               handleNullTarget(field);
-            throw e;
-         }
-      }
-
-      public void set(Object target, Object value) throws Throwable
-      {
-         try
-         {
-            delegate.set(target, value);
-         }
-         catch (ClassCastException e)
-         {
-            Field field = JavassistUtil.ctFieldToField(ctField);
-            Class<?> type = field.getType();
-
-            if (!isStatic(ctField) && !field.getDeclaringClass().isAssignableFrom(target.getClass()))
-               handleWrongTarget(target, field.getDeclaringClass(), field.getName());
-
-            if (!type.isAssignableFrom(value.getClass()))
-               throw new IllegalArgumentException("Wrong arguments. Setting " + field.getName() + " for target " + target + " expected=" + field.getType() + " actual=" + value.getClass());
-         }
-         catch(NullPointerException e)
-         {
-            Field field = JavassistUtil.ctFieldToField(ctField);
-            if (!isStatic(ctField) && target == null)
-               handleNullTarget(field);
-            if (ctField.getType().isPrimitive() && value == null)
-               throw new IllegalArgumentException("Null value setting non-static field. " + field);
-            throw e;
-         }
-      }
-   }
-   
-   
    private static class ParentLoaderHandler
    {
       final ClassLoader reflectLoader;

Modified: projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/JavassistMethodFactory.java
===================================================================
--- projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/JavassistMethodFactory.java	2010-05-12 10:45:48 UTC (rev 104719)
+++ projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/JavassistMethodFactory.java	2010-05-12 11:01:32 UTC (rev 104720)
@@ -27,12 +27,6 @@
 import javassist.CtMethod;
 import javassist.Modifier;
 import javassist.NotFoundException;
-import javassist.bytecode.Bytecode;
-import javassist.bytecode.CodeAttribute;
-import javassist.bytecode.ConstPool;
-import javassist.bytecode.MethodInfo;
-import javassist.bytecode.Opcode;
-import javassist.bytecode.StackMapTable;
 import javassist.util.proxy.RuntimeSupport;
 
 import org.jboss.reflect.plugins.javassist.JavassistMethod;
@@ -55,6 +49,9 @@
    /** The methods from the interface that are being implemented */ 
    private static final Method[] methods;
    
+   /** The descriptors for the methods */
+   private static final String[] methodDescriptors = new String[1];
+   
    static
    {
       interfaceNames = new String[] {JavassistMethod.class.getName()};
@@ -66,7 +63,8 @@
       catch (NoSuchMethodException e)
       {
          throw new RuntimeException(e);
-      } 
+      }
+      methodDescriptors[0] = RuntimeSupport.makeDescriptor(methods[0]);
    }
 
    /** The method we are targeting */
@@ -118,63 +116,55 @@
    }
 
    @Override
-   MethodInfo implementMethod(int index, ConstPool cp)
+   boolean implementMethod(int index, ClassFileWriterContext<?> cfwc)
    {
       if (index >= methods.length)
-         return null;
+         return false;
 
       Method method = methods[index];
       
-      String desc = RuntimeSupport.makeDescriptor(method);
-      MethodInfo minfo = new MethodInfo(cp, method.getName(), desc);
-      minfo.setAccessFlags(Modifier.PUBLIC);
-      setThrows(minfo, cp, method.getExceptionTypes());
-      Bytecode code = new Bytecode(cp, 0, 0);
-      
-      int pc = code.currentPc();
-      
-
+      cfwc.beginMethod(Modifier.PUBLIC, method.getName(), methodDescriptors[index], THROWABLE_EXCEPTIONS);
+ 
       boolean isStatic = Modifier.isStatic(ctBehavior.getModifiers());
-
+      
+      String targetClassName = ClassFileWriterContext.jvmClassName(ctMethod.getDeclaringClass());
       if (!isStatic)
       {
          //push and cast the target object
-         code.addAload(1);
-         code.addCheckcast(ctMethod.getDeclaringClass());
+         cfwc.addAload(1);
+         cfwc.addCheckcast(targetClassName);
       }
       
-      addParameters(code, getParameterTypes(), 2);
-
+      addParameters(cfwc, getParameterTypes(), 2);
+      
       if (isStatic)
-         code.addInvokestatic(ctMethod.getDeclaringClass(), ctMethod.getName(), ctMethod.getSignature());
+         cfwc.addInvokeStatic(targetClassName, ctMethod.getName(), ctMethod.getSignature());
       else if (ctMethod.getDeclaringClass().isInterface())
-         code.addInvokeinterface(ctMethod.getDeclaringClass(), ctMethod.getName(), ctMethod.getSignature(), countParameterStackSize(0, getParameterTypes()));
+      {
+         cfwc.addInvokeInterface(targetClassName, ctMethod.getName(), ctMethod.getSignature(), countParameterStackSize(0, getParameterTypes()));
+      }
       else
-         code.addInvokevirtual(ctMethod.getDeclaringClass(), ctMethod.getName(), ctMethod.getSignature());
+         cfwc.addInvokeVirtual(targetClassName, ctMethod.getName(), ctMethod.getSignature());
       
       if (getReturnType() == CtClass.voidType)
-      {            
-         //return null;
-         code.addOpcode(Opcode.ACONST_NULL);
-         code.addOpcode(Opcode.ARETURN);
+      {
+         //return null
+         cfwc.addAConstNull();
+         cfwc.addAReturn();
       }
       else
       {
-         boxReturnValue(code, getReturnType());
-         code.addOpcode(Opcode.ARETURN);
+         boxReturnValue(cfwc, getReturnType());
+         cfwc.addAReturn();
       }
 
       //We need 3 local variable slots.
       //One for 'this', one for the target reference and one for the argument array.
       //These are all object references and so take one slot each 
-      code.setMaxLocals(3);
-      
-      CodeAttribute ca = code.toCodeAttribute();
-      minfo.setCodeAttribute(ca);
 
-      StackMapTable.Writer writer = new StackMapTable.Writer(32);
-      writer.sameFrame(pc);
-      ca.setAttribute(writer.toStackMapTable(cp));
-      return minfo;
+      //TODO the max stack
+      cfwc.endMethod(3);
+
+      return true;
    }
 }
\ No newline at end of file

Modified: projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/SecurityActions.java
===================================================================
--- projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/SecurityActions.java	2010-05-12 10:45:48 UTC (rev 104719)
+++ projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/bytecode/SecurityActions.java	2010-05-12 11:01:32 UTC (rev 104720)
@@ -21,7 +21,9 @@
 */
 package org.jboss.reflect.plugins.javassist.bytecode;
 
+import java.lang.reflect.AccessibleObject;
 import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
@@ -111,4 +113,47 @@
          }
       }
    }
+   
+   static void setAccessible(final AccessibleObject member)
+   {
+      if (System.getSecurityManager() == null)
+         member.setAccessible(true);
+      else
+         AccessController.doPrivileged(new PrivilegedAction<Object>()
+         {
+            public Object run()
+            {
+               member.setAccessible(true);
+               return null;
+            }
+         });
+   }
+   
+   static Object invoke(final Method method, final Object target, final Object...args) throws IllegalAccessException, InvocationTargetException
+   {
+      if (System.getSecurityManager() == null)
+         return method.invoke(target, args);
+      
+      try
+      {
+         return AccessController.doPrivileged(new PrivilegedExceptionAction<Object>()
+         {
+            public Object run() throws Exception
+            {
+               return method.invoke(target, args);
+            }
+         });
+      }
+      catch (PrivilegedActionException e)
+      {
+         if (e.getCause() instanceof RuntimeException)
+            throw (RuntimeException)e.getCause();
+         if (e.getCause() instanceof IllegalAccessException)
+            throw (IllegalAccessException)e.getCause();
+         if (e.getCause() instanceof InvocationTargetException)
+            throw (InvocationTargetException)e.getCause();
+         
+         throw new RuntimeException(e.getCause());
+      }
+   }
 }




More information about the jboss-cvs-commits mailing list