scolebourne    2002/10/24 16:12:54

  Added:       lang/src/java/org/apache/commons/lang/reflect
                        MethodUtils.java FieldUtils.java
                        ConstructorUtils.java ReflectionException.java
                        ReflectionUtils.java
               lang/src/java/org/apache/commons/lang ClassUtils.java
  Log:
  Initial checkin of reflection code (not all working)
  
  Revision  Changes    Path
  1.1                  
jakarta-commons/lang/src/java/org/apache/commons/lang/reflect/MethodUtils.java
  
  Index: MethodUtils.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.commons.lang.reflect;
  
  import java.lang.reflect.Field;
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.Member;
  import java.lang.reflect.Method;
  import java.lang.reflect.Modifier;
  import java.util.ArrayList;
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Set;
  
  import org.apache.commons.lang.ArrayUtils;
  import org.apache.commons.lang.StringUtils;
  /**
   * <code>MethodUtils</code> contains utility methods for working for
   * methods by reflection.
   * <p>
   * The ability is provided to break the scoping restrictions coded by the
   * programmer. This can break an implementation if used incorrectly. This
   * facility should be used with care.
   *
   * @author Based on code from BeanUtils
   * @author <a href="mailto:scolebourne@;apache.org">Stephen Colebourne</a>
   * @version $Id: MethodUtils.java,v 1.1 2002/10/24 23:12:54 scolebourne Exp $
   */
  public class MethodUtils {
      
      /** An empty method array */
      public static final Method[] EMPTY_METHOD_ARRAY = new Method[0];
      
      /**
       * MethodUtils instances should NOT be constructed in standard programming.
       * Instead, the class should be used as <code>MethodUtils.getMethod(cls, 
name)</code>.
       * This constructor is public to permit tools that require a JavaBean instance
       * to operate.
       */
      public MethodUtils() {
      }
  
      // -------------------------------------------------------------------------
      
      /**
       * Gets a Method by name. The method must be public and take no parameters.
       * Superclasses will be considered.
       *
       * @param cls  the class to reflect, must not be null
       * @param methodName  the field name to obtain
       * @return the Method object
       * @throws IllegalArgumentException if the class or method name is null
       * @throws ReflectionException if an error occurs during reflection
       */
      public static Method getMethod(Class cls, String methodName) {
          return getMethod(cls, methodName, ArrayUtils.EMPTY_CLASS_ARRAY, false);
      }
      
      /**
       * Gets a Method by name. The method must be public.
       * Superclasses will be considered.
       *
       * @param cls  the class to reflect, must not be null
       * @param methodName  the field name to obtain
       * @return the Method object
       * @throws IllegalArgumentException if the class or method name is null
       * @throws ReflectionException if an error occurs during reflection
       */
      public static Method getMethod(Class cls, String methodName, Class[] paramTypes) 
{
          return getMethod(cls, methodName, paramTypes, false);
      }
      
      /**
       * Gets a Method by name.
       * Superclasses will be considered.
       *
       * @param cls  the class to reflect, must not be null
       * @param methodName  the method name to obtain
       * @param breakScope  whether to break scope restrictions using the
       *  <code>setAccessible</code> method. False will only match public fields.
       * @return the Method object
       * @throws IllegalArgumentException if the class or field name is null
       * @throws ReflectionException if an error occurs during reflection
       */
      public static Method getMethod(Class cls, String methodName, Class[] paramTypes, 
boolean breakScope) {
          if (cls == null) {
              throw new IllegalArgumentException("The class must not be null");
          }
          if (methodName == null) {
              throw new IllegalArgumentException("The method name must not be null");
          }
          try {
              if (breakScope) {
                  try {
                      // most common case, always do this for speed
                      return cls.getMethod(methodName, paramTypes);  // must be public
                  } catch (NoSuchMethodException ex) {
                      // ignore
                  }
                  Class acls = cls;
                  while (acls != null) {
                      Method[] methods = acls.getDeclaredMethods();
                      for (int i = 0; i < methods.length; i++) {
                          if (methods[i].getName().equals(methodName) &&
                              ReflectionUtils.isCompatable(paramTypes, 
methods[i].getParameterTypes())) {
                              if (Modifier.isPublic(methods[i].getModifiers())) {
                                  methods[i].setAccessible(true);
                              }
                              return methods[i];
                          }
                      }
                      acls = acls.getSuperclass();  // TODO interfaces
                  }
                  throw new NoSuchMethodException("The method '" + methodName + "' 
could not be found");
              } else {
                  return cls.getMethod(methodName, paramTypes);
              }
      
          } catch (ReflectionException ex) {
              throw ex;
          } catch (LinkageError ex) {
              throw new ReflectionException(ReflectionUtils.getThrowableText(
                  ex, "getting method", cls.getName(), null, methodName), ex);
          } catch (Exception ex) {
              throw new ReflectionException(ReflectionUtils.getThrowableText(
                  ex, "getting method", cls.getName(), null, methodName), ex);
          }
      }
      
      // -------------------------------------------------------------------------
      
      /**
       * <p>Invoke a named method whose parameter type matches the object type.</p>
       *
       * <p>The behaviour of this method is less deterministic 
       * than {@link #invokeExactMethod}. 
       * It loops through all methods with names that match
       * and then executes the first it finds with compatable parameters.</p>
       *
       * <p>This method supports calls to methods taking primitive parameters 
       * via passing in wrapping classes. So, for example, a <code>Boolean</code> class
       * would match a <code>boolean</code> primitive.</p>
       *
       * <p> This is a convenient wrapper for
       * {@link #invokeMethod(Object object,String methodName,Object [] args)}.
       * </p>
       *
       * @param objectToInvoke  invoke method on this object, must not be null
       * @param methodName  get method with this name, must not be null
       * @param arg  use this argument, must not be null
       *
       * @throws NoSuchMethodException if there is no such accessible method
       * @throws InvocationTargetException wraps an exception thrown by the
       *  method invoked
       * @throws IllegalAccessException if the requested method is not accessible
       *  via reflection
       * @throws IllegalArgumentException if any parameter is null
       */
      public static Object invokeMethod(
              Object objectToInvoke,
              String methodName,
              Object arg)
                  throws
                      NoSuchMethodException,
                      IllegalAccessException,
                      InvocationTargetException {
  
          if (objectToInvoke == null) {
              throw new IllegalArgumentException("The object to invoke must not be 
null");
          }
          if (methodName == null) {
              throw new IllegalArgumentException("The method name must not be null");
          }
          if (arg == null) {
              throw new IllegalArgumentException("The argument must not be null");
          }
          Object[] args = {arg};
          return invokeMethod(objectToInvoke, methodName, args);
      }
  
      /**
       * <p>Invoke a named method whose parameter type matches the object type.</p>
       *
       * <p>The behaviour of this method is less deterministic 
       * than {@link #invokeExactMethod(Object object,String methodName,Object [] 
args)}. 
       * It loops through all methods with names that match
       * and then executes the first it finds with compatable parameters.</p>
       *
       * <p>This method supports calls to methods taking primitive parameters 
       * via passing in wrapping classes. So, for example, a <code>Boolean</code> class
       * would match a <code>boolean</code> primitive.</p>
       *
       * <p> This is a convenient wrapper for
       * {@link #invokeMethod(Object object,String methodName,Object [] args,Class[] 
parameterTypes)}.
       * </p>
       *
       * @param objectToInvoke  invoke method on this object, must not be null
       * @param methodName  get method with this name, must not be null
       * @param args  use these arguments - treat null as empty array
       *
       * @throws NoSuchMethodException if there is no such accessible method
       * @throws InvocationTargetException wraps an exception thrown by the
       *  method invoked
       * @throws IllegalAccessException if the requested method is not accessible
       *  via reflection
       * @throws IllegalArgumentException if the objectToInvoke, methodName or any 
argument is null
       */
      public static Object invokeMethod(
              Object objectToInvoke,
              String methodName,
              Object[] args)
                  throws
                      NoSuchMethodException,
                      IllegalAccessException,
                      InvocationTargetException {
          
          if (objectToInvoke == null) {
              throw new IllegalArgumentException("The object to invoke must not be 
null");
          }
          if (methodName == null) {
              throw new IllegalArgumentException("The method name must not be null");
          }
          if (args == null) {
              return invokeMethod(objectToInvoke, methodName, null, null);
          } else {
              int arguments = args.length;
              Class parameterTypes [] = new Class[arguments];
              for (int i = 0; i < arguments; i++) {
                  if (args[i] == null) {
                      throw new IllegalArgumentException("The arguments must not be 
null. Index " + i + " was null.");
                  }
                  parameterTypes[i] = args[i].getClass();
              }
              return invokeMethod(objectToInvoke, methodName, args, parameterTypes);
          }
      }
  
      /**
       * <p>Invoke a named method whose parameter type matches the object type.</p>
       *
       * <p>The behaviour of this method is less deterministic 
       * than {@link 
       * #invokeExactMethod(Object object,String methodName,Object [] args,Class[] 
parameterTypes)}. 
       * It loops through all methods with names that match
       * and then executes the first it finds with compatable parameters.</p>
       *
       * <p>This method supports calls to methods taking primitive parameters 
       * via passing in wrapping classes. So, for example, a <code>Boolean</code> class
       * would match a <code>boolean</code> primitive.</p>
       *
       *
       * @param object  invoke method on this object
       * @param methodName  get method with this name
       * @param args  use these arguments - treat null as empty array
       * @param parameterTypes  match these parameters - treat null as empty array
       *
       * @throws NoSuchMethodException if there is no such accessible method
       * @throws InvocationTargetException wraps an exception thrown by the
       *  method invoked
       * @throws IllegalAccessException if the requested method is not accessible
       *  via reflection
       */
      public static Object invokeMethod(
              Object object,
              String methodName,
              Object[] args,
              Class[] parameterTypes)
                  throws
                      NoSuchMethodException,
                      IllegalAccessException,
                      InvocationTargetException {
                      
          if (parameterTypes == null) {
              parameterTypes = ArrayUtils.EMPTY_CLASS_ARRAY;
          }        
          if (args == null) {
              args = ArrayUtils.EMPTY_OBJECT_ARRAY;
          }  
  
  return null;
  //        Method method = getMatchingAccessibleMethod(
  //                object.getClass(),
  //                methodName,
  //                parameterTypes);
  //        if (method == null)
  //            throw new NoSuchMethodException("No such accessible method: " +
  //                    methodName + "() on object: " + object.getClass().getName());
  //        return method.invoke(object, args);
      }
  
  
      /**
       * <p>Invoke a method whose parameter type matches exactly the object
       * type.</p>
       *
       * <p> This is a convenient wrapper for
       * {@link #invokeExactMethod(Object object,String methodName,Object [] args)}.
       * </p>
       *
       * @param object invoke method on this object
       * @param methodName get method with this name
       * @param arg use this argument
       *
       * @throws NoSuchMethodException if there is no such accessible method
       * @throws InvocationTargetException wraps an exception thrown by the
       *  method invoked
       * @throws IllegalAccessException if the requested method is not accessible
       *  via reflection
       */
      public static Object invokeExactMethod(
              Object object,
              String methodName,
              Object arg)
              throws
              NoSuchMethodException,
              IllegalAccessException,
              InvocationTargetException {
  
          Object[] args = {arg};
          return invokeExactMethod(object, methodName, args);
  
      }
  
  
      /**
       * <p>Invoke a method whose parameter types match exactly the object
       * types.</p>
       *
       * <p> This uses reflection to invoke the method obtained from a call to
       * {@link #getAccessibleMethod}.</p>
       *
       * @param object invoke method on this object
       * @param methodName get method with this name
       * @param args use these arguments - treat null as empty array
       *
       * @throws NoSuchMethodException if there is no such accessible method
       * @throws InvocationTargetException wraps an exception thrown by the
       *  method invoked
       * @throws IllegalAccessException if the requested method is not accessible
       *  via reflection
       */
      public static Object invokeExactMethod(
              Object object,
              String methodName,
              Object[] args)
              throws
              NoSuchMethodException,
              IllegalAccessException,
              InvocationTargetException {
          if (args == null) {
              args = ArrayUtils.EMPTY_OBJECT_ARRAY;
          }  
          int arguments = args.length;
          Class parameterTypes [] = new Class[arguments];
          for (int i = 0; i < arguments; i++) {
              parameterTypes[i] = args[i].getClass();
          }
          return invokeExactMethod(object, methodName, args, parameterTypes);
  
      }
  
  
      /**
       * <p>Invoke a method whose parameter types match exactly the parameter
       * types given.</p>
       *
       * <p>This uses reflection to invoke the method obtained from a call to
       * {@link #getAccessibleMethod}.</p>
       *
       * @param object invoke method on this object
       * @param methodName get method with this name
       * @param args use these arguments - treat null as empty array
       * @param parameterTypes match these parameters - treat null as empty array
       *
       * @throws NoSuchMethodException if there is no such accessible method
       * @throws InvocationTargetException wraps an exception thrown by the
       *  method invoked
       * @throws IllegalAccessException if the requested method is not accessible
       *  via reflection
       */
      public static Object invokeExactMethod(
              Object object,
              String methodName,
              Object[] args,
              Class[] parameterTypes)
              throws
              NoSuchMethodException,
              IllegalAccessException,
              InvocationTargetException {
          
          if (args == null) {
              args = ArrayUtils.EMPTY_OBJECT_ARRAY;
          }  
                  
          if (parameterTypes == null) {
              parameterTypes = ArrayUtils.EMPTY_CLASS_ARRAY;
          }
  
          Method method = getAccessibleMethod(
                  object.getClass(),
                  methodName,
                  parameterTypes);
          if (method == null)
              throw new NoSuchMethodException("No such accessible method: " +
                      methodName + "() on object: " + object.getClass().getName());
          return method.invoke(object, args);
  
      }
  
  
      /**
       * <p>Return an accessible method (that is, one that can be invoked via
       * reflection) with given name and a single parameter.  If no such method
       * can be found, return <code>null</code>.
       * Basically, a convenience wrapper that constructs a <code>Class</code>
       * array for you.</p>
       *
       * @param clazz get method from this class
       * @param methodName get method with this name
       * @param parameterType taking this type of parameter
       */
      public static Method getAccessibleMethod(
              Class clazz,
              String methodName,
              Class parameterType) {
  
          Class[] parameterTypes = {parameterType};
          return getAccessibleMethod(clazz, methodName, parameterTypes);
  
      }
  
  
      /**
       * <p>Return an accessible method (that is, one that can be invoked via
       * reflection) with given name and parameters.  If no such method
       * can be found, return <code>null</code>.
       * This is just a convenient wrapper for
       * {@link #getAccessibleMethod(Method method)}.</p>
       *
       * @param clazz get method from this class
       * @param methodName get method with this name
       * @param parameterTypes with these parameters types
       */
      public static Method getAccessibleMethod(
              Class clazz,
              String methodName,
              Class[] parameterTypes) {
  
          try {
              return getAccessibleMethod
                      (clazz.getMethod(methodName, parameterTypes));
          } catch (NoSuchMethodException e) {
              return (null);
          }
  
      }
  
  
      /**
       * <p>Return an accessible method (that is, one that can be invoked via
       * reflection) that implements the specified Method.  If no such method
       * can be found, return <code>null</code>.</p>
       *
       * @param method The method that we wish to call
       */
      public static Method getAccessibleMethod(Method method) {
  
          // Make sure we have a method to check
          if (method == null) {
              return (null);
          }
  
          // If the requested method is not public we cannot call it
          if (!Modifier.isPublic(method.getModifiers())) {
              return (null);
          }
  
          // If the declaring class is public, we are done
          Class clazz = method.getDeclaringClass();
          if (Modifier.isPublic(clazz.getModifiers())) {
              return (method);
          }
  
          // Check the implemented interfaces and subinterfaces
          String methodName = method.getName();
          Class[] parameterTypes = method.getParameterTypes();
          method =
                  getAccessibleMethodFromInterfaceNest(clazz,
                          method.getName(),
                          method.getParameterTypes());
          return (method);
  
      }
  
  
      // -------------------------------------------------------- Private Methods
  
      /**
       * <p>Return an accessible method (that is, one that can be invoked via
       * reflection) that implements the specified method, by scanning through
       * all implemented interfaces and subinterfaces.  If no such method
       * can be found, return <code>null</code>.</p>
       *
       * <p> There isn't any good reason why this method must be private.
       * It is because there doesn't seem any reason why other classes should
       * call this rather than the higher level methods.</p>
       *
       * @param clazz Parent class for the interfaces to be checked
       * @param methodName Method name of the method we wish to call
       * @param parameterTypes The parameter type signatures
       */
      private static Method getAccessibleMethodFromInterfaceNest
              (Class clazz, String methodName, Class parameterTypes[]) {
  
          Method method = null;
  
          // Search up the superclass chain
          for (; clazz != null; clazz = clazz.getSuperclass()) {
  
              // Check the implemented interfaces of the parent class
              Class interfaces[] = clazz.getInterfaces();
              for (int i = 0; i < interfaces.length; i++) {
  
                  // Is this interface public?
                  if (!Modifier.isPublic(interfaces[i].getModifiers()))
                      continue;
  
                  // Does the method exist on this interface?
                  try {
                      method = interfaces[i].getDeclaredMethod(methodName,
                              parameterTypes);
                  } catch (NoSuchMethodException e) {
                      ;
                  }
                  if (method != null)
                      break;
  
                  // Recursively check our parent interfaces
                  method =
                          getAccessibleMethodFromInterfaceNest(interfaces[i],
                                  methodName,
                                  parameterTypes);
                  if (method != null)
                      break;
  
              }
  
          }
  
          // If we found a method return it
          if (method != null)
              return (method);
  
          // We did not find anything
          return (null);
  
      }
  
  //    /**
  //     * <p>Find an accessible method that matches the given name and has compatible 
parameters.
  //     * Compatible parameters mean that every method parameter is assignable from 
  //     * the given parameters.
  //     * In other words, it finds a method with the given name 
  //     * that will take the parameters given.<p>
  //     *
  //     * <p>This method is slightly undeterminstic since it loops 
  //     * through methods names and return the first matching method.</p>
  //     * 
  //     * <p>This method is used by 
  //     * {@link 
  //     * #invokeMethod(Object object,String methodName,Object [] args,Class[] 
parameterTypes)}.
  //     *
  //     * <p>This method can match primitive parameter by passing in wrapper classes.
  //     * For example, a <code>Boolean</code> will match a primitive 
<code>boolean</code>
  //     * parameter.
  //     *
  //     * @param clazz find method in this class
  //     * @param methodName find method with this name
  //     * @param parameterTypes find method with compatible parameters 
  //     */
  //    private static Method getMatchingAccessibleMethod(
  //                                                Class clazz,
  //                                                String methodName,
  //                                                Class[] parameterTypes) {
  //        // trace logging
  //        if (log.isTraceEnabled()) {
  //            log.trace("Matching name=" + methodName + " on " + clazz);
  //        }
  //        
  //        // see if we can find the method directly
  //        // most of the time this works and it's much faster
  //        try {
  //            Method method = clazz.getMethod(methodName, parameterTypes);
  //            return method;
  //            
  //        } catch (NoSuchMethodException e) { /* SWALLOW */ }
  //        
  //        // search through all methods 
  //        int paramSize = parameterTypes.length;
  //        Method[] methods = clazz.getMethods();
  //        for (int i = 0, size = methods.length; i < size ; i++) {
  //            if (methods[i].getName().equals(methodName)) {  
  //                // log some trace information
  //                if (log.isTraceEnabled()) {
  //                    log.trace("Found matching name:");
  //                    log.trace(methods[i]);
  //                }                
  //                
  //                // compare parameters
  //                Class[] methodsParams = methods[i].getParameterTypes();
  //                int methodParamSize = methodsParams.length;
  //                if (methodParamSize == paramSize) {          
  //                    boolean match = true;
  //                    for (int n = 0 ; n < methodParamSize; n++) {
  //                        if (log.isTraceEnabled()) {
  //                            log.trace("Param=" + parameterTypes[n].getName());
  //                            log.trace("Method=" + methodsParams[n].getName());
  //                        }
  //                        if (!isAssignmentCompatible(methodsParams[n], 
parameterTypes[n])) {
  //                            if (log.isTraceEnabled()) {
  //                                log.trace(methodsParams[n] + " is not assignable 
from " 
  //                                            + parameterTypes[n]);
  //                            }    
  //                            match = false;
  //                            break;
  //                        }
  //                    }
  //                    
  //                    if (match) {
  //                        // get accessible version of method
  //                        Method method = getAccessibleMethod(methods[i]);
  //                        if (method != null) {
  //                            if (log.isTraceEnabled()) {
  //                                log.trace(method + " accessible version of " 
  //                                            + methods[i]);
  //                            }
  //                            return method;
  //                        }
  //                        
  //                        log.trace("Couldn't find accessible method.");
  //                    }
  //                }
  //            }
  //        }
  //        
  //        // didn't find a match
  //        log.trace("No match found.");
  //        return null;                                        
  //    }
  //
  //    /**
  //     * <p>Determine whether a type can be used as a parameter in a method 
invocation.
  //     * This method handles primitive conversions correctly.</p>
  //     *
  //     * <p>In order words, it will match a <code>Boolean</code> to a 
<code>boolean</code>,
  //     * a <code>Long</code> to a <code>long</code>,
  //     * a <code>Float</code> to a <code>float</code>,
  //     * a <code>Integer</code> to a <code>int</code>,
  //     * and a <code>Double</code> to a <code>double</code>.
  //     * Now logic widening matches are allowed.
  //     * For example, a <code>Long</code> will not match a <code>int</code>.
  //     *
  //     * @param parameterType the type of parameter accepted by the method
  //     * @param parameterization the type of parameter being tested 
  //     *
  //     * @return true if the assignement is compatible.
  //     */
  //    private static final boolean isAssignmentCompatible(Class parameterType, Class 
parameterization) {
  //        // try plain assignment
  //        if (parameterType.isAssignableFrom(parameterization)) {
  //            return true;
  //        }
  //        
  //        if (parameterType.isPrimitive()) {
  //            // does anyone know a better strategy than comparing names?
  //            // also, this method does *not* do widening - you must specify exactly
  //            // is this the right behaviour?
  //            if (boolean.class.equals(parameterType)) {
  //                return Boolean.class.equals(parameterization);
  //            }         
  //            if (float.class.equals(parameterType)) {
  //                return Float.class.equals(parameterization);
  //            }     
  //            if (long.class.equals(parameterType)) {
  //                return Long.class.equals(parameterization);
  //            }     
  //            if (int.class.equals(parameterType)) {
  //                return Integer.class.equals(parameterization);
  //            }                
  //            if (double.class.equals(parameterType)) {
  //                return Double.class.equals(parameterization);
  //            }               
  //        }
  //        
  //        return false;
  //    }
  //    
  }
  
  
  
  1.1                  
jakarta-commons/lang/src/java/org/apache/commons/lang/reflect/FieldUtils.java
  
  Index: FieldUtils.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.commons.lang.reflect;
  
  import java.lang.reflect.Field;
  import java.lang.reflect.Modifier;
  /**
   * <code>FieldUtils</code> contains utility methods for working with
   * fields by reflection.
   * <p>
   * The ability is provided to break the scoping restrictions coded by the
   * programmer. This can allow fields to be changed that shouldn't be. This
   * facility should be used with care.
   *
   * @author <a href="mailto:scolebourne@;apache.org">Stephen Colebourne</a>
   * @version $Id: FieldUtils.java,v 1.1 2002/10/24 23:12:54 scolebourne Exp $
   */
  public class FieldUtils {
      
      /** An empty field array */
      public static final Field[] EMPTY_FIELD_ARRAY = new Field[0];
      
      /**
       * FieldUtils instances should NOT be constructed in standard programming.
       * Instead, the class should be used as <code>FieldUtils.getField(cls, 
name)</code>.
       * This constructor is public to permit tools that require a JavaBean instance
       * to operate.
       */
      public FieldUtils() {
      }
  
      // -------------------------------------------------------------------------
      
      /**
       * Gets an accessible Field by name repecting scope.
       * Superclasses/interfaces will be considered.
       *
       * @param cls  the class to reflect, must not be null
       * @param fieldName  the field name to obtain
       * @return the Field object
       * @throws IllegalArgumentException if the class or field name is null
       * @throws ReflectionException if an error occurs during reflection
       */
      public static Field getField(Class cls, String fieldName) {
          return getField(cls, fieldName, false);
      }
      
      /**
       * Gets an accessible Field by name breaking scope if requested.
       * Superclasses/interfaces will be considered.
       *
       * @param cls  the class to reflect, must not be null
       * @param fieldName  the field name to obtain
       * @param breakScope  whether to break scope restrictions using the
       *  <code>setAccessible</code> method. False will only match public fields.
       * @return the Field object
       * @throws IllegalArgumentException if the class or field name is null
       * @throws ReflectionException if an error occurs during reflection
       */
      public static Field getField(Class cls, String fieldName, boolean breakScope) {
          if (cls == null) {
              throw new IllegalArgumentException("The class must not be null");
          }
          if (fieldName == null) {
              throw new IllegalArgumentException("The field name must not be null");
          }
          // Sun Java 1.3 has a bugged implementation of getField hence we write the
          // code ourselves
          
          // getField() will return the Field object with the declaring class
          // set correctly to the class that declares the field. Thus requesting the
          // field on a subclass will return the field from the superclass.
          //
          // priority order for lookup:
          // searchclass private/protected/package/public
          // superclass protected/package/public
          //  private/different package blocks access to further superclasses
          // implementedinterface public
          try {
              // check up the superclass hierarchy
              Class acls = cls;
              Field match = null;
              while (acls != null && acls != Object.class) {
                  // getDeclaredField checks for non-public scopes as well
                  // and it returns accurate results
                  try {
                      Field field = acls.getDeclaredField(fieldName);
                      if (Modifier.isPublic(field.getModifiers()) == false) {
                          field.setAccessible(breakScope);
                          return field;
                      }
                      if (breakScope == false) {
                          // only public acceptable if not breaking scope
                          throw new IllegalAccessException("The field '" + fieldName + 
                              "' was found, but it's scope prevents direct access by 
reflection");
                      }
                      field.setAccessible(true);
                      match = field;
                      break;
                      
                  } catch (NoSuchFieldException ex) {
                      // ignore
                  }
                  // next superclass
                  acls = acls.getSuperclass();
              }
              // check the public interface case. This must be manually searched for
              // incase there is a public supersuperclass field hidden by a 
private/package
              // superclass field.
              // check up the superclass hierarchy
              Class[] ints = cls.getInterfaces();
              for (int i = 0; i < ints.length; i++) {
                  // getField is fine here, because everything is public, and thus it 
works
                  try {
                      Field field = ints[i].getField(fieldName);
                      return field;
                      
                  } catch (NoSuchFieldException ex) {
                      // ignore
                  }
              }
              if (match != null) {
                  return match;
              }
              throw new NoSuchFieldException("The field '" + fieldName + "' could not 
be found");
      
          } catch (ReflectionException ex) {
              throw ex;
          } catch (LinkageError ex) {
              throw new ReflectionException(ReflectionUtils.getThrowableText(
                  ex, "getting field", cls.getName(), null, fieldName), ex);
          } catch (Exception ex) {
              throw new ReflectionException(ReflectionUtils.getThrowableText(
                  ex, "getting field", cls.getName(), null, fieldName), ex);
          }
      }
      
      // -------------------------------------------------------------------------
      
      /**
       * Gets an accessible Field by name respecting scope.
       * Only the specified class will be considered.
       *
       * @param cls  the class to reflect, must not be null
       * @param fieldName  the field name to obtain
       * @return the Field object
       * @throws IllegalArgumentException if the class or field name is null
       * @throws ReflectionException if an error occurs during reflection
       */
      public static Field getFieldExact(Class cls, String fieldName) {
          return getFieldExact(cls, fieldName, false);
      }
      
      /**
       * Gets an accessible Field by name breaking scope if requested.
       * Only the specified class will be considered.
       *
       * @param cls  the class to reflect, must not be null
       * @param fieldName  the field name to obtain
       * @param breakScope  whether to break scope restrictions using the
       *  <code>setAccessible</code> method. False will only match public fields.
       * @return the Field object
       * @throws IllegalArgumentException if the class or field name is null
       * @throws ReflectionException if an error occurs during reflection
       */
      public static Field getFieldExact(Class cls, String fieldName, boolean 
breakScope) {
          if (cls == null) {
              throw new IllegalArgumentException("The class must not be null");
          }
          if (fieldName == null) {
              throw new IllegalArgumentException("The field name must not be null");
          }
          try {
              // only consider the specified class by using getDeclaredField()
              Field field = cls.getDeclaredField(fieldName);
              if (Modifier.isPublic(field.getModifiers()) == false) {
                  if (breakScope) {
                      field.setAccessible(true);
                  } else {
                      throw new IllegalAccessException("The field '" + fieldName + "' 
was found, but it's scope prevents direct access by reflection");
                  }
              }
              return field;
      
          } catch (ReflectionException ex) {
              throw ex;
          } catch (LinkageError ex) {
              throw new ReflectionException(ReflectionUtils.getThrowableText(
                  ex, "getting field", cls.getName(), null, fieldName), ex);
          } catch (Exception ex) {
              throw new ReflectionException(ReflectionUtils.getThrowableText(
                  ex, "getting field", cls.getName(), null, fieldName), ex);
          }
      }
      
      // -------------------------------------------------------------------------
      
      /**
       * Gets a static Field value from a Field object.
       * 
       * @param field  the field to use
       * @return the field value
       * @throws IllegalArgumentException if the field is null or not static
       * @throws ReflectionException if an error occurs during reflection
       */
      public static Object getStaticFieldValue(Field field) {
          if (field == null) {
              throw new IllegalArgumentException("The field must not be null");
          }
          if (Modifier.isStatic(field.getModifiers()) == false) {
              throw new IllegalArgumentException("The field '" + field.getName() + "' 
is not static");
          }
          return getFieldValue(field, (Object) null, false);
      }
      
      /**
       * Gets a static Field value from a Field object.
       * 
       * @param field  the field to use
       * @param breakScope  whether to break scope restrictions using the
       *  <code>setAccessible</code> method. False will only match public methods.
       * @return the field value
       * @throws IllegalArgumentException if the field is null or not static
       * @throws ReflectionException if an error occurs during reflection
       */
      public static Object getStaticFieldValue(Field field, boolean breakScope) {
          if (field == null) {
              throw new IllegalArgumentException("The field must not be null");
          }
          if (Modifier.isStatic(field.getModifiers()) == false) {
              throw new IllegalArgumentException("The field '" + field.getName() + "' 
is not static");
          }
          return getFieldValue(field, (Object) null, breakScope);
      }
      
      /**
       * Gets a Field value from a Field object.
       * 
       * @param field  the field to use
       * @param object  the object to call on, may be null for static fields
       * @return the field value
       * @throws IllegalArgumentException if the field is null
       * @throws ReflectionException if an error occurs during reflection
       */
      public static Object getFieldValue(Field field, Object object) {
          return getFieldValue(field, object, false);
      }
      
      /**
       * Gets a Field value from a Field object.
       * 
       * @param field  the field to use
       * @param object  the object to call on, may be null for static fields
       * @param breakScope  whether to break scope restrictions using the
       *  <code>setAccessible</code> method. False will only match public methods.
       * @return the field value
       * @throws IllegalArgumentException if the field is null
       * @throws ReflectionException if an error occurs during reflection
       */
      public static Object getFieldValue(Field field, Object object, boolean 
breakScope) {
          if (field == null) {
              throw new IllegalArgumentException("The field must not be null");
          }
          try {
              if (breakScope && Modifier.isPublic(field.getModifiers()) == false) {
                  field.setAccessible(true);
              }
              return field.get(object);
      
          } catch (ReflectionException ex) {
              throw ex;
          } catch (LinkageError ex) {
              throw new ReflectionException(ReflectionUtils.getThrowableText(
                  ex, "getting field value", field.getDeclaringClass().getName(), 
null, field.getName()), ex);
          } catch (Exception ex) {
              throw new ReflectionException(ReflectionUtils.getThrowableText(
                  ex, "getting field value", field.getDeclaringClass().getName(), 
null, field.getName()), ex);
          }
      }
      
      // -------------------------------------------------------------------------
      
      /**
       * Gets a static Field value by name. The field must be public.
       * Superclasses will be considered.
       *
       * @param cls  the class to reflect, must not be null
       * @param fieldName  the field name to obtain
       * @return the value of the field
       * @throws IllegalArgumentException if the class or field name is null
       * @throws ReflectionException if an error occurs during reflection
       */
      public static Object getStaticFieldValue(Class cls, String fieldName) {
          return getStaticFieldValue(cls, fieldName, false);
      }
      
      /**
       * Gets a static Field value by name.
       * Only the specified class will be considered.
       *
       * @param cls  the class to reflect, must not be null
       * @param fieldName  the field name to obtain
       * @param breakScope  whether to break scope restrictions using the
       *  <code>setAccessible</code> method. False will only match public fields.
       * @return the Field object
       * @throws IllegalArgumentException if the class or field name is null
       * @throws ReflectionException if an error occurs during reflection
       */
      public static Object getStaticFieldValue(Class cls, String fieldName, boolean 
breakScope) {
          try {
              Field field = getField(cls, fieldName, breakScope);
              if (Modifier.isStatic(field.getModifiers()) == false) {
                  throw new NoSuchMethodException("The field '" + fieldName + "' is 
not static");
              }
              return getStaticFieldValue(field, breakScope);
              
          } catch (ReflectionException ex) {
              throw ex;
          } catch (LinkageError ex) {
              throw new ReflectionException(ReflectionUtils.getThrowableText(
                  ex, "getting field value", cls.getName(), null, fieldName), ex);
          } catch (Exception ex) {
              throw new ReflectionException(ReflectionUtils.getThrowableText(
                  ex, "getting field value", cls.getName(), null, fieldName), ex);
          }
      }
      
      // -------------------------------------------------------------------------
      
      /**
       * Gets a static Field value by name. The field must be public.
       * Only the specified class will be considered.
       *
       * @param cls  the class to reflect, must not be null
       * @param fieldName  the field name to obtain
       * @return the value of the field
       * @throws IllegalArgumentException if the class or field name is null
       * @throws ReflectionException if an error occurs during reflection
       */
      public static Object getStaticFieldValueExact(Class cls, String fieldName) {
          return getStaticFieldValueExact(cls, fieldName, false);
      }
      
      /**
       * Gets a static Field value by name.
       * Only the specified class will be considered.
       *
       * @param cls  the class to reflect, must not be null
       * @param fieldName  the field name to obtain
       * @param breakScope  whether to break scope restrictions using the
       *  <code>setAccessible</code> method. False will only match public fields.
       * @return the Field object
       * @throws IllegalArgumentException if the class or field name is null
       * @throws ReflectionException if an error occurs during reflection
       */
      public static Object getStaticFieldValueExact(Class cls, String fieldName, 
boolean breakScope) {
          try {
              Field field = getFieldExact(cls, fieldName, breakScope);
              if (Modifier.isStatic(field.getModifiers()) == false) {
                  throw new NoSuchMethodException("The field '" + fieldName + "' is 
not static");
              }
              return getStaticFieldValue(field, breakScope);
              
          } catch (ReflectionException ex) {
              throw ex;
          } catch (LinkageError ex) {
              throw new ReflectionException(ReflectionUtils.getThrowableText(
                  ex, "getting field value", cls.getName(), null, fieldName), ex);
          } catch (Exception ex) {
              throw new ReflectionException(ReflectionUtils.getThrowableText(
                  ex, "getting field value", cls.getName(), null, fieldName), ex);
          }
      }
      
      // -------------------------------------------------------------------------
      
      /**
       * Gets a Field value by name. The field must be public.
       * Superclasses will be considered.
       *
       * @param object  the object to reflect, must not be null
       * @param fieldName  the field name to obtain
       * @return the value of the field
       * @throws IllegalArgumentException if the class or field name is null
       * @throws ReflectionException if an error occurs during reflection
       */
      public static Object getFieldValue(Object object, String fieldName) {
          return getFieldValue(object, fieldName, false);
      }
      
      /**
       * Gets a Field value by name.
       * Only the specified class will be considered.
       *
       * @param object  the object to reflect, must not be null
       * @param fieldName  the field name to obtain
       * @param breakScope  whether to break scope restrictions using the
       *  <code>setAccessible</code> method. False will only match public fields.
       * @return the Field object
       * @throws IllegalArgumentException if the class or field name is null
       * @throws ReflectionException if an error occurs during reflection
       */
      public static Object getFieldValue(Object object, String fieldName, boolean 
breakScope) {
          Field field = getField(object.getClass(), fieldName, breakScope);
          return getFieldValue(field, object, breakScope);
      }
      
      // -------------------------------------------------------------------------
      
      /**
       * Gets a Field value by name. The field must be public.
       * Only the class of the specified object will be considered.
       *
       * @param object  the object to reflect, must not be null
       * @param fieldName  the field name to obtain
       * @return the value of the field
       * @throws IllegalArgumentException if the class or field name is null
       * @throws ReflectionException if an error occurs during reflection
       */
      public static Object getFieldValueExact(Object object, String fieldName) {
          return getFieldValueExact(object, fieldName, false);
      }
      
      /**
       * Gets a Field value by name.
       * Only the class of the specified object will be considered.
       *
       * @param object  the object to reflect, must not be null
       * @param fieldName  the field name to obtain
       * @param breakScope  whether to break scope restrictions using the
       *  <code>setAccessible</code> method. False will only match public fields.
       * @return the Field object
       * @throws IllegalArgumentException if the class or field name is null
       * @throws ReflectionException if an error occurs during reflection
       */
      public static Object getFieldValueExact(Object object, String fieldName, boolean 
breakScope) {
          Field field = getFieldExact(object.getClass(), fieldName, breakScope);
          return getFieldValue(field, object, breakScope);
      }
      
  }
  
  
  
  1.1                  
jakarta-commons/lang/src/java/org/apache/commons/lang/reflect/ConstructorUtils.java
  
  Index: ConstructorUtils.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.commons.lang.reflect;
  
  import java.lang.reflect.Constructor;
  import java.lang.reflect.Modifier;
  
  import org.apache.commons.lang.ArrayUtils;
  /**
   * <code>ConstructorUtils</code> contains utility methods for working for
   * constructors by reflection.
   * <p>
   * The ability is provided to break the scoping restrictions coded by the
   * programmer. This can allow classes to be created that shouldn't be, for
   * example new instances of an enumerated type. Thus, this facility should
   * be used with care.
   *
   * @author <a href="mailto:scolebourne@;apache.org">Stephen Colebourne</a>
   * @version $Id: ConstructorUtils.java,v 1.1 2002/10/24 23:12:54 scolebourne Exp $
   */
  public class ConstructorUtils {
  
      /** An empty constructor array */
      public static final Constructor[] EMPTY_CONSTRUCTOR_ARRAY = new Constructor[0];
      
      /**
       * ConstructorUtils instances should NOT be constructed in standard programming.
       * Instead, the class should be used as 
<code>ConstructorUtils.newInstance(...)</code>.
       * This constructor is public to permit tools that require a JavaBean instance
       * to operate.
       */
      public ConstructorUtils() {
      }
  
      // -------------------------------------------------------------------------
      
      /**
       * Gets a public <code>Constructor</code> object by matching the 
       * parameter types as per the Java Language Specification.
       *
       * @param cls  Class object to find constructor for, must not be null
       * @param types  array of Class objects representing parameter types, may be null
       * @return Constructor object
       * @throws ReflectionException if an error occurs during reflection
       * @throws IllegalArgumentException if the class is null
       */
      public static Constructor getConstructor(Class cls, Class[] types) {
          return getConstructor(cls, types, false);
      }
      
      /**
       * Gets a public <code>Constructor</code> object by matching the 
       * parameter types as per the Java Language Specification.
       *
       * @param cls  Class object to find constructor for, must not be null
       * @param types  array of Class objects representing parameter types, may be null
       * @param breakScope  whether to break scope restrictions using the
       *  <code>setAccessible</code> method. False will only match public methods.
       * @return Constructor object
       * @throws ReflectionException if an error occurs during reflection
       * @throws IllegalArgumentException if the class is null
       */
      public static Constructor getConstructor(Class cls, Class[] types, boolean 
breakScope) {
          if (cls == null) {
              throw new IllegalArgumentException("The class must not be null");
          }
          // try exact call first for speed
          try {
              getConstructorExact(cls, types, breakScope);
              
          } catch (ReflectionException ex) {
              if (types == null || types.length == 0) {
                  throw ex;
              }
              if (ex.getCause() instanceof NoSuchMethodException == false) {
                  throw ex;
              }
          }
          // try to find best match
          try {
              Constructor[] cons = cls.getDeclaredConstructors();
              for (int i = 0; i < cons.length; i++) {
                  if (cons[i].getParameterTypes().length == types.length) {
                      // TODO
                  }
              }
              return null;
  
          } catch (ReflectionException ex) {
              throw ex;
          } catch (LinkageError ex) {
              throw new ReflectionException(ReflectionUtils.getThrowableText(
                  ex, "getting constructor", cls.getName(), types, null), ex);
          } catch (Exception ex) {
              throw new ReflectionException(ReflectionUtils.getThrowableText(
                  ex, "getting constructor", cls.getName(), types, null), ex);
          }
      }
      
      // -------------------------------------------------------------------------
      
      /**
       * Gets a public <code>Constructor</code> object by exactly matching the
       * parameter types.
       *
       * @param cls  Class object to find constructor for, must not be null
       * @param types  array of Class objects representing parameter types, may be null
       * @return Constructor object
       * @throws ReflectionException if an error occurs during reflection
       * @throws IllegalArgumentException if the class is null
       */
      public static Constructor getConstructorExact(Class cls, Class[] types) {
          return getConstructorExact(cls, types, false);
      }
      
      /**
       * Gets a <code>Constructor</code> object by exactly matching the
       * parameter types.
       *
       * @param cls  Class object to find constructor for, must not be null
       * @param types  array of Class objects representing parameter types, may be null
       * @param breakScope  whether to break scope restrictions using the
       *  <code>setAccessible</code> method. False will only match public methods.
       * @return Constructor object
       * @throws ReflectionException if an error occurs during reflection
       * @throws IllegalArgumentException if the class is null
       */
      public static Constructor getConstructorExact(Class cls, Class[] types, boolean 
breakScope) {
          if (cls == null) {
              throw new IllegalArgumentException("The class must not be null");
          }
          try {
              if (breakScope) {
                  Constructor con = cls.getDeclaredConstructor(types);
                  if (Modifier.isPublic(con.getModifiers()) == false) {
                      con.setAccessible(true);
                  }
                  return con;
                  
              } else {
                  return cls.getConstructor(types);
              }
  
          } catch (ReflectionException ex) {
              throw ex;
          } catch (LinkageError ex) {
              throw new ReflectionException(ReflectionUtils.getThrowableText(
                  ex, "getting constructor", cls.getName(), types, null), ex);
          } catch (Exception ex) {
              throw new ReflectionException(ReflectionUtils.getThrowableText(
                  ex, "getting constructor", cls.getName(), types, null), ex);
          }
      }
      
      // -------------------------------------------------------------------------
      
      /**
       * Creates a new instance using a <code>Constructor</code> and parameters.
       * 
       * @param con  Class object to find constructor for, must not be null
       * @param param  the single parameter to pass to the constructor, may be null
       * @return the newly created object
       * @throws ReflectionException if an error occurs during reflection
       * @throws IllegalArgumentException if the constructor is null
       */
      public static Object newInstance(Constructor con, Object param) {
          return newInstance(con, new Object[] {param}, false);
      }
      
      /**
       * Creates a new instance using a <code>Constructor</code> and parameters.
       * 
       * @param con  Class object to find constructor for, must not be null
       * @param params  array of objects to pass as parameters, may be null
       * @return the newly created object
       * @throws ReflectionException if an error occurs during reflection
       * @throws IllegalArgumentException if the constructor is null
       */
      public static Object newInstance(Constructor con, Object[] params) {
          return newInstance(con, params, false);
      }
      
      /**
       * Creates a new instance using a <code>Constructor</code> and parameters.
       * 
       * @param con  Class object to find constructor for, must not be null
       * @param params  array of objects to pass as parameters, may be null
       * @param breakScope  whether to break scope restrictions using the
       *  <code>setAccessible</code> method. False will only match public methods.
       * @return the newly created object
       * @throws ReflectionException if an error occurs during reflection
       * @throws IllegalArgumentException if the constructor is null
       */
      public static Object newInstance(Constructor con, Object[] params, boolean 
breakScope) {
          if (con == null) {
              throw new IllegalArgumentException("The constructor must not be null");
          }
          try {
              if (breakScope && Modifier.isPublic(con.getModifiers()) == false) {
                  con.setAccessible(true);
              }
              return con.newInstance(params);
      
          } catch (ReflectionException ex) {
              throw ex;
          } catch (LinkageError ex) {
              throw new ReflectionException(ReflectionUtils.getThrowableText(
                  ex, "invoking constructor", con.getDeclaringClass().getName(), 
con.getParameterTypes(), null), ex);
          } catch (Exception ex) {
              throw new ReflectionException(ReflectionUtils.getThrowableText(
                  ex, "invoking constructor", con.getDeclaringClass().getName(), 
con.getParameterTypes(), null), ex);
          }
      }
      
      // -------------------------------------------------------------------------
      
      /**
       * Creates a new instance of the specified <code>Class</code> by name.
       * 
       * @param className  String class name to instantiate, must not be empty
       * @return the newly created object
       * @throws ReflectionException if an error occurs during reflection
       * @throws IllegalArgumentException if the class name is empty
       */
      public static Object newInstance(String className) {
          return newInstance(className, false);
      }
      
      /**
       * Creates a new instance of the specified <code>Class</code> by name.
       * If the constructor is not public, <code>setAccessible(true)</code>
       * is used to make it accessible.
       * 
       * @param className  String class name to instantiate, must not be empty
       * @param breakScope  whether to break scope restrictions using the
       *  <code>setAccessible</code> method. False will only match public methods.
       * @return the newly created object
       * @throws ReflectionException if an error occurs during reflection
       * @throws IllegalArgumentException if the class name is empty
       */
      public static Object newInstance(String className, boolean breakScope) {
          Class cls = ReflectionUtils.getClass(className);
          return newInstance(cls, breakScope);
      }
      
      // -------------------------------------------------------------------------
      
      /**
       * Creates a new instance of the specified <code>Class</code>.
       * 
       * @param cls  Class object to instantiate, must not be null
       * @return the newly created object
       * @throws ReflectionException if an error occurs during reflection
       * @throws IllegalArgumentException if the class is null
       */
      public static Object newInstance(Class cls) {
          return newInstance(cls, false);
      }
      
      /**
       * Creates a new instance of the specified <code>Class</code>.
       * If the constructor is not public, <code>setAccessible(true)</code>
       * is used to make it accessible.
       * 
       * @param cls  Class object to instantiate, must not be null
       * @param breakScope  whether to break scope restrictions using the
       *  <code>setAccessible</code> method. False will only match public methods.
       * @return the newly created object
       * @throws ReflectionException if an error occurs during reflection
       * @throws IllegalArgumentException if the class is null
       */
      public static Object newInstance(Class cls, boolean breakScope) {
          if (breakScope) {
              return newInstanceExact(cls, null, null, true);
              
          } else {
              if (cls == null) {
                  throw new IllegalArgumentException("The constructor must not be 
null");
              }
              try {
                  return cls.newInstance();
          
              } catch (ReflectionException ex) {
                  throw ex;
              } catch (LinkageError ex) {
                  throw new ReflectionException(ReflectionUtils.getThrowableText(
                      ex, "instantiating class", cls.getName(), null, null), ex);
              } catch (Exception ex) {
                  throw new ReflectionException(ReflectionUtils.getThrowableText(
                      ex, "instantiating class", cls.getName(), null, null), ex);
              }
          }
      }
      
      // -------------------------------------------------------------------------
      
      /**
       * Creates a new instance of the specified <code>Class</code>.
       * The constructor is found by matching the 
       * parameter types as per the Java Language Specification.
       * 
       * @param cls  Class object to instantiate, must not be null
       * @param types  array of Class objects representing parameter types, may be null
       * @param params  array of objects to pass as parameters, may be null
       * @return the newly created object
       * @throws ReflectionException if an error occurs during reflection
       * @throws IllegalArgumentException if the class is null
       */
      public static Object newInstance(Class cls, Class[] types, Object[] params) {
          return newInstance(cls, types, params, false);
      }
      
      /**
       * Creates a new instance of the specified <code>Class</code>.
       * The constructor is found by matching the 
       * parameter types as per the Java Language Specification.
       * 
       * @param cls  Class object to instantiate, must not be null
       * @param types  array of Class objects representing parameter types, may be null
       * @param params  array of objects to pass as parameters, may be null
       * @param breakScope  whether to break scope restrictions using the
       *  <code>setAccessible</code> method. False will only match public methods.
       * @return the newly created object
       * @throws ReflectionException if an error occurs during reflection
       * @throws IllegalArgumentException if the types and params lengths differ
       * @throws IllegalArgumentException if the class is null
       */
      public static Object newInstance(Class cls, Class[] types, Object[] params, 
boolean breakScope) {
          if (ArrayUtils.isSameLength(types, params) == false) {
              throw new IllegalArgumentException("The types and params lengths must be 
the same");
          }
          Constructor con = getConstructor(cls, types, breakScope);
          return newInstance(con, params, breakScope);
      }
      
      // -------------------------------------------------------------------------
      
      /**
       * Creates a new instance of the specified <code>Class</code>.
       * The constructor is found by matching the parameter types exactly.
       * 
       * @param cls  Class object to instantiate, must not be null
       * @param types  array of Class objects representing parameter types, may be null
       * @param params  array of objects to pass as parameters, may be null
       * @return the newly created object
       * @throws ReflectionException if an error occurs during reflection
       * @throws IllegalArgumentException if the class is null
       */
      public static Object newInstanceExact(Class cls, Class[] types, Object[] params) 
{
          return newInstanceExact(cls, types, params, false);
      }
      
      /**
       * Creates a new instance of the specified <code>Class</code>.
       * The constructor is found by matching the parameter types exactly.
       * 
       * @param cls  Class object to instantiate, must not be null
       * @param types  array of Class objects representing parameter types, may be null
       * @param params  array of objects to pass as parameters, may be null
       * @param breakScope  whether to break scope restrictions using the
       *  <code>setAccessible</code> method. False will only match public methods.
       * @return the newly created object
       * @throws ReflectionException if an error occurs during reflection
       * @throws IllegalArgumentException if the types and params lengths differ
       * @throws IllegalArgumentException if the class is null
       */
      public static Object newInstanceExact(Class cls, Class[] types, Object[] params, 
boolean breakScope) {
          if (ArrayUtils.isSameLength(types, params) == false) {
              throw new IllegalArgumentException("The types and params lengths must be 
the same");
          }
          Constructor con = getConstructorExact(cls, types, breakScope);
          return newInstance(con, params, breakScope);
      }
      
      // -------------------------------------------------------------------------
      
  }
  
  
  
  1.1                  
jakarta-commons/lang/src/java/org/apache/commons/lang/reflect/ReflectionException.java
  
  Index: ReflectionException.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.commons.lang.reflect;
  
  import org.apache.commons.lang.exception.NestableRuntimeException;
  /**
   * Exception thrown when the Reflection process fails. The original
   * error is wrapped within this one.
   *
   * @author <a href="mailto:scolebourne@;joda.org">Stephen Colebourne</a>
   * @version $Id: ReflectionException.java,v 1.1 2002/10/24 23:12:54 scolebourne Exp $
   */
  public class ReflectionException extends NestableRuntimeException {
  
      /**
       * Constructs a new <code>ReflectionException</code> without specified
       * detail message.
       */
      public ReflectionException() {
          super();
      }
  
      /**
       * Constructs a new <code>ReflectionException</code> with specified
       * detail message.
       *
       * @param msg  The error message.
       */
      public ReflectionException(String msg) {
          super(msg);
      }
  
      /**
       * Constructs a new <code>ReflectionException</code> with specified
       * nested <code>Throwable</code>.
       *
       * @param cause  The exception or error that caused this exception
       *               to be thrown.
       */
      public ReflectionException(Throwable cause) {
          super(cause);
      }
  
      /**
       * Constructs a new <code>ReflectionException</code> with specified
       * detail message and nested <code>Throwable</code>.
       *
       * @param msg    The error message.
       * @param cause  The exception or error that caused this exception
       *               to be thrown.
       */
      public ReflectionException(String msg, Throwable cause) {
          super(msg, cause);
      }
  
  }
  
  
  
  1.1                  
jakarta-commons/lang/src/java/org/apache/commons/lang/reflect/ReflectionUtils.java
  
  Index: ReflectionUtils.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.commons.lang.reflect;
  
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.Member;
  import java.lang.reflect.Method;
  import java.lang.reflect.Modifier;
  import java.util.ArrayList;
  import java.util.Iterator;
  import java.util.List;
  
  import org.apache.commons.lang.*;
  import org.apache.commons.lang.ArrayUtils;
  import org.apache.commons.lang.StringUtils;
  /**
   * <code>ReflectionUtils</code> contains utility methods for working for
   * reflection.
   *
   * @author <a href="mailto:scolebourne@;apache.org">Stephen Colebourne</a>
   * @version $Id: ReflectionUtils.java,v 1.1 2002/10/24 23:12:54 scolebourne Exp $
   */
  public class ReflectionUtils {
      
      /**
       * ReflectionUtils instances should NOT be constructed in standard programming.
       * Instead, the class should be used as 
<code>ReflectionUtils.getShortClassName(obj)</code>.
       * This constructor is public to permit tools that require a JavaBean instance
       * to operate.
       */
      public ReflectionUtils() {
      }
  
      // -------------------------------------------------------------------------
      
      /**
       * Tests whether the specified field or method is 
       * <code>static</code>.
       * 
       * @param member  the member to test, must not be null
       * @return true if the member is static
       */
      public static boolean isStatic(Member member) {
          if (member == null) {
              throw new IllegalArgumentException("The member must not be null");
          }    
          return Modifier.isStatic(member.getModifiers());
      }
  
      /**
       * Tests whether the specified field or method is 
       * <code>static</code>.
       * 
       * @param member  the member to test, must not be null
       * @return true if the member is final
       */
      public static boolean isFinal(Member member) {
          if (member == null) {
              throw new IllegalArgumentException("The member must not be null");
          }    
          return Modifier.isFinal(member.getModifiers());
      }
  
      /**
       * Tests whether the specified field, method or constructor is 
       * <code>public</code>.
       * 
       * @param member  the member to test, must not be null
       * @return true if the member is public scoped
       */
      public static boolean isPublicScope(Member member) {
          if (member == null) {
              throw new IllegalArgumentException("The member must not be null");
          }    
          return Modifier.isStatic(member.getModifiers());
      }
  
      /**
       * Tests whether the specified field, method or constructor is 
       * <code>protected</code>.
       * 
       * @param member  the member to test, must not be null
       * @return true if the member is protected scoped
       */
      public static boolean isProtectedScope(Member member) {
          if (member == null) {
              throw new IllegalArgumentException("The member must not be null");
          }    
          return Modifier.isProtected(member.getModifiers());
      }
  
      /**
       * Tests whether the specified field, method or constructor is 
       * package (default) scoped.
       * 
       * @param member  the member to test, must not be null
       * @return true if the member is package scoped
       */
      public static boolean isPackageScope(Member member) {
          return !(isPublicScope(member) || isProtectedScope(member) || 
isPrivateScope(member));
      }
  
      /**
       * Tests whether the specified field, method or constructor is 
       * <code>private</code>.
       * 
       * @param member  the member to test, must not be null
       * @return true if the member is private scoped
       */
      public static boolean isPrivateScope(Member member) {
          if (member == null) {
              throw new IllegalArgumentException("The member must not be null");
          }    
          return Modifier.isPrivate(member.getModifiers());
      }
  
      // -------------------------------------------------------------------------
      
      /**
       * Gets a class object for the specified string.
       *
       * @param className  fully qualified class name to find, must not be empty
       * @return Class object for class
       * @throws ReflectionException if an error occurs during reflection
       * @throws IllegalArgumentException if the class name is empty
       */
      public static Class getClass(String className) throws ReflectionException {
          if (StringUtils.isEmpty(className)) {
              throw new IllegalArgumentException("The class name must not be null");
          }
          try {
              return Class.forName(className);
      
          } catch (LinkageError ex) {
              throw new ReflectionException(getThrowableText(ex, "getting class", 
className, null, null), ex);
          } catch (Exception ex) {
              throw new ReflectionException(getThrowableText(ex, "getting class", 
className, null, null), ex);
          }
      }
      
      // -------------------------------------------------------------------------
      
      /**
       * Checks if the requested Class array is compatable with the specified
       * parameter array.
       * Primitive classes are handled correctly .
       * <p>
       * In other words, a <code>boolean</code> Class will be converted to 
       * a <code>Boolean</code> Class and so on.
       *
       * @param requestedTypes  the class array requested
       * @param paramTypes  the actual class array for the method
       * @return true if the parameters are compatable
       */
      public static boolean isCompatable(Class[] requestedTypes, Class[] paramTypes) {
          if (ArrayUtils.isSameLength(requestedTypes, paramTypes) == false) {
              return false;
          }
          if (requestedTypes == null) {
              requestedTypes = ArrayUtils.EMPTY_CLASS_ARRAY;
          }
          if (paramTypes == null) {
              paramTypes = ArrayUtils.EMPTY_CLASS_ARRAY;
          }
          for (int i = 0; i < requestedTypes.length; i++) {
              if (ClassUtils.isAssignable(requestedTypes[i], paramTypes[i]) == false) {
                  return false;
              }
          }
          return true;
      }
      
      /**
       * Converts a primitive class to its matching object class.
       * Non-primitive classes are unaffected.
       * <p>
       * In other words, a <code>boolean</code> Class will be converted to 
       * a <code>Boolean</code> Class and so on.
       *
       * @param cls  the class to convert
       * @return converted class
       * @throws IllegalArgumentException if the class is null
       */
      public static Class convertPrimitiveClass(Class cls) {
          if (cls == null) {
              throw new IllegalArgumentException("The class must not be null");
          }
          if (cls.isPrimitive()) {
              if (Integer.TYPE.equals(cls)) {
                  return Integer.class;
              } else if (Long.TYPE.equals(cls)) {
                  return Long.class;
              } else if (Boolean.TYPE.equals(cls)) {
                  return Boolean.class;
              } else if (Double.TYPE.equals(cls)) {
                  return Double.class;
              } else if (Float.TYPE.equals(cls)) {
                  return Float.class;
              } else if (Character.TYPE.equals(cls)) {
                  return Character.class;
              } else if (Short.TYPE.equals(cls)) {
                  return Short.class;
              } else if (Byte.TYPE.equals(cls)) {
                  return Byte.class;
              }         
          }
          return cls;
      }
      
      // -------------------------------------------------------------------------
      
      /**
       * Produces nicely formatted informational error messages for reflection errors.
       * 
       * @param th  the throwable
       * @param desc  the short description of the action, such as 'getting field'
       * @param className  the class name being used
       * @param types  the parameter types
       * @param memberName  the name of the field or method
       * @return a suitable error message
       */
      public static String getThrowableText(Throwable th, String desc, String 
className, Class[] types, String memberName) {
          String message = null;
          try {
              throw th;
      
          } catch (NoSuchMethodException ex) {
              message = "the method does not exist";
          } catch (NoSuchFieldException ex) {
              message = "the field does not exist";
          } catch (ClassNotFoundException ex) {
              message = "the class could not be found in the classpath";
          } catch (InvocationTargetException ex) {
              message = "the method threw an exception";
          } catch (InstantiationException ex) {
              message = "the class is abstract/interface/array/primitive";
          } catch (IllegalAccessException ex) {
              message = "the method was not public/accessible";
          } catch (IllegalArgumentException ex) {
              message = "the parameters did not match those expected";
          } catch (SecurityException ex) {
              message = "the security manager prevents reflection";
          } catch (ExceptionInInitializerError ex) {
              message = "the class initialization for static variables threw an 
exception";
          } catch (ClassCircularityError ex) {
              message = "a circularity has been detected while initializing a class";
          } catch (ClassFormatError ex) {
              message = "the class file is malformed or otherwise cannot be 
interpreted as a class";
          } catch (IncompatibleClassChangeError ex) {
              message = "the method references another class that has changed 
incompatibly since compile time";
          } catch (UnsatisfiedLinkError ex) {
              message = "no implementation found for a native method";
          } catch (VerifyError ex) {
              message = "the class file contains an internal inconsistency or security 
problem";
          } catch (NoClassDefFoundError ex) {
              message = "the class references another class that was present at 
compile time but is no longer available";
          } catch (LinkageError ex) {
              message = "the class references another class that has changed 
incompatibly since compile time";
          } catch (Throwable ex) {
              message = null;
          }
          StringBuffer buf = new StringBuffer();
          buf.append(ClassUtils.getShortClassName(th));
          buf.append(" while ");
          buf.append(desc);
          buf.append(" on Class '");
          buf.append(className);
          buf.append("'");
          if (types != null) {
              buf.append(" for types ");
              buf.append(ArrayUtils.toString(types));
          }
          if (memberName != null) {
              buf.append(" for method '");
              buf.append(memberName);
              buf.append("'");
          }
          if (message != null) {
              buf.append(" - ");
              buf.append(message);
          }
          return buf.toString();
      }
      
  }
  
  
  
  1.3       +489 -221  
jakarta-commons/lang/src/java/org/apache/commons/lang/ClassUtils.java
  
  
  
  

--
To unsubscribe, e-mail:   <mailto:commons-dev-unsubscribe@;jakarta.apache.org>
For additional commands, e-mail: <mailto:commons-dev-help@;jakarta.apache.org>

Reply via email to