# HG changeset patch # User Jaroslav Tulach # Date 1354624157 -3600 # Node ID 21b390daf4449bbfb84e04b36e95fa3af6295150 # Parent d29326a16822cca7dc5e0dfbb5a3556b2095fa9c Bringing in few reflection types, in order to support Class.getMethods diff -r d29326a16822 -r 21b390daf444 emul/src/main/java/java/lang/reflect/AccessibleObject.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emul/src/main/java/java/lang/reflect/AccessibleObject.java Tue Dec 04 13:29:17 2012 +0100 @@ -0,0 +1,274 @@ +/* + * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.lang.reflect; + +import java.security.AccessController; +import sun.reflect.Reflection; +import sun.reflect.ReflectionFactory; +import java.lang.annotation.Annotation; + +/** + * The AccessibleObject class is the base class for Field, Method and + * Constructor objects. It provides the ability to flag a reflected + * object as suppressing default Java language access control checks + * when it is used. The access checks--for public, default (package) + * access, protected, and private members--are performed when Fields, + * Methods or Constructors are used to set or get fields, to invoke + * methods, or to create and initialize new instances of classes, + * respectively. + * + *

Setting the {@code accessible} flag in a reflected object + * permits sophisticated applications with sufficient privilege, such + * as Java Object Serialization or other persistence mechanisms, to + * manipulate objects in a manner that would normally be prohibited. + * + *

By default, a reflected object is not accessible. + * + * @see Field + * @see Method + * @see Constructor + * @see ReflectPermission + * + * @since 1.2 + */ +public class AccessibleObject implements AnnotatedElement { + + /** + * The Permission object that is used to check whether a client + * has sufficient privilege to defeat Java language access + * control checks. + */ + static final private java.security.Permission ACCESS_PERMISSION = + new ReflectPermission("suppressAccessChecks"); + + /** + * Convenience method to set the {@code accessible} flag for an + * array of objects with a single security check (for efficiency). + * + *

First, if there is a security manager, its + * {@code checkPermission} method is called with a + * {@code ReflectPermission("suppressAccessChecks")} permission. + * + *

A {@code SecurityException} is raised if {@code flag} is + * {@code true} but accessibility of any of the elements of the input + * {@code array} may not be changed (for example, if the element + * object is a {@link Constructor} object for the class {@link + * java.lang.Class}). In the event of such a SecurityException, the + * accessibility of objects is set to {@code flag} for array elements + * upto (and excluding) the element for which the exception occurred; the + * accessibility of elements beyond (and including) the element for which + * the exception occurred is unchanged. + * + * @param array the array of AccessibleObjects + * @param flag the new value for the {@code accessible} flag + * in each object + * @throws SecurityException if the request is denied. + * @see SecurityManager#checkPermission + * @see java.lang.RuntimePermission + */ + public static void setAccessible(AccessibleObject[] array, boolean flag) + throws SecurityException { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) sm.checkPermission(ACCESS_PERMISSION); + for (int i = 0; i < array.length; i++) { + setAccessible0(array[i], flag); + } + } + + /** + * Set the {@code accessible} flag for this object to + * the indicated boolean value. A value of {@code true} indicates that + * the reflected object should suppress Java language access + * checking when it is used. A value of {@code false} indicates + * that the reflected object should enforce Java language access checks. + * + *

First, if there is a security manager, its + * {@code checkPermission} method is called with a + * {@code ReflectPermission("suppressAccessChecks")} permission. + * + *

A {@code SecurityException} is raised if {@code flag} is + * {@code true} but accessibility of this object may not be changed + * (for example, if this element object is a {@link Constructor} object for + * the class {@link java.lang.Class}). + * + *

A {@code SecurityException} is raised if this object is a {@link + * java.lang.reflect.Constructor} object for the class + * {@code java.lang.Class}, and {@code flag} is true. + * + * @param flag the new value for the {@code accessible} flag + * @throws SecurityException if the request is denied. + * @see SecurityManager#checkPermission + * @see java.lang.RuntimePermission + */ + public void setAccessible(boolean flag) throws SecurityException { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) sm.checkPermission(ACCESS_PERMISSION); + setAccessible0(this, flag); + } + + /* Check that you aren't exposing java.lang.Class.. */ + private static void setAccessible0(AccessibleObject obj, boolean flag) + throws SecurityException + { + if (obj instanceof Constructor && flag == true) { + Constructor c = (Constructor)obj; + if (c.getDeclaringClass() == Class.class) { + throw new SecurityException("Can not make a java.lang.Class" + + " constructor accessible"); + } + } + obj.override = flag; + } + + /** + * Get the value of the {@code accessible} flag for this object. + * + * @return the value of the object's {@code accessible} flag + */ + public boolean isAccessible() { + return override; + } + + /** + * Constructor: only used by the Java Virtual Machine. + */ + protected AccessibleObject() {} + + // Indicates whether language-level access checks are overridden + // by this object. Initializes to "false". This field is used by + // Field, Method, and Constructor. + // + // NOTE: for security purposes, this field must not be visible + // outside this package. + boolean override; + + // Reflection factory used by subclasses for creating field, + // method, and constructor accessors. Note that this is called + // very early in the bootstrapping process. + static final ReflectionFactory reflectionFactory = + AccessController.doPrivileged( + new sun.reflect.ReflectionFactory.GetReflectionFactoryAction()); + + /** + * @throws NullPointerException {@inheritDoc} + * @since 1.5 + */ + public T getAnnotation(Class annotationClass) { + throw new AssertionError("All subclasses should override this method"); + } + + /** + * @throws NullPointerException {@inheritDoc} + * @since 1.5 + */ + public boolean isAnnotationPresent( + Class annotationClass) { + return getAnnotation(annotationClass) != null; + } + + /** + * @since 1.5 + */ + public Annotation[] getAnnotations() { + return getDeclaredAnnotations(); + } + + /** + * @since 1.5 + */ + public Annotation[] getDeclaredAnnotations() { + throw new AssertionError("All subclasses should override this method"); + } + + + // Shared access checking logic. + + // For non-public members or members in package-private classes, + // it is necessary to perform somewhat expensive security checks. + // If the security check succeeds for a given class, it will + // always succeed (it is not affected by the granting or revoking + // of permissions); we speed up the check in the common case by + // remembering the last Class for which the check succeeded. + // + // The simple security check for Constructor is to see if + // the caller has already been seen, verified, and cached. + // (See also Class.newInstance(), which uses a similar method.) + // + // A more complicated security check cache is needed for Method and Field + // The cache can be either null (empty cache), a 2-array of {caller,target}, + // or a caller (with target implicitly equal to this.clazz). + // In the 2-array case, the target is always different from the clazz. + volatile Object securityCheckCache; + + void checkAccess(Class caller, Class clazz, Object obj, int modifiers) + throws IllegalAccessException + { + if (caller == clazz) { // quick check + return; // ACCESS IS OK + } + Object cache = securityCheckCache; // read volatile + Class targetClass = clazz; + if (obj != null + && Modifier.isProtected(modifiers) + && ((targetClass = obj.getClass()) != clazz)) { + // Must match a 2-list of { caller, targetClass }. + if (cache instanceof Class[]) { + Class[] cache2 = (Class[]) cache; + if (cache2[1] == targetClass && + cache2[0] == caller) { + return; // ACCESS IS OK + } + // (Test cache[1] first since range check for [1] + // subsumes range check for [0].) + } + } else if (cache == caller) { + // Non-protected case (or obj.class == this.clazz). + return; // ACCESS IS OK + } + + // If no return, fall through to the slow path. + slowCheckMemberAccess(caller, clazz, obj, modifiers, targetClass); + } + + // Keep all this slow stuff out of line: + void slowCheckMemberAccess(Class caller, Class clazz, Object obj, int modifiers, + Class targetClass) + throws IllegalAccessException + { + Reflection.ensureMemberAccess(caller, clazz, obj, modifiers); + + // Success: Update the cache. + Object cache = ((targetClass == clazz) + ? caller + : new Class[] { caller, targetClass }); + + // Note: The two cache elements are not volatile, + // but they are effectively final. The Java memory model + // guarantees that the initializing stores for the cache + // elements will occur before the volatile write. + securityCheckCache = cache; // write volatile + } +} diff -r d29326a16822 -r 21b390daf444 emul/src/main/java/java/lang/reflect/AnnotatedElement.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emul/src/main/java/java/lang/reflect/AnnotatedElement.java Tue Dec 04 13:29:17 2012 +0100 @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.lang.reflect; + +import java.lang.annotation.Annotation; + +/** + * Represents an annotated element of the program currently running in this + * VM. This interface allows annotations to be read reflectively. All + * annotations returned by methods in this interface are immutable and + * serializable. It is permissible for the caller to modify the + * arrays returned by accessors for array-valued enum members; it will + * have no affect on the arrays returned to other callers. + * + *

If an annotation returned by a method in this interface contains + * (directly or indirectly) a {@link Class}-valued member referring to + * a class that is not accessible in this VM, attempting to read the class + * by calling the relevant Class-returning method on the returned annotation + * will result in a {@link TypeNotPresentException}. + * + *

Similarly, attempting to read an enum-valued member will result in + * a {@link EnumConstantNotPresentException} if the enum constant in the + * annotation is no longer present in the enum type. + * + *

Finally, Attempting to read a member whose definition has evolved + * incompatibly will result in a {@link + * java.lang.annotation.AnnotationTypeMismatchException} or an + * {@link java.lang.annotation.IncompleteAnnotationException}. + * + * @see java.lang.EnumConstantNotPresentException + * @see java.lang.TypeNotPresentException + * @see java.lang.annotation.AnnotationFormatError + * @see java.lang.annotation.AnnotationTypeMismatchException + * @see java.lang.annotation.IncompleteAnnotationException + * @since 1.5 + * @author Josh Bloch + */ +public interface AnnotatedElement { + /** + * Returns true if an annotation for the specified type + * is present on this element, else false. This method + * is designed primarily for convenient access to marker annotations. + * + * @param annotationClass the Class object corresponding to the + * annotation type + * @return true if an annotation for the specified annotation + * type is present on this element, else false + * @throws NullPointerException if the given annotation class is null + * @since 1.5 + */ + boolean isAnnotationPresent(Class annotationClass); + + /** + * Returns this element's annotation for the specified type if + * such an annotation is present, else null. + * + * @param annotationClass the Class object corresponding to the + * annotation type + * @return this element's annotation for the specified annotation type if + * present on this element, else null + * @throws NullPointerException if the given annotation class is null + * @since 1.5 + */ + T getAnnotation(Class annotationClass); + + /** + * Returns all annotations present on this element. (Returns an array + * of length zero if this element has no annotations.) The caller of + * this method is free to modify the returned array; it will have no + * effect on the arrays returned to other callers. + * + * @return all annotations present on this element + * @since 1.5 + */ + Annotation[] getAnnotations(); + + /** + * Returns all annotations that are directly present on this + * element. Unlike the other methods in this interface, this method + * ignores inherited annotations. (Returns an array of length zero if + * no annotations are directly present on this element.) The caller of + * this method is free to modify the returned array; it will have no + * effect on the arrays returned to other callers. + * + * @return All annotations directly present on this element + * @since 1.5 + */ + Annotation[] getDeclaredAnnotations(); +} diff -r d29326a16822 -r 21b390daf444 emul/src/main/java/java/lang/reflect/Field.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emul/src/main/java/java/lang/reflect/Field.java Tue Dec 04 13:29:17 2012 +0100 @@ -0,0 +1,1040 @@ +/* + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.lang.reflect; + +import sun.reflect.FieldAccessor; +import sun.reflect.Reflection; +import sun.reflect.generics.repository.FieldRepository; +import sun.reflect.generics.factory.CoreReflectionFactory; +import sun.reflect.generics.factory.GenericsFactory; +import sun.reflect.generics.scope.ClassScope; +import java.lang.annotation.Annotation; +import java.util.Map; +import sun.reflect.annotation.AnnotationParser; + + +/** + * A {@code Field} provides information about, and dynamic access to, a + * single field of a class or an interface. The reflected field may + * be a class (static) field or an instance field. + * + *

A {@code Field} permits widening conversions to occur during a get or + * set access operation, but throws an {@code IllegalArgumentException} if a + * narrowing conversion would occur. + * + * @see Member + * @see java.lang.Class + * @see java.lang.Class#getFields() + * @see java.lang.Class#getField(String) + * @see java.lang.Class#getDeclaredFields() + * @see java.lang.Class#getDeclaredField(String) + * + * @author Kenneth Russell + * @author Nakul Saraiya + */ +public final +class Field extends AccessibleObject implements Member { + + private Class clazz; + private int slot; + // This is guaranteed to be interned by the VM in the 1.4 + // reflection implementation + private String name; + private Class type; + private int modifiers; + // Generics and annotations support + private transient String signature; + // generic info repository; lazily initialized + private transient FieldRepository genericInfo; + private byte[] annotations; + // Cached field accessor created without override + private FieldAccessor fieldAccessor; + // Cached field accessor created with override + private FieldAccessor overrideFieldAccessor; + // For sharing of FieldAccessors. This branching structure is + // currently only two levels deep (i.e., one root Field and + // potentially many Field objects pointing to it.) + private Field root; + + // Generics infrastructure + + private String getGenericSignature() {return signature;} + + // Accessor for factory + private GenericsFactory getFactory() { + Class c = getDeclaringClass(); + // create scope and factory + return CoreReflectionFactory.make(c, ClassScope.make(c)); + } + + // Accessor for generic info repository + private FieldRepository getGenericInfo() { + // lazily initialize repository if necessary + if (genericInfo == null) { + // create and cache generic info repository + genericInfo = FieldRepository.make(getGenericSignature(), + getFactory()); + } + return genericInfo; //return cached repository + } + + + /** + * Package-private constructor used by ReflectAccess to enable + * instantiation of these objects in Java code from the java.lang + * package via sun.reflect.LangReflectAccess. + */ + Field(Class declaringClass, + String name, + Class type, + int modifiers, + int slot, + String signature, + byte[] annotations) + { + this.clazz = declaringClass; + this.name = name; + this.type = type; + this.modifiers = modifiers; + this.slot = slot; + this.signature = signature; + this.annotations = annotations; + } + + /** + * Package-private routine (exposed to java.lang.Class via + * ReflectAccess) which returns a copy of this Field. The copy's + * "root" field points to this Field. + */ + Field copy() { + // This routine enables sharing of FieldAccessor objects + // among Field objects which refer to the same underlying + // method in the VM. (All of this contortion is only necessary + // because of the "accessibility" bit in AccessibleObject, + // which implicitly requires that new java.lang.reflect + // objects be fabricated for each reflective call on Class + // objects.) + Field res = new Field(clazz, name, type, modifiers, slot, signature, annotations); + res.root = this; + // Might as well eagerly propagate this if already present + res.fieldAccessor = fieldAccessor; + res.overrideFieldAccessor = overrideFieldAccessor; + return res; + } + + /** + * Returns the {@code Class} object representing the class or interface + * that declares the field represented by this {@code Field} object. + */ + public Class getDeclaringClass() { + return clazz; + } + + /** + * Returns the name of the field represented by this {@code Field} object. + */ + public String getName() { + return name; + } + + /** + * Returns the Java language modifiers for the field represented + * by this {@code Field} object, as an integer. The {@code Modifier} class should + * be used to decode the modifiers. + * + * @see Modifier + */ + public int getModifiers() { + return modifiers; + } + + /** + * Returns {@code true} if this field represents an element of + * an enumerated type; returns {@code false} otherwise. + * + * @return {@code true} if and only if this field represents an element of + * an enumerated type. + * @since 1.5 + */ + public boolean isEnumConstant() { + return (getModifiers() & Modifier.ENUM) != 0; + } + + /** + * Returns {@code true} if this field is a synthetic + * field; returns {@code false} otherwise. + * + * @return true if and only if this field is a synthetic + * field as defined by the Java Language Specification. + * @since 1.5 + */ + public boolean isSynthetic() { + return Modifier.isSynthetic(getModifiers()); + } + + /** + * Returns a {@code Class} object that identifies the + * declared type for the field represented by this + * {@code Field} object. + * + * @return a {@code Class} object identifying the declared + * type of the field represented by this object + */ + public Class getType() { + return type; + } + + /** + * Returns a {@code Type} object that represents the declared type for + * the field represented by this {@code Field} object. + * + *

If the {@code Type} is a parameterized type, the + * {@code Type} object returned must accurately reflect the + * actual type parameters used in the source code. + * + *

If the type of the underlying field is a type variable or a + * parameterized type, it is created. Otherwise, it is resolved. + * + * @return a {@code Type} object that represents the declared type for + * the field represented by this {@code Field} object + * @throws GenericSignatureFormatError if the generic field + * signature does not conform to the format specified in + * The Java™ Virtual Machine Specification + * @throws TypeNotPresentException if the generic type + * signature of the underlying field refers to a non-existent + * type declaration + * @throws MalformedParameterizedTypeException if the generic + * signature of the underlying field refers to a parameterized type + * that cannot be instantiated for any reason + * @since 1.5 + */ + public Type getGenericType() { + if (getGenericSignature() != null) + return getGenericInfo().getGenericType(); + else + return getType(); + } + + + /** + * Compares this {@code Field} against the specified object. Returns + * true if the objects are the same. Two {@code Field} objects are the same if + * they were declared by the same class and have the same name + * and type. + */ + public boolean equals(Object obj) { + if (obj != null && obj instanceof Field) { + Field other = (Field)obj; + return (getDeclaringClass() == other.getDeclaringClass()) + && (getName() == other.getName()) + && (getType() == other.getType()); + } + return false; + } + + /** + * Returns a hashcode for this {@code Field}. This is computed as the + * exclusive-or of the hashcodes for the underlying field's + * declaring class name and its name. + */ + public int hashCode() { + return getDeclaringClass().getName().hashCode() ^ getName().hashCode(); + } + + /** + * Returns a string describing this {@code Field}. The format is + * the access modifiers for the field, if any, followed + * by the field type, followed by a space, followed by + * the fully-qualified name of the class declaring the field, + * followed by a period, followed by the name of the field. + * For example: + *

+     *    public static final int java.lang.Thread.MIN_PRIORITY
+     *    private int java.io.FileDescriptor.fd
+     * 
+ * + *

The modifiers are placed in canonical order as specified by + * "The Java Language Specification". This is {@code public}, + * {@code protected} or {@code private} first, and then other + * modifiers in the following order: {@code static}, {@code final}, + * {@code transient}, {@code volatile}. + */ + public String toString() { + int mod = getModifiers(); + return (((mod == 0) ? "" : (Modifier.toString(mod) + " ")) + + getTypeName(getType()) + " " + + getTypeName(getDeclaringClass()) + "." + + getName()); + } + + /** + * Returns a string describing this {@code Field}, including + * its generic type. The format is the access modifiers for the + * field, if any, followed by the generic field type, followed by + * a space, followed by the fully-qualified name of the class + * declaring the field, followed by a period, followed by the name + * of the field. + * + *

The modifiers are placed in canonical order as specified by + * "The Java Language Specification". This is {@code public}, + * {@code protected} or {@code private} first, and then other + * modifiers in the following order: {@code static}, {@code final}, + * {@code transient}, {@code volatile}. + * + * @return a string describing this {@code Field}, including + * its generic type + * + * @since 1.5 + */ + public String toGenericString() { + int mod = getModifiers(); + Type fieldType = getGenericType(); + return (((mod == 0) ? "" : (Modifier.toString(mod) + " ")) + + ((fieldType instanceof Class) ? + getTypeName((Class)fieldType): fieldType.toString())+ " " + + getTypeName(getDeclaringClass()) + "." + + getName()); + } + + /** + * Returns the value of the field represented by this {@code Field}, on + * the specified object. The value is automatically wrapped in an + * object if it has a primitive type. + * + *

The underlying field's value is obtained as follows: + * + *

If the underlying field is a static field, the {@code obj} argument + * is ignored; it may be null. + * + *

Otherwise, the underlying field is an instance field. If the + * specified {@code obj} argument is null, the method throws a + * {@code NullPointerException}. If the specified object is not an + * instance of the class or interface declaring the underlying + * field, the method throws an {@code IllegalArgumentException}. + * + *

If this {@code Field} object is enforcing Java language access control, and + * the underlying field is inaccessible, the method throws an + * {@code IllegalAccessException}. + * If the underlying field is static, the class that declared the + * field is initialized if it has not already been initialized. + * + *

Otherwise, the value is retrieved from the underlying instance + * or static field. If the field has a primitive type, the value + * is wrapped in an object before being returned, otherwise it is + * returned as is. + * + *

If the field is hidden in the type of {@code obj}, + * the field's value is obtained according to the preceding rules. + * + * @param obj object from which the represented field's value is + * to be extracted + * @return the value of the represented field in object + * {@code obj}; primitive values are wrapped in an appropriate + * object before being returned + * + * @exception IllegalAccessException if this {@code Field} object + * is enforcing Java language access control and the underlying + * field is inaccessible. + * @exception IllegalArgumentException if the specified object is not an + * instance of the class or interface declaring the underlying + * field (or a subclass or implementor thereof). + * @exception NullPointerException if the specified object is null + * and the field is an instance field. + * @exception ExceptionInInitializerError if the initialization provoked + * by this method fails. + */ + public Object get(Object obj) + throws IllegalArgumentException, IllegalAccessException + { + return getFieldAccessor(obj).get(obj); + } + + /** + * Gets the value of a static or instance {@code boolean} field. + * + * @param obj the object to extract the {@code boolean} value + * from + * @return the value of the {@code boolean} field + * + * @exception IllegalAccessException if this {@code Field} object + * is enforcing Java language access control and the underlying + * field is inaccessible. + * @exception IllegalArgumentException if the specified object is not + * an instance of the class or interface declaring the + * underlying field (or a subclass or implementor + * thereof), or if the field value cannot be + * converted to the type {@code boolean} by a + * widening conversion. + * @exception NullPointerException if the specified object is null + * and the field is an instance field. + * @exception ExceptionInInitializerError if the initialization provoked + * by this method fails. + * @see Field#get + */ + public boolean getBoolean(Object obj) + throws IllegalArgumentException, IllegalAccessException + { + return getFieldAccessor(obj).getBoolean(obj); + } + + /** + * Gets the value of a static or instance {@code byte} field. + * + * @param obj the object to extract the {@code byte} value + * from + * @return the value of the {@code byte} field + * + * @exception IllegalAccessException if this {@code Field} object + * is enforcing Java language access control and the underlying + * field is inaccessible. + * @exception IllegalArgumentException if the specified object is not + * an instance of the class or interface declaring the + * underlying field (or a subclass or implementor + * thereof), or if the field value cannot be + * converted to the type {@code byte} by a + * widening conversion. + * @exception NullPointerException if the specified object is null + * and the field is an instance field. + * @exception ExceptionInInitializerError if the initialization provoked + * by this method fails. + * @see Field#get + */ + public byte getByte(Object obj) + throws IllegalArgumentException, IllegalAccessException + { + return getFieldAccessor(obj).getByte(obj); + } + + /** + * Gets the value of a static or instance field of type + * {@code char} or of another primitive type convertible to + * type {@code char} via a widening conversion. + * + * @param obj the object to extract the {@code char} value + * from + * @return the value of the field converted to type {@code char} + * + * @exception IllegalAccessException if this {@code Field} object + * is enforcing Java language access control and the underlying + * field is inaccessible. + * @exception IllegalArgumentException if the specified object is not + * an instance of the class or interface declaring the + * underlying field (or a subclass or implementor + * thereof), or if the field value cannot be + * converted to the type {@code char} by a + * widening conversion. + * @exception NullPointerException if the specified object is null + * and the field is an instance field. + * @exception ExceptionInInitializerError if the initialization provoked + * by this method fails. + * @see Field#get + */ + public char getChar(Object obj) + throws IllegalArgumentException, IllegalAccessException + { + return getFieldAccessor(obj).getChar(obj); + } + + /** + * Gets the value of a static or instance field of type + * {@code short} or of another primitive type convertible to + * type {@code short} via a widening conversion. + * + * @param obj the object to extract the {@code short} value + * from + * @return the value of the field converted to type {@code short} + * + * @exception IllegalAccessException if this {@code Field} object + * is enforcing Java language access control and the underlying + * field is inaccessible. + * @exception IllegalArgumentException if the specified object is not + * an instance of the class or interface declaring the + * underlying field (or a subclass or implementor + * thereof), or if the field value cannot be + * converted to the type {@code short} by a + * widening conversion. + * @exception NullPointerException if the specified object is null + * and the field is an instance field. + * @exception ExceptionInInitializerError if the initialization provoked + * by this method fails. + * @see Field#get + */ + public short getShort(Object obj) + throws IllegalArgumentException, IllegalAccessException + { + return getFieldAccessor(obj).getShort(obj); + } + + /** + * Gets the value of a static or instance field of type + * {@code int} or of another primitive type convertible to + * type {@code int} via a widening conversion. + * + * @param obj the object to extract the {@code int} value + * from + * @return the value of the field converted to type {@code int} + * + * @exception IllegalAccessException if this {@code Field} object + * is enforcing Java language access control and the underlying + * field is inaccessible. + * @exception IllegalArgumentException if the specified object is not + * an instance of the class or interface declaring the + * underlying field (or a subclass or implementor + * thereof), or if the field value cannot be + * converted to the type {@code int} by a + * widening conversion. + * @exception NullPointerException if the specified object is null + * and the field is an instance field. + * @exception ExceptionInInitializerError if the initialization provoked + * by this method fails. + * @see Field#get + */ + public int getInt(Object obj) + throws IllegalArgumentException, IllegalAccessException + { + return getFieldAccessor(obj).getInt(obj); + } + + /** + * Gets the value of a static or instance field of type + * {@code long} or of another primitive type convertible to + * type {@code long} via a widening conversion. + * + * @param obj the object to extract the {@code long} value + * from + * @return the value of the field converted to type {@code long} + * + * @exception IllegalAccessException if this {@code Field} object + * is enforcing Java language access control and the underlying + * field is inaccessible. + * @exception IllegalArgumentException if the specified object is not + * an instance of the class or interface declaring the + * underlying field (or a subclass or implementor + * thereof), or if the field value cannot be + * converted to the type {@code long} by a + * widening conversion. + * @exception NullPointerException if the specified object is null + * and the field is an instance field. + * @exception ExceptionInInitializerError if the initialization provoked + * by this method fails. + * @see Field#get + */ + public long getLong(Object obj) + throws IllegalArgumentException, IllegalAccessException + { + return getFieldAccessor(obj).getLong(obj); + } + + /** + * Gets the value of a static or instance field of type + * {@code float} or of another primitive type convertible to + * type {@code float} via a widening conversion. + * + * @param obj the object to extract the {@code float} value + * from + * @return the value of the field converted to type {@code float} + * + * @exception IllegalAccessException if this {@code Field} object + * is enforcing Java language access control and the underlying + * field is inaccessible. + * @exception IllegalArgumentException if the specified object is not + * an instance of the class or interface declaring the + * underlying field (or a subclass or implementor + * thereof), or if the field value cannot be + * converted to the type {@code float} by a + * widening conversion. + * @exception NullPointerException if the specified object is null + * and the field is an instance field. + * @exception ExceptionInInitializerError if the initialization provoked + * by this method fails. + * @see Field#get + */ + public float getFloat(Object obj) + throws IllegalArgumentException, IllegalAccessException + { + return getFieldAccessor(obj).getFloat(obj); + } + + /** + * Gets the value of a static or instance field of type + * {@code double} or of another primitive type convertible to + * type {@code double} via a widening conversion. + * + * @param obj the object to extract the {@code double} value + * from + * @return the value of the field converted to type {@code double} + * + * @exception IllegalAccessException if this {@code Field} object + * is enforcing Java language access control and the underlying + * field is inaccessible. + * @exception IllegalArgumentException if the specified object is not + * an instance of the class or interface declaring the + * underlying field (or a subclass or implementor + * thereof), or if the field value cannot be + * converted to the type {@code double} by a + * widening conversion. + * @exception NullPointerException if the specified object is null + * and the field is an instance field. + * @exception ExceptionInInitializerError if the initialization provoked + * by this method fails. + * @see Field#get + */ + public double getDouble(Object obj) + throws IllegalArgumentException, IllegalAccessException + { + return getFieldAccessor(obj).getDouble(obj); + } + + /** + * Sets the field represented by this {@code Field} object on the + * specified object argument to the specified new value. The new + * value is automatically unwrapped if the underlying field has a + * primitive type. + * + *

The operation proceeds as follows: + * + *

If the underlying field is static, the {@code obj} argument is + * ignored; it may be null. + * + *

Otherwise the underlying field is an instance field. If the + * specified object argument is null, the method throws a + * {@code NullPointerException}. If the specified object argument is not + * an instance of the class or interface declaring the underlying + * field, the method throws an {@code IllegalArgumentException}. + * + *

If this {@code Field} object is enforcing Java language access control, and + * the underlying field is inaccessible, the method throws an + * {@code IllegalAccessException}. + * + *

If the underlying field is final, the method throws an + * {@code IllegalAccessException} unless {@code setAccessible(true)} + * has succeeded for this {@code Field} object + * and the field is non-static. Setting a final field in this way + * is meaningful only during deserialization or reconstruction of + * instances of classes with blank final fields, before they are + * made available for access by other parts of a program. Use in + * any other context may have unpredictable effects, including cases + * in which other parts of a program continue to use the original + * value of this field. + * + *

If the underlying field is of a primitive type, an unwrapping + * conversion is attempted to convert the new value to a value of + * a primitive type. If this attempt fails, the method throws an + * {@code IllegalArgumentException}. + * + *

If, after possible unwrapping, the new value cannot be + * converted to the type of the underlying field by an identity or + * widening conversion, the method throws an + * {@code IllegalArgumentException}. + * + *

If the underlying field is static, the class that declared the + * field is initialized if it has not already been initialized. + * + *

The field is set to the possibly unwrapped and widened new value. + * + *

If the field is hidden in the type of {@code obj}, + * the field's value is set according to the preceding rules. + * + * @param obj the object whose field should be modified + * @param value the new value for the field of {@code obj} + * being modified + * + * @exception IllegalAccessException if this {@code Field} object + * is enforcing Java language access control and the underlying + * field is either inaccessible or final. + * @exception IllegalArgumentException if the specified object is not an + * instance of the class or interface declaring the underlying + * field (or a subclass or implementor thereof), + * or if an unwrapping conversion fails. + * @exception NullPointerException if the specified object is null + * and the field is an instance field. + * @exception ExceptionInInitializerError if the initialization provoked + * by this method fails. + */ + public void set(Object obj, Object value) + throws IllegalArgumentException, IllegalAccessException + { + getFieldAccessor(obj).set(obj, value); + } + + /** + * Sets the value of a field as a {@code boolean} on the specified object. + * This method is equivalent to + * {@code set(obj, zObj)}, + * where {@code zObj} is a {@code Boolean} object and + * {@code zObj.booleanValue() == z}. + * + * @param obj the object whose field should be modified + * @param z the new value for the field of {@code obj} + * being modified + * + * @exception IllegalAccessException if this {@code Field} object + * is enforcing Java language access control and the underlying + * field is either inaccessible or final. + * @exception IllegalArgumentException if the specified object is not an + * instance of the class or interface declaring the underlying + * field (or a subclass or implementor thereof), + * or if an unwrapping conversion fails. + * @exception NullPointerException if the specified object is null + * and the field is an instance field. + * @exception ExceptionInInitializerError if the initialization provoked + * by this method fails. + * @see Field#set + */ + public void setBoolean(Object obj, boolean z) + throws IllegalArgumentException, IllegalAccessException + { + getFieldAccessor(obj).setBoolean(obj, z); + } + + /** + * Sets the value of a field as a {@code byte} on the specified object. + * This method is equivalent to + * {@code set(obj, bObj)}, + * where {@code bObj} is a {@code Byte} object and + * {@code bObj.byteValue() == b}. + * + * @param obj the object whose field should be modified + * @param b the new value for the field of {@code obj} + * being modified + * + * @exception IllegalAccessException if this {@code Field} object + * is enforcing Java language access control and the underlying + * field is either inaccessible or final. + * @exception IllegalArgumentException if the specified object is not an + * instance of the class or interface declaring the underlying + * field (or a subclass or implementor thereof), + * or if an unwrapping conversion fails. + * @exception NullPointerException if the specified object is null + * and the field is an instance field. + * @exception ExceptionInInitializerError if the initialization provoked + * by this method fails. + * @see Field#set + */ + public void setByte(Object obj, byte b) + throws IllegalArgumentException, IllegalAccessException + { + getFieldAccessor(obj).setByte(obj, b); + } + + /** + * Sets the value of a field as a {@code char} on the specified object. + * This method is equivalent to + * {@code set(obj, cObj)}, + * where {@code cObj} is a {@code Character} object and + * {@code cObj.charValue() == c}. + * + * @param obj the object whose field should be modified + * @param c the new value for the field of {@code obj} + * being modified + * + * @exception IllegalAccessException if this {@code Field} object + * is enforcing Java language access control and the underlying + * field is either inaccessible or final. + * @exception IllegalArgumentException if the specified object is not an + * instance of the class or interface declaring the underlying + * field (or a subclass or implementor thereof), + * or if an unwrapping conversion fails. + * @exception NullPointerException if the specified object is null + * and the field is an instance field. + * @exception ExceptionInInitializerError if the initialization provoked + * by this method fails. + * @see Field#set + */ + public void setChar(Object obj, char c) + throws IllegalArgumentException, IllegalAccessException + { + getFieldAccessor(obj).setChar(obj, c); + } + + /** + * Sets the value of a field as a {@code short} on the specified object. + * This method is equivalent to + * {@code set(obj, sObj)}, + * where {@code sObj} is a {@code Short} object and + * {@code sObj.shortValue() == s}. + * + * @param obj the object whose field should be modified + * @param s the new value for the field of {@code obj} + * being modified + * + * @exception IllegalAccessException if this {@code Field} object + * is enforcing Java language access control and the underlying + * field is either inaccessible or final. + * @exception IllegalArgumentException if the specified object is not an + * instance of the class or interface declaring the underlying + * field (or a subclass or implementor thereof), + * or if an unwrapping conversion fails. + * @exception NullPointerException if the specified object is null + * and the field is an instance field. + * @exception ExceptionInInitializerError if the initialization provoked + * by this method fails. + * @see Field#set + */ + public void setShort(Object obj, short s) + throws IllegalArgumentException, IllegalAccessException + { + getFieldAccessor(obj).setShort(obj, s); + } + + /** + * Sets the value of a field as an {@code int} on the specified object. + * This method is equivalent to + * {@code set(obj, iObj)}, + * where {@code iObj} is a {@code Integer} object and + * {@code iObj.intValue() == i}. + * + * @param obj the object whose field should be modified + * @param i the new value for the field of {@code obj} + * being modified + * + * @exception IllegalAccessException if this {@code Field} object + * is enforcing Java language access control and the underlying + * field is either inaccessible or final. + * @exception IllegalArgumentException if the specified object is not an + * instance of the class or interface declaring the underlying + * field (or a subclass or implementor thereof), + * or if an unwrapping conversion fails. + * @exception NullPointerException if the specified object is null + * and the field is an instance field. + * @exception ExceptionInInitializerError if the initialization provoked + * by this method fails. + * @see Field#set + */ + public void setInt(Object obj, int i) + throws IllegalArgumentException, IllegalAccessException + { + getFieldAccessor(obj).setInt(obj, i); + } + + /** + * Sets the value of a field as a {@code long} on the specified object. + * This method is equivalent to + * {@code set(obj, lObj)}, + * where {@code lObj} is a {@code Long} object and + * {@code lObj.longValue() == l}. + * + * @param obj the object whose field should be modified + * @param l the new value for the field of {@code obj} + * being modified + * + * @exception IllegalAccessException if this {@code Field} object + * is enforcing Java language access control and the underlying + * field is either inaccessible or final. + * @exception IllegalArgumentException if the specified object is not an + * instance of the class or interface declaring the underlying + * field (or a subclass or implementor thereof), + * or if an unwrapping conversion fails. + * @exception NullPointerException if the specified object is null + * and the field is an instance field. + * @exception ExceptionInInitializerError if the initialization provoked + * by this method fails. + * @see Field#set + */ + public void setLong(Object obj, long l) + throws IllegalArgumentException, IllegalAccessException + { + getFieldAccessor(obj).setLong(obj, l); + } + + /** + * Sets the value of a field as a {@code float} on the specified object. + * This method is equivalent to + * {@code set(obj, fObj)}, + * where {@code fObj} is a {@code Float} object and + * {@code fObj.floatValue() == f}. + * + * @param obj the object whose field should be modified + * @param f the new value for the field of {@code obj} + * being modified + * + * @exception IllegalAccessException if this {@code Field} object + * is enforcing Java language access control and the underlying + * field is either inaccessible or final. + * @exception IllegalArgumentException if the specified object is not an + * instance of the class or interface declaring the underlying + * field (or a subclass or implementor thereof), + * or if an unwrapping conversion fails. + * @exception NullPointerException if the specified object is null + * and the field is an instance field. + * @exception ExceptionInInitializerError if the initialization provoked + * by this method fails. + * @see Field#set + */ + public void setFloat(Object obj, float f) + throws IllegalArgumentException, IllegalAccessException + { + getFieldAccessor(obj).setFloat(obj, f); + } + + /** + * Sets the value of a field as a {@code double} on the specified object. + * This method is equivalent to + * {@code set(obj, dObj)}, + * where {@code dObj} is a {@code Double} object and + * {@code dObj.doubleValue() == d}. + * + * @param obj the object whose field should be modified + * @param d the new value for the field of {@code obj} + * being modified + * + * @exception IllegalAccessException if this {@code Field} object + * is enforcing Java language access control and the underlying + * field is either inaccessible or final. + * @exception IllegalArgumentException if the specified object is not an + * instance of the class or interface declaring the underlying + * field (or a subclass or implementor thereof), + * or if an unwrapping conversion fails. + * @exception NullPointerException if the specified object is null + * and the field is an instance field. + * @exception ExceptionInInitializerError if the initialization provoked + * by this method fails. + * @see Field#set + */ + public void setDouble(Object obj, double d) + throws IllegalArgumentException, IllegalAccessException + { + getFieldAccessor(obj).setDouble(obj, d); + } + + // Convenience routine which performs security checks + private FieldAccessor getFieldAccessor(Object obj) + throws IllegalAccessException + { + doSecurityCheck(obj); + boolean ov = override; + FieldAccessor a = (ov)? overrideFieldAccessor : fieldAccessor; + return (a != null)? a : acquireFieldAccessor(ov); + } + + // NOTE that there is no synchronization used here. It is correct + // (though not efficient) to generate more than one FieldAccessor + // for a given Field. However, avoiding synchronization will + // probably make the implementation more scalable. + private FieldAccessor acquireFieldAccessor(boolean overrideFinalCheck) { + // First check to see if one has been created yet, and take it + // if so + FieldAccessor tmp = null; + if (root != null) tmp = root.getFieldAccessor(overrideFinalCheck); + if (tmp != null) { + if (overrideFinalCheck) + overrideFieldAccessor = tmp; + else + fieldAccessor = tmp; + } else { + // Otherwise fabricate one and propagate it up to the root + tmp = reflectionFactory.newFieldAccessor(this, overrideFinalCheck); + setFieldAccessor(tmp, overrideFinalCheck); + } + + return tmp; + } + + // Returns FieldAccessor for this Field object, not looking up + // the chain to the root + private FieldAccessor getFieldAccessor(boolean overrideFinalCheck) { + return (overrideFinalCheck)? overrideFieldAccessor : fieldAccessor; + } + + // Sets the FieldAccessor for this Field object and + // (recursively) its root + private void setFieldAccessor(FieldAccessor accessor, boolean overrideFinalCheck) { + if (overrideFinalCheck) + overrideFieldAccessor = accessor; + else + fieldAccessor = accessor; + // Propagate up + if (root != null) { + root.setFieldAccessor(accessor, overrideFinalCheck); + } + } + + // NOTE: be very careful if you change the stack depth of this + // routine. The depth of the "getCallerClass" call is hardwired so + // that the compiler can have an easier time if this gets inlined. + private void doSecurityCheck(Object obj) throws IllegalAccessException { + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + Class caller = Reflection.getCallerClass(4); + + checkAccess(caller, clazz, obj, modifiers); + } + } + } + + /* + * Utility routine to paper over array type names + */ + static String getTypeName(Class type) { + if (type.isArray()) { + try { + Class cl = type; + int dimensions = 0; + while (cl.isArray()) { + dimensions++; + cl = cl.getComponentType(); + } + StringBuffer sb = new StringBuffer(); + sb.append(cl.getName()); + for (int i = 0; i < dimensions; i++) { + sb.append("[]"); + } + return sb.toString(); + } catch (Throwable e) { /*FALLTHRU*/ } + } + return type.getName(); + } + + /** + * @throws NullPointerException {@inheritDoc} + * @since 1.5 + */ + public T getAnnotation(Class annotationClass) { + if (annotationClass == null) + throw new NullPointerException(); + + return (T) declaredAnnotations().get(annotationClass); + } + + /** + * @since 1.5 + */ + public Annotation[] getDeclaredAnnotations() { + return AnnotationParser.toArray(declaredAnnotations()); + } + + private transient Map, Annotation> declaredAnnotations; + + private synchronized Map, Annotation> declaredAnnotations() { + if (declaredAnnotations == null) { + declaredAnnotations = AnnotationParser.parseAnnotations( + annotations, sun.misc.SharedSecrets.getJavaLangAccess(). + getConstantPool(getDeclaringClass()), + getDeclaringClass()); + } + return declaredAnnotations; + } +} diff -r d29326a16822 -r 21b390daf444 emul/src/main/java/java/lang/reflect/GenericDeclaration.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emul/src/main/java/java/lang/reflect/GenericDeclaration.java Tue Dec 04 13:29:17 2012 +0100 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.lang.reflect; + +/** + * A common interface for all entities that declare type variables. + * + * @since 1.5 + */ +public interface GenericDeclaration { + /** + * Returns an array of {@code TypeVariable} objects that + * represent the type variables declared by the generic + * declaration represented by this {@code GenericDeclaration} + * object, in declaration order. Returns an array of length 0 if + * the underlying generic declaration declares no type variables. + * + * @return an array of {@code TypeVariable} objects that represent + * the type variables declared by this generic declaration + * @throws GenericSignatureFormatError if the generic + * signature of this generic declaration does not conform to + * the format specified in + * The Java™ Virtual Machine Specification + */ + public TypeVariable[] getTypeParameters(); +} diff -r d29326a16822 -r 21b390daf444 emul/src/main/java/java/lang/reflect/InvocationTargetException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emul/src/main/java/java/lang/reflect/InvocationTargetException.java Tue Dec 04 13:29:17 2012 +0100 @@ -0,0 +1,111 @@ +/* + * Copyright (c) 1996, 2004, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.lang.reflect; + +/** + * InvocationTargetException is a checked exception that wraps + * an exception thrown by an invoked method or constructor. + * + *

As of release 1.4, this exception has been retrofitted to conform to + * the general purpose exception-chaining mechanism. The "target exception" + * that is provided at construction time and accessed via the + * {@link #getTargetException()} method is now known as the cause, + * and may be accessed via the {@link Throwable#getCause()} method, + * as well as the aforementioned "legacy method." + * + * @see Method + * @see Constructor + */ +public class InvocationTargetException extends ReflectiveOperationException { + /** + * Use serialVersionUID from JDK 1.1.X for interoperability + */ + private static final long serialVersionUID = 4085088731926701167L; + + /** + * This field holds the target if the + * InvocationTargetException(Throwable target) constructor was + * used to instantiate the object + * + * @serial + * + */ + private Throwable target; + + /** + * Constructs an {@code InvocationTargetException} with + * {@code null} as the target exception. + */ + protected InvocationTargetException() { + super((Throwable)null); // Disallow initCause + } + + /** + * Constructs a InvocationTargetException with a target exception. + * + * @param target the target exception + */ + public InvocationTargetException(Throwable target) { + super((Throwable)null); // Disallow initCause + this.target = target; + } + + /** + * Constructs a InvocationTargetException with a target exception + * and a detail message. + * + * @param target the target exception + * @param s the detail message + */ + public InvocationTargetException(Throwable target, String s) { + super(s, null); // Disallow initCause + this.target = target; + } + + /** + * Get the thrown target exception. + * + *

This method predates the general-purpose exception chaining facility. + * The {@link Throwable#getCause()} method is now the preferred means of + * obtaining this information. + * + * @return the thrown target exception (cause of this exception). + */ + public Throwable getTargetException() { + return target; + } + + /** + * Returns the cause of this exception (the thrown target exception, + * which may be {@code null}). + * + * @return the cause of this exception. + * @since 1.4 + */ + public Throwable getCause() { + return target; + } +} diff -r d29326a16822 -r 21b390daf444 emul/src/main/java/java/lang/reflect/Member.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emul/src/main/java/java/lang/reflect/Member.java Tue Dec 04 13:29:17 2012 +0100 @@ -0,0 +1,93 @@ +/* + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.lang.reflect; + +/** + * Member is an interface that reflects identifying information about + * a single member (a field or a method) or a constructor. + * + * @see java.lang.Class + * @see Field + * @see Method + * @see Constructor + * + * @author Nakul Saraiya + */ +public +interface Member { + + /** + * Identifies the set of all public members of a class or interface, + * including inherited members. + * @see java.lang.SecurityManager#checkMemberAccess + */ + public static final int PUBLIC = 0; + + /** + * Identifies the set of declared members of a class or interface. + * Inherited members are not included. + * @see java.lang.SecurityManager#checkMemberAccess + */ + public static final int DECLARED = 1; + + /** + * Returns the Class object representing the class or interface + * that declares the member or constructor represented by this Member. + * + * @return an object representing the declaring class of the + * underlying member + */ + public Class getDeclaringClass(); + + /** + * Returns the simple name of the underlying member or constructor + * represented by this Member. + * + * @return the simple name of the underlying member + */ + public String getName(); + + /** + * Returns the Java language modifiers for the member or + * constructor represented by this Member, as an integer. The + * Modifier class should be used to decode the modifiers in + * the integer. + * + * @return the Java language modifiers for the underlying member + * @see Modifier + */ + public int getModifiers(); + + /** + * Returns {@code true} if this member was introduced by + * the compiler; returns {@code false} otherwise. + * + * @return true if and only if this member was introduced by + * the compiler. + * @since 1.5 + */ + public boolean isSynthetic(); +} diff -r d29326a16822 -r 21b390daf444 emul/src/main/java/java/lang/reflect/Method.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emul/src/main/java/java/lang/reflect/Method.java Tue Dec 04 13:29:17 2012 +0100 @@ -0,0 +1,767 @@ +/* + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.lang.reflect; + +import sun.reflect.MethodAccessor; +import sun.reflect.Reflection; +import sun.reflect.generics.repository.MethodRepository; +import sun.reflect.generics.factory.CoreReflectionFactory; +import sun.reflect.generics.factory.GenericsFactory; +import sun.reflect.generics.scope.MethodScope; +import sun.reflect.annotation.AnnotationType; +import sun.reflect.annotation.AnnotationParser; +import java.lang.annotation.Annotation; +import java.lang.annotation.AnnotationFormatError; +import java.nio.ByteBuffer; +import java.util.Map; + +/** + * A {@code Method} provides information about, and access to, a single method + * on a class or interface. The reflected method may be a class method + * or an instance method (including an abstract method). + * + *

A {@code Method} permits widening conversions to occur when matching the + * actual parameters to invoke with the underlying method's formal + * parameters, but it throws an {@code IllegalArgumentException} if a + * narrowing conversion would occur. + * + * @see Member + * @see java.lang.Class + * @see java.lang.Class#getMethods() + * @see java.lang.Class#getMethod(String, Class[]) + * @see java.lang.Class#getDeclaredMethods() + * @see java.lang.Class#getDeclaredMethod(String, Class[]) + * + * @author Kenneth Russell + * @author Nakul Saraiya + */ +public final + class Method extends AccessibleObject implements GenericDeclaration, + Member { + private Class clazz; + private int slot; + // This is guaranteed to be interned by the VM in the 1.4 + // reflection implementation + private String name; + private Class returnType; + private Class[] parameterTypes; + private Class[] exceptionTypes; + private int modifiers; + // Generics and annotations support + private transient String signature; + // generic info repository; lazily initialized + private transient MethodRepository genericInfo; + private byte[] annotations; + private byte[] parameterAnnotations; + private byte[] annotationDefault; + private volatile MethodAccessor methodAccessor; + // For sharing of MethodAccessors. This branching structure is + // currently only two levels deep (i.e., one root Method and + // potentially many Method objects pointing to it.) + private Method root; + + // Generics infrastructure + + private String getGenericSignature() {return signature;} + + // Accessor for factory + private GenericsFactory getFactory() { + // create scope and factory + return CoreReflectionFactory.make(this, MethodScope.make(this)); + } + + // Accessor for generic info repository + private MethodRepository getGenericInfo() { + // lazily initialize repository if necessary + if (genericInfo == null) { + // create and cache generic info repository + genericInfo = MethodRepository.make(getGenericSignature(), + getFactory()); + } + return genericInfo; //return cached repository + } + + /** + * Package-private constructor used by ReflectAccess to enable + * instantiation of these objects in Java code from the java.lang + * package via sun.reflect.LangReflectAccess. + */ + Method(Class declaringClass, + String name, + Class[] parameterTypes, + Class returnType, + Class[] checkedExceptions, + int modifiers, + int slot, + String signature, + byte[] annotations, + byte[] parameterAnnotations, + byte[] annotationDefault) + { + this.clazz = declaringClass; + this.name = name; + this.parameterTypes = parameterTypes; + this.returnType = returnType; + this.exceptionTypes = checkedExceptions; + this.modifiers = modifiers; + this.slot = slot; + this.signature = signature; + this.annotations = annotations; + this.parameterAnnotations = parameterAnnotations; + this.annotationDefault = annotationDefault; + } + + /** + * Package-private routine (exposed to java.lang.Class via + * ReflectAccess) which returns a copy of this Method. The copy's + * "root" field points to this Method. + */ + Method copy() { + // This routine enables sharing of MethodAccessor objects + // among Method objects which refer to the same underlying + // method in the VM. (All of this contortion is only necessary + // because of the "accessibility" bit in AccessibleObject, + // which implicitly requires that new java.lang.reflect + // objects be fabricated for each reflective call on Class + // objects.) + Method res = new Method(clazz, name, parameterTypes, returnType, + exceptionTypes, modifiers, slot, signature, + annotations, parameterAnnotations, annotationDefault); + res.root = this; + // Might as well eagerly propagate this if already present + res.methodAccessor = methodAccessor; + return res; + } + + /** + * Returns the {@code Class} object representing the class or interface + * that declares the method represented by this {@code Method} object. + */ + public Class getDeclaringClass() { + return clazz; + } + + /** + * Returns the name of the method represented by this {@code Method} + * object, as a {@code String}. + */ + public String getName() { + return name; + } + + /** + * Returns the Java language modifiers for the method represented + * by this {@code Method} object, as an integer. The {@code Modifier} class should + * be used to decode the modifiers. + * + * @see Modifier + */ + public int getModifiers() { + return modifiers; + } + + /** + * Returns an array of {@code TypeVariable} objects that represent the + * type variables declared by the generic declaration represented by this + * {@code GenericDeclaration} object, in declaration order. Returns an + * array of length 0 if the underlying generic declaration declares no type + * variables. + * + * @return an array of {@code TypeVariable} objects that represent + * the type variables declared by this generic declaration + * @throws GenericSignatureFormatError if the generic + * signature of this generic declaration does not conform to + * the format specified in + * The Java™ Virtual Machine Specification + * @since 1.5 + */ + public TypeVariable[] getTypeParameters() { + if (getGenericSignature() != null) + return (TypeVariable[])getGenericInfo().getTypeParameters(); + else + return (TypeVariable[])new TypeVariable[0]; + } + + /** + * Returns a {@code Class} object that represents the formal return type + * of the method represented by this {@code Method} object. + * + * @return the return type for the method this object represents + */ + public Class getReturnType() { + return returnType; + } + + /** + * Returns a {@code Type} object that represents the formal return + * type of the method represented by this {@code Method} object. + * + *

If the return type is a parameterized type, + * the {@code Type} object returned must accurately reflect + * the actual type parameters used in the source code. + * + *

If the return type is a type variable or a parameterized type, it + * is created. Otherwise, it is resolved. + * + * @return a {@code Type} object that represents the formal return + * type of the underlying method + * @throws GenericSignatureFormatError + * if the generic method signature does not conform to the format + * specified in + * The Java™ Virtual Machine Specification + * @throws TypeNotPresentException if the underlying method's + * return type refers to a non-existent type declaration + * @throws MalformedParameterizedTypeException if the + * underlying method's return typed refers to a parameterized + * type that cannot be instantiated for any reason + * @since 1.5 + */ + public Type getGenericReturnType() { + if (getGenericSignature() != null) { + return getGenericInfo().getReturnType(); + } else { return getReturnType();} + } + + + /** + * Returns an array of {@code Class} objects that represent the formal + * parameter types, in declaration order, of the method + * represented by this {@code Method} object. Returns an array of length + * 0 if the underlying method takes no parameters. + * + * @return the parameter types for the method this object + * represents + */ + public Class[] getParameterTypes() { + return (Class[]) parameterTypes.clone(); + } + + /** + * Returns an array of {@code Type} objects that represent the formal + * parameter types, in declaration order, of the method represented by + * this {@code Method} object. Returns an array of length 0 if the + * underlying method takes no parameters. + * + *

If a formal parameter type is a parameterized type, + * the {@code Type} object returned for it must accurately reflect + * the actual type parameters used in the source code. + * + *

If a formal parameter type is a type variable or a parameterized + * type, it is created. Otherwise, it is resolved. + * + * @return an array of Types that represent the formal + * parameter types of the underlying method, in declaration order + * @throws GenericSignatureFormatError + * if the generic method signature does not conform to the format + * specified in + * The Java™ Virtual Machine Specification + * @throws TypeNotPresentException if any of the parameter + * types of the underlying method refers to a non-existent type + * declaration + * @throws MalformedParameterizedTypeException if any of + * the underlying method's parameter types refer to a parameterized + * type that cannot be instantiated for any reason + * @since 1.5 + */ + public Type[] getGenericParameterTypes() { + if (getGenericSignature() != null) + return getGenericInfo().getParameterTypes(); + else + return getParameterTypes(); + } + + + /** + * Returns an array of {@code Class} objects that represent + * the types of the exceptions declared to be thrown + * by the underlying method + * represented by this {@code Method} object. Returns an array of length + * 0 if the method declares no exceptions in its {@code throws} clause. + * + * @return the exception types declared as being thrown by the + * method this object represents + */ + public Class[] getExceptionTypes() { + return (Class[]) exceptionTypes.clone(); + } + + /** + * Returns an array of {@code Type} objects that represent the + * exceptions declared to be thrown by this {@code Method} object. + * Returns an array of length 0 if the underlying method declares + * no exceptions in its {@code throws} clause. + * + *

If an exception type is a type variable or a parameterized + * type, it is created. Otherwise, it is resolved. + * + * @return an array of Types that represent the exception types + * thrown by the underlying method + * @throws GenericSignatureFormatError + * if the generic method signature does not conform to the format + * specified in + * The Java™ Virtual Machine Specification + * @throws TypeNotPresentException if the underlying method's + * {@code throws} clause refers to a non-existent type declaration + * @throws MalformedParameterizedTypeException if + * the underlying method's {@code throws} clause refers to a + * parameterized type that cannot be instantiated for any reason + * @since 1.5 + */ + public Type[] getGenericExceptionTypes() { + Type[] result; + if (getGenericSignature() != null && + ((result = getGenericInfo().getExceptionTypes()).length > 0)) + return result; + else + return getExceptionTypes(); + } + + /** + * Compares this {@code Method} against the specified object. Returns + * true if the objects are the same. Two {@code Methods} are the same if + * they were declared by the same class and have the same name + * and formal parameter types and return type. + */ + public boolean equals(Object obj) { + if (obj != null && obj instanceof Method) { + Method other = (Method)obj; + if ((getDeclaringClass() == other.getDeclaringClass()) + && (getName() == other.getName())) { + if (!returnType.equals(other.getReturnType())) + return false; + /* Avoid unnecessary cloning */ + Class[] params1 = parameterTypes; + Class[] params2 = other.parameterTypes; + if (params1.length == params2.length) { + for (int i = 0; i < params1.length; i++) { + if (params1[i] != params2[i]) + return false; + } + return true; + } + } + } + return false; + } + + /** + * Returns a hashcode for this {@code Method}. The hashcode is computed + * as the exclusive-or of the hashcodes for the underlying + * method's declaring class name and the method's name. + */ + public int hashCode() { + return getDeclaringClass().getName().hashCode() ^ getName().hashCode(); + } + + /** + * Returns a string describing this {@code Method}. The string is + * formatted as the method access modifiers, if any, followed by + * the method return type, followed by a space, followed by the + * class declaring the method, followed by a period, followed by + * the method name, followed by a parenthesized, comma-separated + * list of the method's formal parameter types. If the method + * throws checked exceptions, the parameter list is followed by a + * space, followed by the word throws followed by a + * comma-separated list of the thrown exception types. + * For example: + *

+     *    public boolean java.lang.Object.equals(java.lang.Object)
+     * 
+ * + *

The access modifiers are placed in canonical order as + * specified by "The Java Language Specification". This is + * {@code public}, {@code protected} or {@code private} first, + * and then other modifiers in the following order: + * {@code abstract}, {@code static}, {@code final}, + * {@code synchronized}, {@code native}, {@code strictfp}. + */ + public String toString() { + try { + StringBuilder sb = new StringBuilder(); + int mod = getModifiers() & Modifier.methodModifiers(); + if (mod != 0) { + sb.append(Modifier.toString(mod)).append(' '); + } + sb.append(Field.getTypeName(getReturnType())).append(' '); + sb.append(Field.getTypeName(getDeclaringClass())).append('.'); + sb.append(getName()).append('('); + Class[] params = parameterTypes; // avoid clone + for (int j = 0; j < params.length; j++) { + sb.append(Field.getTypeName(params[j])); + if (j < (params.length - 1)) + sb.append(','); + } + sb.append(')'); + Class[] exceptions = exceptionTypes; // avoid clone + if (exceptions.length > 0) { + sb.append(" throws "); + for (int k = 0; k < exceptions.length; k++) { + sb.append(exceptions[k].getName()); + if (k < (exceptions.length - 1)) + sb.append(','); + } + } + return sb.toString(); + } catch (Exception e) { + return "<" + e + ">"; + } + } + + /** + * Returns a string describing this {@code Method}, including + * type parameters. The string is formatted as the method access + * modifiers, if any, followed by an angle-bracketed + * comma-separated list of the method's type parameters, if any, + * followed by the method's generic return type, followed by a + * space, followed by the class declaring the method, followed by + * a period, followed by the method name, followed by a + * parenthesized, comma-separated list of the method's generic + * formal parameter types. + * + * If this method was declared to take a variable number of + * arguments, instead of denoting the last parameter as + * "Type[]", it is denoted as + * "Type...". + * + * A space is used to separate access modifiers from one another + * and from the type parameters or return type. If there are no + * type parameters, the type parameter list is elided; if the type + * parameter list is present, a space separates the list from the + * class name. If the method is declared to throw exceptions, the + * parameter list is followed by a space, followed by the word + * throws followed by a comma-separated list of the generic thrown + * exception types. If there are no type parameters, the type + * parameter list is elided. + * + *

The access modifiers are placed in canonical order as + * specified by "The Java Language Specification". This is + * {@code public}, {@code protected} or {@code private} first, + * and then other modifiers in the following order: + * {@code abstract}, {@code static}, {@code final}, + * {@code synchronized}, {@code native}, {@code strictfp}. + * + * @return a string describing this {@code Method}, + * include type parameters + * + * @since 1.5 + */ + public String toGenericString() { + try { + StringBuilder sb = new StringBuilder(); + int mod = getModifiers() & Modifier.methodModifiers(); + if (mod != 0) { + sb.append(Modifier.toString(mod)).append(' '); + } + TypeVariable[] typeparms = getTypeParameters(); + if (typeparms.length > 0) { + boolean first = true; + sb.append('<'); + for(TypeVariable typeparm: typeparms) { + if (!first) + sb.append(','); + // Class objects can't occur here; no need to test + // and call Class.getName(). + sb.append(typeparm.toString()); + first = false; + } + sb.append("> "); + } + + Type genRetType = getGenericReturnType(); + sb.append( ((genRetType instanceof Class)? + Field.getTypeName((Class)genRetType):genRetType.toString())) + .append(' '); + + sb.append(Field.getTypeName(getDeclaringClass())).append('.'); + sb.append(getName()).append('('); + Type[] params = getGenericParameterTypes(); + for (int j = 0; j < params.length; j++) { + String param = (params[j] instanceof Class)? + Field.getTypeName((Class)params[j]): + (params[j].toString()); + if (isVarArgs() && (j == params.length - 1)) // replace T[] with T... + param = param.replaceFirst("\\[\\]$", "..."); + sb.append(param); + if (j < (params.length - 1)) + sb.append(','); + } + sb.append(')'); + Type[] exceptions = getGenericExceptionTypes(); + if (exceptions.length > 0) { + sb.append(" throws "); + for (int k = 0; k < exceptions.length; k++) { + sb.append((exceptions[k] instanceof Class)? + ((Class)exceptions[k]).getName(): + exceptions[k].toString()); + if (k < (exceptions.length - 1)) + sb.append(','); + } + } + return sb.toString(); + } catch (Exception e) { + return "<" + e + ">"; + } + } + + /** + * Invokes the underlying method represented by this {@code Method} + * object, on the specified object with the specified parameters. + * Individual parameters are automatically unwrapped to match + * primitive formal parameters, and both primitive and reference + * parameters are subject to method invocation conversions as + * necessary. + * + *

If the underlying method is static, then the specified {@code obj} + * argument is ignored. It may be null. + * + *

If the number of formal parameters required by the underlying method is + * 0, the supplied {@code args} array may be of length 0 or null. + * + *

If the underlying method is an instance method, it is invoked + * using dynamic method lookup as documented in The Java Language + * Specification, Second Edition, section 15.12.4.4; in particular, + * overriding based on the runtime type of the target object will occur. + * + *

If the underlying method is static, the class that declared + * the method is initialized if it has not already been initialized. + * + *

If the method completes normally, the value it returns is + * returned to the caller of invoke; if the value has a primitive + * type, it is first appropriately wrapped in an object. However, + * if the value has the type of an array of a primitive type, the + * elements of the array are not wrapped in objects; in + * other words, an array of primitive type is returned. If the + * underlying method return type is void, the invocation returns + * null. + * + * @param obj the object the underlying method is invoked from + * @param args the arguments used for the method call + * @return the result of dispatching the method represented by + * this object on {@code obj} with parameters + * {@code args} + * + * @exception IllegalAccessException if this {@code Method} object + * is enforcing Java language access control and the underlying + * method is inaccessible. + * @exception IllegalArgumentException if the method is an + * instance method and the specified object argument + * is not an instance of the class or interface + * declaring the underlying method (or of a subclass + * or implementor thereof); if the number of actual + * and formal parameters differ; if an unwrapping + * conversion for primitive arguments fails; or if, + * after possible unwrapping, a parameter value + * cannot be converted to the corresponding formal + * parameter type by a method invocation conversion. + * @exception InvocationTargetException if the underlying method + * throws an exception. + * @exception NullPointerException if the specified object is null + * and the method is an instance method. + * @exception ExceptionInInitializerError if the initialization + * provoked by this method fails. + */ + public Object invoke(Object obj, Object... args) + throws IllegalAccessException, IllegalArgumentException, + InvocationTargetException + { + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + Class caller = Reflection.getCallerClass(1); + + checkAccess(caller, clazz, obj, modifiers); + } + } + MethodAccessor ma = methodAccessor; // read volatile + if (ma == null) { + ma = acquireMethodAccessor(); + } + return ma.invoke(obj, args); + } + + /** + * Returns {@code true} if this method is a bridge + * method; returns {@code false} otherwise. + * + * @return true if and only if this method is a bridge + * method as defined by the Java Language Specification. + * @since 1.5 + */ + public boolean isBridge() { + return (getModifiers() & Modifier.BRIDGE) != 0; + } + + /** + * Returns {@code true} if this method was declared to take + * a variable number of arguments; returns {@code false} + * otherwise. + * + * @return {@code true} if an only if this method was declared to + * take a variable number of arguments. + * @since 1.5 + */ + public boolean isVarArgs() { + return (getModifiers() & Modifier.VARARGS) != 0; + } + + /** + * Returns {@code true} if this method is a synthetic + * method; returns {@code false} otherwise. + * + * @return true if and only if this method is a synthetic + * method as defined by the Java Language Specification. + * @since 1.5 + */ + public boolean isSynthetic() { + return Modifier.isSynthetic(getModifiers()); + } + + // NOTE that there is no synchronization used here. It is correct + // (though not efficient) to generate more than one MethodAccessor + // for a given Method. However, avoiding synchronization will + // probably make the implementation more scalable. + private MethodAccessor acquireMethodAccessor() { + // First check to see if one has been created yet, and take it + // if so + MethodAccessor tmp = null; + if (root != null) tmp = root.getMethodAccessor(); + if (tmp != null) { + methodAccessor = tmp; + } else { + // Otherwise fabricate one and propagate it up to the root + tmp = reflectionFactory.newMethodAccessor(this); + setMethodAccessor(tmp); + } + + return tmp; + } + + // Returns MethodAccessor for this Method object, not looking up + // the chain to the root + MethodAccessor getMethodAccessor() { + return methodAccessor; + } + + // Sets the MethodAccessor for this Method object and + // (recursively) its root + void setMethodAccessor(MethodAccessor accessor) { + methodAccessor = accessor; + // Propagate up + if (root != null) { + root.setMethodAccessor(accessor); + } + } + + /** + * @throws NullPointerException {@inheritDoc} + * @since 1.5 + */ + public T getAnnotation(Class annotationClass) { + if (annotationClass == null) + throw new NullPointerException(); + + return (T) declaredAnnotations().get(annotationClass); + } + + /** + * @since 1.5 + */ + public Annotation[] getDeclaredAnnotations() { + return AnnotationParser.toArray(declaredAnnotations()); + } + + private transient Map, Annotation> declaredAnnotations; + + private synchronized Map, Annotation> declaredAnnotations() { + if (declaredAnnotations == null) { + declaredAnnotations = AnnotationParser.parseAnnotations( + annotations, sun.misc.SharedSecrets.getJavaLangAccess(). + getConstantPool(getDeclaringClass()), + getDeclaringClass()); + } + return declaredAnnotations; + } + + /** + * Returns the default value for the annotation member represented by + * this {@code Method} instance. If the member is of a primitive type, + * an instance of the corresponding wrapper type is returned. Returns + * null if no default is associated with the member, or if the method + * instance does not represent a declared member of an annotation type. + * + * @return the default value for the annotation member represented + * by this {@code Method} instance. + * @throws TypeNotPresentException if the annotation is of type + * {@link Class} and no definition can be found for the + * default class value. + * @since 1.5 + */ + public Object getDefaultValue() { + if (annotationDefault == null) + return null; + Class memberType = AnnotationType.invocationHandlerReturnType( + getReturnType()); + Object result = AnnotationParser.parseMemberValue( + memberType, ByteBuffer.wrap(annotationDefault), + sun.misc.SharedSecrets.getJavaLangAccess(). + getConstantPool(getDeclaringClass()), + getDeclaringClass()); + if (result instanceof sun.reflect.annotation.ExceptionProxy) + throw new AnnotationFormatError("Invalid default: " + this); + return result; + } + + /** + * Returns an array of arrays that represent the annotations on the formal + * parameters, in declaration order, of the method represented by + * this {@code Method} object. (Returns an array of length zero if the + * underlying method is parameterless. If the method has one or more + * parameters, a nested array of length zero is returned for each parameter + * with no annotations.) The annotation objects contained in the returned + * arrays are serializable. The caller of this method is free to modify + * the returned arrays; it will have no effect on the arrays returned to + * other callers. + * + * @return an array of arrays that represent the annotations on the formal + * parameters, in declaration order, of the method represented by this + * Method object + * @since 1.5 + */ + public Annotation[][] getParameterAnnotations() { + int numParameters = parameterTypes.length; + if (parameterAnnotations == null) + return new Annotation[numParameters][0]; + + Annotation[][] result = AnnotationParser.parseParameterAnnotations( + parameterAnnotations, + sun.misc.SharedSecrets.getJavaLangAccess(). + getConstantPool(getDeclaringClass()), + getDeclaringClass()); + if (result.length != numParameters) + throw new java.lang.annotation.AnnotationFormatError( + "Parameter annotations don't match number of parameters"); + return result; + } +} diff -r d29326a16822 -r 21b390daf444 emul/src/main/java/java/lang/reflect/Modifier.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emul/src/main/java/java/lang/reflect/Modifier.java Tue Dec 04 13:29:17 2012 +0100 @@ -0,0 +1,452 @@ +/* + * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.lang.reflect; + +import java.security.AccessController; +import sun.reflect.LangReflectAccess; +import sun.reflect.ReflectionFactory; + +/** + * The Modifier class provides {@code static} methods and + * constants to decode class and member access modifiers. The sets of + * modifiers are represented as integers with distinct bit positions + * representing different modifiers. The values for the constants + * representing the modifiers are taken from the tables in sections 4.1, 4.4, 4.5, and 4.7 of + * The Java™ Virtual Machine Specification. + * + * @see Class#getModifiers() + * @see Member#getModifiers() + * + * @author Nakul Saraiya + * @author Kenneth Russell + */ +public +class Modifier { + + /* + * Bootstrapping protocol between java.lang and java.lang.reflect + * packages + */ + static { + sun.reflect.ReflectionFactory factory = + AccessController.doPrivileged( + new ReflectionFactory.GetReflectionFactoryAction()); + factory.setLangReflectAccess(new java.lang.reflect.ReflectAccess()); + } + + /** + * Return {@code true} if the integer argument includes the + * {@code public} modifier, {@code false} otherwise. + * + * @param mod a set of modifiers + * @return {@code true} if {@code mod} includes the + * {@code public} modifier; {@code false} otherwise. + */ + public static boolean isPublic(int mod) { + return (mod & PUBLIC) != 0; + } + + /** + * Return {@code true} if the integer argument includes the + * {@code private} modifier, {@code false} otherwise. + * + * @param mod a set of modifiers + * @return {@code true} if {@code mod} includes the + * {@code private} modifier; {@code false} otherwise. + */ + public static boolean isPrivate(int mod) { + return (mod & PRIVATE) != 0; + } + + /** + * Return {@code true} if the integer argument includes the + * {@code protected} modifier, {@code false} otherwise. + * + * @param mod a set of modifiers + * @return {@code true} if {@code mod} includes the + * {@code protected} modifier; {@code false} otherwise. + */ + public static boolean isProtected(int mod) { + return (mod & PROTECTED) != 0; + } + + /** + * Return {@code true} if the integer argument includes the + * {@code static} modifier, {@code false} otherwise. + * + * @param mod a set of modifiers + * @return {@code true} if {@code mod} includes the + * {@code static} modifier; {@code false} otherwise. + */ + public static boolean isStatic(int mod) { + return (mod & STATIC) != 0; + } + + /** + * Return {@code true} if the integer argument includes the + * {@code final} modifier, {@code false} otherwise. + * + * @param mod a set of modifiers + * @return {@code true} if {@code mod} includes the + * {@code final} modifier; {@code false} otherwise. + */ + public static boolean isFinal(int mod) { + return (mod & FINAL) != 0; + } + + /** + * Return {@code true} if the integer argument includes the + * {@code synchronized} modifier, {@code false} otherwise. + * + * @param mod a set of modifiers + * @return {@code true} if {@code mod} includes the + * {@code synchronized} modifier; {@code false} otherwise. + */ + public static boolean isSynchronized(int mod) { + return (mod & SYNCHRONIZED) != 0; + } + + /** + * Return {@code true} if the integer argument includes the + * {@code volatile} modifier, {@code false} otherwise. + * + * @param mod a set of modifiers + * @return {@code true} if {@code mod} includes the + * {@code volatile} modifier; {@code false} otherwise. + */ + public static boolean isVolatile(int mod) { + return (mod & VOLATILE) != 0; + } + + /** + * Return {@code true} if the integer argument includes the + * {@code transient} modifier, {@code false} otherwise. + * + * @param mod a set of modifiers + * @return {@code true} if {@code mod} includes the + * {@code transient} modifier; {@code false} otherwise. + */ + public static boolean isTransient(int mod) { + return (mod & TRANSIENT) != 0; + } + + /** + * Return {@code true} if the integer argument includes the + * {@code native} modifier, {@code false} otherwise. + * + * @param mod a set of modifiers + * @return {@code true} if {@code mod} includes the + * {@code native} modifier; {@code false} otherwise. + */ + public static boolean isNative(int mod) { + return (mod & NATIVE) != 0; + } + + /** + * Return {@code true} if the integer argument includes the + * {@code interface} modifier, {@code false} otherwise. + * + * @param mod a set of modifiers + * @return {@code true} if {@code mod} includes the + * {@code interface} modifier; {@code false} otherwise. + */ + public static boolean isInterface(int mod) { + return (mod & INTERFACE) != 0; + } + + /** + * Return {@code true} if the integer argument includes the + * {@code abstract} modifier, {@code false} otherwise. + * + * @param mod a set of modifiers + * @return {@code true} if {@code mod} includes the + * {@code abstract} modifier; {@code false} otherwise. + */ + public static boolean isAbstract(int mod) { + return (mod & ABSTRACT) != 0; + } + + /** + * Return {@code true} if the integer argument includes the + * {@code strictfp} modifier, {@code false} otherwise. + * + * @param mod a set of modifiers + * @return {@code true} if {@code mod} includes the + * {@code strictfp} modifier; {@code false} otherwise. + */ + public static boolean isStrict(int mod) { + return (mod & STRICT) != 0; + } + + /** + * Return a string describing the access modifier flags in + * the specified modifier. For example: + *

+     *    public final synchronized strictfp
+     * 
+ * The modifier names are returned in an order consistent with the + * suggested modifier orderings given in sections 8.1.1, 8.3.1, 8.4.3, 8.8.3, and 9.1.1 of + * The Java™ Language Specification. + * The full modifier ordering used by this method is: + *
{@code + * public protected private abstract static final transient + * volatile synchronized native strictfp + * interface }
+ * The {@code interface} modifier discussed in this class is + * not a true modifier in the Java language and it appears after + * all other modifiers listed by this method. This method may + * return a string of modifiers that are not valid modifiers of a + * Java entity; in other words, no checking is done on the + * possible validity of the combination of modifiers represented + * by the input. + * + * Note that to perform such checking for a known kind of entity, + * such as a constructor or method, first AND the argument of + * {@code toString} with the appropriate mask from a method like + * {@link #constructorModifiers} or {@link #methodModifiers}. + * + * @param mod a set of modifiers + * @return a string representation of the set of modifiers + * represented by {@code mod} + */ + public static String toString(int mod) { + StringBuffer sb = new StringBuffer(); + int len; + + if ((mod & PUBLIC) != 0) sb.append("public "); + if ((mod & PROTECTED) != 0) sb.append("protected "); + if ((mod & PRIVATE) != 0) sb.append("private "); + + /* Canonical order */ + if ((mod & ABSTRACT) != 0) sb.append("abstract "); + if ((mod & STATIC) != 0) sb.append("static "); + if ((mod & FINAL) != 0) sb.append("final "); + if ((mod & TRANSIENT) != 0) sb.append("transient "); + if ((mod & VOLATILE) != 0) sb.append("volatile "); + if ((mod & SYNCHRONIZED) != 0) sb.append("synchronized "); + if ((mod & NATIVE) != 0) sb.append("native "); + if ((mod & STRICT) != 0) sb.append("strictfp "); + if ((mod & INTERFACE) != 0) sb.append("interface "); + + if ((len = sb.length()) > 0) /* trim trailing space */ + return sb.toString().substring(0, len-1); + return ""; + } + + /* + * Access modifier flag constants from tables 4.1, 4.4, 4.5, and 4.7 of + * The Java™ Virtual Machine Specification + */ + + /** + * The {@code int} value representing the {@code public} + * modifier. + */ + public static final int PUBLIC = 0x00000001; + + /** + * The {@code int} value representing the {@code private} + * modifier. + */ + public static final int PRIVATE = 0x00000002; + + /** + * The {@code int} value representing the {@code protected} + * modifier. + */ + public static final int PROTECTED = 0x00000004; + + /** + * The {@code int} value representing the {@code static} + * modifier. + */ + public static final int STATIC = 0x00000008; + + /** + * The {@code int} value representing the {@code final} + * modifier. + */ + public static final int FINAL = 0x00000010; + + /** + * The {@code int} value representing the {@code synchronized} + * modifier. + */ + public static final int SYNCHRONIZED = 0x00000020; + + /** + * The {@code int} value representing the {@code volatile} + * modifier. + */ + public static final int VOLATILE = 0x00000040; + + /** + * The {@code int} value representing the {@code transient} + * modifier. + */ + public static final int TRANSIENT = 0x00000080; + + /** + * The {@code int} value representing the {@code native} + * modifier. + */ + public static final int NATIVE = 0x00000100; + + /** + * The {@code int} value representing the {@code interface} + * modifier. + */ + public static final int INTERFACE = 0x00000200; + + /** + * The {@code int} value representing the {@code abstract} + * modifier. + */ + public static final int ABSTRACT = 0x00000400; + + /** + * The {@code int} value representing the {@code strictfp} + * modifier. + */ + public static final int STRICT = 0x00000800; + + // Bits not (yet) exposed in the public API either because they + // have different meanings for fields and methods and there is no + // way to distinguish between the two in this class, or because + // they are not Java programming language keywords + static final int BRIDGE = 0x00000040; + static final int VARARGS = 0x00000080; + static final int SYNTHETIC = 0x00001000; + static final int ANNOTATION= 0x00002000; + static final int ENUM = 0x00004000; + static boolean isSynthetic(int mod) { + return (mod & SYNTHETIC) != 0; + } + + /** + * See JLSv3 section 8.1.1. + */ + private static final int CLASS_MODIFIERS = + Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE | + Modifier.ABSTRACT | Modifier.STATIC | Modifier.FINAL | + Modifier.STRICT; + + /** + * See JLSv3 section 9.1.1. + */ + private static final int INTERFACE_MODIFIERS = + Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE | + Modifier.ABSTRACT | Modifier.STATIC | Modifier.STRICT; + + + /** + * See JLSv3 section 8.8.3. + */ + private static final int CONSTRUCTOR_MODIFIERS = + Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE; + + /** + * See JLSv3 section 8.4.3. + */ + private static final int METHOD_MODIFIERS = + Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE | + Modifier.ABSTRACT | Modifier.STATIC | Modifier.FINAL | + Modifier.SYNCHRONIZED | Modifier.NATIVE | Modifier.STRICT; + + /** + * See JLSv3 section 8.3.1. + */ + private static final int FIELD_MODIFIERS = + Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE | + Modifier.STATIC | Modifier.FINAL | Modifier.TRANSIENT | + Modifier.VOLATILE; + + /** + * Return an {@code int} value OR-ing together the source language + * modifiers that can be applied to a class. + * @return an {@code int} value OR-ing together the source language + * modifiers that can be applied to a class. + * + * @jls 8.1.1 Class Modifiers + * @since 1.7 + */ + public static int classModifiers() { + return CLASS_MODIFIERS; + } + + /** + * Return an {@code int} value OR-ing together the source language + * modifiers that can be applied to an interface. + * @return an {@code int} value OR-ing together the source language + * modifiers that can be applied to an inteface. + * + * @jls 9.1.1 Interface Modifiers + * @since 1.7 + */ + public static int interfaceModifiers() { + return INTERFACE_MODIFIERS; + } + + /** + * Return an {@code int} value OR-ing together the source language + * modifiers that can be applied to a constructor. + * @return an {@code int} value OR-ing together the source language + * modifiers that can be applied to a constructor. + * + * @jls 8.8.3 Constructor Modifiers + * @since 1.7 + */ + public static int constructorModifiers() { + return CONSTRUCTOR_MODIFIERS; + } + + /** + * Return an {@code int} value OR-ing together the source language + * modifiers that can be applied to a method. + * @return an {@code int} value OR-ing together the source language + * modifiers that can be applied to a method. + * + * @jls 8.4.3 Method Modifiers + * @since 1.7 + */ + public static int methodModifiers() { + return METHOD_MODIFIERS; + } + + + /** + * Return an {@code int} value OR-ing together the source language + * modifiers that can be applied to a field. + * @return an {@code int} value OR-ing together the source language + * modifiers that can be applied to a field. + * + * @jls 8.3.1 Field Modifiers + * @since 1.7 + */ + public static int fieldModifiers() { + return FIELD_MODIFIERS; + } +} diff -r d29326a16822 -r 21b390daf444 emul/src/main/java/java/lang/reflect/Type.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emul/src/main/java/java/lang/reflect/Type.java Tue Dec 04 13:29:17 2012 +0100 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.lang.reflect; + +/** + * Type is the common superinterface for all types in the Java + * programming language. These include raw types, parameterized types, + * array types, type variables and primitive types. + * + * @since 1.5 + */ + +public interface Type { +} diff -r d29326a16822 -r 21b390daf444 emul/src/main/java/java/lang/reflect/TypeVariable.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emul/src/main/java/java/lang/reflect/TypeVariable.java Tue Dec 04 13:29:17 2012 +0100 @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.lang.reflect; + +/** + * TypeVariable is the common superinterface for type variables of kinds. + * A type variable is created the first time it is needed by a reflective + * method, as specified in this package. If a type variable t is referenced + * by a type (i.e, class, interface or annotation type) T, and T is declared + * by the nth enclosing class of T (see JLS 8.1.2), then the creation of t + * requires the resolution (see JVMS 5) of the ith enclosing class of T, + * for i = 0 to n, inclusive. Creating a type variable must not cause the + * creation of its bounds. Repeated creation of a type variable has no effect. + * + *

Multiple objects may be instantiated at run-time to + * represent a given type variable. Even though a type variable is + * created only once, this does not imply any requirement to cache + * instances representing the type variable. However, all instances + * representing a type variable must be equal() to each other. + * As a consequence, users of type variables must not rely on the identity + * of instances of classes implementing this interface. + * + * @param the type of generic declaration that declared the + * underlying type variable. + * + * @since 1.5 + */ +public interface TypeVariable extends Type { + /** + * Returns an array of {@code Type} objects representing the + * upper bound(s) of this type variable. Note that if no upper bound is + * explicitly declared, the upper bound is {@code Object}. + * + *

For each upper bound B:

+ * + * @throws TypeNotPresentException if any of the + * bounds refers to a non-existent type declaration + * @throws MalformedParameterizedTypeException if any of the + * bounds refer to a parameterized type that cannot be instantiated + * for any reason + * @return an array of {@code Type}s representing the upper + * bound(s) of this type variable + */ + Type[] getBounds(); + + /** + * Returns the {@code GenericDeclaration} object representing the + * generic declaration declared this type variable. + * + * @return the generic declaration declared for this type variable. + * + * @since 1.5 + */ + D getGenericDeclaration(); + + /** + * Returns the name of this type variable, as it occurs in the source code. + * + * @return the name of this type variable, as it appears in the source code + */ + String getName(); +} diff -r d29326a16822 -r 21b390daf444 emul/src/main/java/java/lang/reflect/package-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emul/src/main/java/java/lang/reflect/package-info.java Tue Dec 04 13:29:17 2012 +0100 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Provides classes and interfaces for obtaining reflective + * information about classes and objects. Reflection allows + * programmatic access to information about the fields, methods and + * constructors of loaded classes, and the use of reflected fields, + * methods, and constructors to operate on their underlying + * counterparts, within security restrictions. + * + *

{@code AccessibleObject} allows suppression of access checks if + * the necessary {@code ReflectPermission} is available. + * + *

{@code Array} provides static methods to dynamically create and + * access arrays. + * + *

Classes in this package, along with {@code java.lang.Class} + * accommodate applications such as debuggers, interpreters, object + * inspectors, class browsers, and services such as Object + * Serialization and JavaBeans that need access to either the public + * members of a target object (based on its runtime class) or the + * members declared by a given class. + * + * @since JDK1.1 + */ +package java.lang.reflect;