diff options
Diffstat (limited to 'luni-kernel')
40 files changed, 0 insertions, 15124 deletions
diff --git a/luni-kernel/MODULE_LICENSE_APACHE2 b/luni-kernel/MODULE_LICENSE_APACHE2 deleted file mode 100644 index e69de29..0000000 --- a/luni-kernel/MODULE_LICENSE_APACHE2 +++ /dev/null diff --git a/luni-kernel/src/main/java/java/lang/Class.java b/luni-kernel/src/main/java/java/lang/Class.java deleted file mode 100644 index 35e47bc..0000000 --- a/luni-kernel/src/main/java/java/lang/Class.java +++ /dev/null @@ -1,1579 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - * Copyright (C) 2006-2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang; - -import dalvik.system.VMStack; - -import org.apache.harmony.kernel.vm.StringUtils; -import org.apache.harmony.luni.lang.reflect.GenericSignatureParser; -import org.apache.harmony.luni.lang.reflect.Types; - -import java.io.InputStream; -import java.io.Serializable; -import java.lang.annotation.Annotation; -import java.lang.annotation.Inherited; -import java.lang.ref.SoftReference; -import java.lang.reflect.AccessibleObject; -import java.lang.reflect.AnnotatedElement; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.GenericDeclaration; -import java.lang.reflect.Member; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.lang.reflect.Type; -import java.lang.reflect.TypeVariable; -import java.util.Collection; -import java.util.HashMap; -import java.net.URL; -import java.security.ProtectionDomain; - -import static java.lang.ClassCache.REFLECT; -import static java.lang.ClassCache.compareClassLists; -import static java.lang.ClassCache.findMethodByName; -import static java.lang.ClassCache.findFieldByName; - -/** - * The in-memory representation of a Java class. This representation serves as - * the starting point for querying class-related information, a process usually - * called "reflection". There are basically three types of {@code Class} - * instances: those representing real classes and interfaces, those representing - * primitive types, and those representing array classes. - * - * <h4>Class instances representing object types (classes or interfaces)</h4> - * <p> - * These represent an ordinary class or interface as found in the class - * hierarchy. The name associated with these {@code Class} instances is simply - * the fully qualified class name of the class or interface that it represents. - * In addition to this human-readable name, each class is also associated by a - * so-called <em>signature</em>, which is the letter "L", followed by the - * class name and a semicolon (";"). The signature is what the runtime system - * uses internally for identifying the class (for example in a DEX file). - * </p> - * <h4>Classes representing primitive types</h4> - * <p> - * These represent the standard Java primitive types and hence share their - * names (for example "int" for the {@code int} primitive type). Although it is - * not possible to create new instances based on these {@code Class} instances, - * they are still useful for providing reflection information, and as the - * component type of array classes. There is one {@code Class} instance for each - * primitive type, and their signatures are: - * </p> - * <ul> - * <li>{@code B} representing the {@code byte} primitive type</li> - * <li>{@code S} representing the {@code short} primitive type</li> - * <li>{@code I} representing the {@code int} primitive type</li> - * <li>{@code J} representing the {@code long} primitive type</li> - * <li>{@code F} representing the {@code float} primitive type</li> - * <li>{@code D} representing the {@code double} primitive type</li> - * <li>{@code C} representing the {@code char} primitive type</li> - * <li>{@code Z} representing the {@code boolean} primitive type</li> - * <li>{@code V} representing void function return values</li> - * </ul> - * <p> - * <h4>Classes representing array classes</h4> - * <p> - * These represent the classes of Java arrays. There is one such {@code Class} - * instance per combination of array leaf component type and arity (number of - * dimensions). In this case, the name associated with the {@code Class} - * consists of one or more left square brackets (one per dimension in the array) - * followed by the signature of the class representing the leaf component type, - * which can be either an object type or a primitive type. The signature of a - * {@code Class} representing an array type is the same as its name. Examples - * of array class signatures are: - * </p> - * <ul> - * <li>{@code [I} representing the {@code int[]} type</li> - * <li>{@code [Ljava/lang/String;} representing the {@code String[]} type</li> - * <li>{@code [[[C} representing the {@code char[][][]} type (three dimensions!)</li> - * </ul> - */ -public final class Class<T> implements Serializable, AnnotatedElement, GenericDeclaration, Type { - - private static final long serialVersionUID = 3206093459760846163L; - - /** - * This field is initialized by dalvikvm when the class is loaded. - */ - private transient ProtectionDomain pd; - - /** - * null-ok; cache of reflective information, wrapped in a soft - * reference - */ - private transient volatile SoftReference<ClassCache<T>> cacheRef; - - private Class() { - // Prevent this class to be instantiated, instance - // should be created by JVM only - } - - /** - * Get the Signature attribute for this class. Returns null if not found. - */ - private String getSignatureAttribute() { - Object[] annotation = getSignatureAnnotation(); - - if (annotation == null) { - return null; - } - - return StringUtils.combineStrings(annotation); - } - - /** - * Get the Signature annotation for this class. Returns null if not found. - */ - native private Object[] getSignatureAnnotation(); - - /** - * Returns a {@code Class} object which represents the class with the - * specified name. The name should be the name of a class as described in - * the {@link Class class definition}; however, {@code Class}es representing - * primitive types can not be found using this method. - * <p> - * If the class has not been loaded so far, it is being loaded and linked - * first. This is done through either the class loader of the calling class - * or one of its parent class loaders. The class is also being initialized, - * which means that a possible static initializer block is executed. - * - * @param className - * the name of the non-primitive-type class to find. - * @return the named {@code Class} instance. - * @throws ClassNotFoundException - * if the requested class can not be found. - * @throws LinkageError - * if an error occurs during linkage - * @throws ExceptionInInitializerError - * if an exception occurs during static initialization of a - * class. - */ - public static Class<?> forName(String className) throws ClassNotFoundException { - return forName(className, true, VMStack.getCallingClassLoader()); - } - - /** - * Returns a {@code Class} object which represents the class with the - * specified name. The name should be the name of a class as described in - * the {@link Class class definition}, however {@code Class}es representing - * primitive types can not be found using this method. Security rules will - * be obeyed. - * <p> - * If the class has not been loaded so far, it is being loaded and linked - * first. This is done through either the specified class loader or one of - * its parent class loaders. The caller can also request the class to be - * initialized, which means that a possible static initializer block is - * executed. - * - * @param className - * the name of the non-primitive-type class to find. - * @param initializeBoolean - * indicates whether the class should be initialized. - * @param classLoader - * the class loader to use to load the class. - * @return the named {@code Class} instance. - * @throws ClassNotFoundException - * if the requested class can not be found. - * @throws LinkageError - * if an error occurs during linkage - * @throws ExceptionInInitializerError - * if an exception occurs during static initialization of a - * class. - */ - public static Class<?> forName(String className, boolean initializeBoolean, - ClassLoader classLoader) throws ClassNotFoundException { - - if (classLoader == null) { - SecurityManager smgr = System.getSecurityManager(); - if (smgr != null) { - ClassLoader calling = VMStack.getCallingClassLoader(); - if (calling != null) { - smgr.checkPermission(new RuntimePermission("getClassLoader")); - } - } - - classLoader = ClassLoader.getSystemClassLoader(); - } - // Catch an Exception thrown by the underlying native code. It wraps - // up everything inside a ClassNotFoundException, even if e.g. an - // Error occurred during initialization. This as a workaround for - // an ExceptionInInitilaizerError that's also wrapped. It is actually - // expected to be thrown. Maybe the same goes for other errors. - // Not wrapping up all the errors will break android though. - Class<?> result; - try { - result = classForName(className, initializeBoolean, - classLoader); - } catch (ClassNotFoundException e) { - Throwable cause = e.getCause(); - if (cause instanceof ExceptionInInitializerError) { - throw (ExceptionInInitializerError) cause; - } - throw e; - } - return result; - } - - /* - * Returns a class by name without any security checks. - * - * @param className The name of the non-primitive type class to find - * @param initializeBoolean A boolean indicating whether the class should be - * initialized - * @param classLoader The class loader to use to load the class - * @return the named class. - * @throws ClassNotFoundException If the class could not be found - */ - static native Class<?> classForName(String className, boolean initializeBoolean, - ClassLoader classLoader) throws ClassNotFoundException; - - /** - * Returns an array containing {@code Class} objects for all public classes - * and interfaces that are members of this class. This includes public - * members inherited from super classes and interfaces. If there are no such - * class members or if this object represents a primitive type then an array - * of length 0 is returned. - * - * @return the public class members of the class represented by this object. - * @throws SecurityException - * if a security manager exists and it does not allow member - * access. - */ - public Class[] getClasses() { - // BEGIN android-note - // trying to get closer to the RI which returns a raw class array. - // copied from newer version of harmony - // END android-note - checkPublicMemberAccess(); - return getFullListOfClasses(true); - } - - /** - * Returns the annotation of the given type. If there is no such annotation - * then the method returns {@code null}. - * - * @param annotationClass - * the annotation type. - * @return the annotation of the given type, or {@code null} if there is no - * such annotation. - */ - @SuppressWarnings("unchecked") - public <A extends Annotation> A getAnnotation(Class<A> annotationClass) { - Annotation[] list = getAnnotations(); - for (int i = 0; i < list.length; i++) { - if (annotationClass.isInstance(list[i])) { - return (A)list[i]; - } - } - - return null; - } - - /** - * Returns all the annotations of this class. If there are no annotations - * then an empty array is returned. - * - * @return a copy of the array containing this class' annotations. - * @see #getDeclaredAnnotations() - */ - public Annotation[] getAnnotations() { - /* - * We need to get the annotations declared on this class, plus the - * annotations from superclasses that have the "@Inherited" annotation - * set. We create a temporary map to use while we accumulate the - * annotations and convert it to an array at the end. - * - * It's possible to have duplicates when annotations are inherited. - * We use a Map to filter those out. - * - * HashMap might be overkill here. - */ - HashMap<Class, Annotation> map = new HashMap<Class, Annotation>(); - Annotation[] annos = getDeclaredAnnotations(); - - for (int i = annos.length-1; i >= 0; --i) - map.put(annos[i].annotationType(), annos[i]); - - for (Class sup = getSuperclass(); sup != null; - sup = sup.getSuperclass()) { - annos = sup.getDeclaredAnnotations(); - for (int i = annos.length-1; i >= 0; --i) { - Class clazz = annos[i].annotationType(); - if (!map.containsKey(clazz) && - clazz.isAnnotationPresent(Inherited.class)) { - map.put(clazz, annos[i]); - } - } - } - - /* convert annotation values from HashMap to array */ - Collection<Annotation> coll = map.values(); - return coll.toArray(new Annotation[coll.size()]); - } - - /** - * Returns the canonical name of this class. If this class does not have a - * canonical name as defined in the Java Language Specification, then the - * method returns {@code null}. - * - * @return this class' canonical name, or {@code null} if it does not have a - * canonical name. - */ - public String getCanonicalName() { - if (isLocalClass() || isAnonymousClass()) - return null; - - if (isArray()) { - /* - * The canonical name of an array type depends on the (existence of) - * the component type's canonical name. - */ - String name = getComponentType().getCanonicalName(); - if (name != null) { - return name + "[]"; - } - } else if (isMemberClass()) { - /* - * The canonical name of an inner class depends on the (existence - * of) the declaring class' canonical name. - */ - String name = getDeclaringClass().getCanonicalName(); - if (name != null) { - return name + "." + getSimpleName(); - } - } else { - /* - * The canonical name of a top-level class or primitive type is - * equal to the fully qualified name. - */ - return getName(); - } - - /* - * Other classes don't have a canonical name. - */ - return null; - } - - /** - * Returns the class loader which was used to load the class represented by - * this {@code Class}. Implementations are free to return {@code null} for - * classes that were loaded by the bootstrap class loader. The Android - * reference implementation, though, returns a reference to an actual - * representation of the bootstrap class loader. - * - * @return the class loader for the represented class. - * @throws SecurityException - * if a security manager exists and it does not allow accessing - * the class loader. - * @see ClassLoader - */ - public ClassLoader getClassLoader() { - SecurityManager smgr = System.getSecurityManager(); - ClassLoader loader = getClassLoaderImpl(); - if (smgr != null && loader != null) { - ClassLoader calling = VMStack.getCallingClassLoader(); - - if (calling != null && !calling.isAncestorOf(loader)) { - smgr.checkPermission(new RuntimePermission("getClassLoader")); - } - } - - if (this.isPrimitive()) { - return null; - } - - if (loader == null) { - loader = BootClassLoader.getInstance(); - } - - return loader; - } - - /** - * This must be provided by the VM vendor, as it is used by other provided - * class implementations in this package. Outside of this class, it is used - * by SecurityManager.checkMemberAccess(), classLoaderDepth(), - * currentClassLoader() and currentLoadedClass(). Return the ClassLoader for - * this Class without doing any security checks. The bootstrap ClassLoader - * is returned, unlike getClassLoader() which returns null in place of the - * bootstrap ClassLoader. - * - * @return the ClassLoader - * @see ClassLoader#isSystemClassLoader() - */ - ClassLoader getClassLoaderImpl() { - ClassLoader loader = getClassLoader(this); - return loader == null ? BootClassLoader.getInstance() : loader; - } - - /* - * Returns the defining class loader for the given class. - * - * @param clazz the class the class loader of which we want - * @return the class loader - */ - private static native ClassLoader getClassLoader(Class<?> clazz); - - /** - * Returns a {@code Class} object which represents the component type if - * this class represents an array type. Returns {@code null} if this class - * does not represent an array type. The component type of an array type is - * the type of the elements of the array. - * - * @return the component type of this class. - */ - public native Class<?> getComponentType(); - - /** - * Returns a {@code Constructor} object which represents the public - * constructor matching the specified parameter types. - * - * @param parameterTypes - * the parameter types of the requested constructor. - * {@code (Class[]) null} is equivalent to the empty array. - * @return the constructor described by {@code parameterTypes}. - * @throws NoSuchMethodException - * if the constructor can not be found. - * @throws SecurityException - * if a security manager exists and it does not allow member - * access. - * @see #getDeclaredConstructor(Class...) - */ - @SuppressWarnings("unchecked") - public Constructor<T> getConstructor(Class... parameterTypes) throws NoSuchMethodException, - SecurityException { - checkPublicMemberAccess(); - return getMatchingConstructor(getDeclaredConstructors(this, true), parameterTypes); - } - - /** - * Returns an array containing {@code Constructor} objects for all public - * constructors for the class represented by this {@code Class}. If there - * are no public constructors or if this {@code Class} represents an array - * class, a primitive type or void then an empty array is returned. - * - * @return an array with the public constructors of the class represented by - * this {@code Class}. - * @throws SecurityException - * if a security manager exists and it does not allow member - * access. - * @see #getDeclaredConstructors() - */ - public Constructor[] getConstructors() throws SecurityException { - // BEGIN android-note - // trying to get closer to the RI which returns a raw constructor array. - // copied from newer version of harmony - // END android-note - checkPublicMemberAccess(); - return getDeclaredConstructors(this, true); - } - - /** - * Returns the annotations that are directly defined on the class - * represented by this {@code Class}. Annotations that are inherited are not - * included in the result. If there are no annotations at all, an empty - * array is returned. - * - * @return a copy of the array containing the annotations defined for the - * class that this {@code Class} represents. - * @see #getAnnotations() - */ - native public Annotation[] getDeclaredAnnotations(); - - /** - * Returns an array containing {@code Class} objects for all classes and - * interfaces that are declared as members of the class which this {@code - * Class} represents. If there are no classes or interfaces declared or if - * this class represents an array class, a primitive type or void, then an - * empty array is returned. - * - * @return an array with {@code Class} objects for all the classes and - * interfaces that are used in member declarations. - * @throws SecurityException - * if a security manager exists and it does not allow member - * access. - */ - public Class[] getDeclaredClasses() throws SecurityException { - // BEGIN android-note - // trying to get closer to the RI which returns a raw class array. - // copied from newer version of harmony - // END android-note - checkDeclaredMemberAccess(); - return getDeclaredClasses(this, false); - } - - /* - * Returns the list of member classes without performing any security checks - * first. This includes the member classes inherited from superclasses. If no - * member classes exist at all, an empty array is returned. - * - * @param publicOnly reflects whether we want only public members or all of them - * @return the list of classes - */ - private Class<?>[] getFullListOfClasses(boolean publicOnly) { - Class<?>[] result = getDeclaredClasses(this, publicOnly); - - // Traverse all superclasses - Class<?> clazz = this.getSuperclass(); - while (clazz != null) { - Class<?>[] temp = getDeclaredClasses(clazz, publicOnly); - if (temp.length != 0) { - result = arraycopy(new Class[result.length + temp.length], result, temp); - } - - clazz = clazz.getSuperclass(); - } - - return result; - } - - /* - * Returns the list of member classes of the given class. No security checks - * are performed. If no members exist, an empty array is returned. - * - * @param clazz the class the members of which we want - * @param publicOnly reflects whether we want only public member or all of them - * @return the class' class members - */ - native private static Class<?>[] getDeclaredClasses(Class<?> clazz, - boolean publicOnly); - - /** - * Returns a {@code Constructor} object which represents the constructor - * matching the specified parameter types that is declared by the class - * represented by this {@code Class}. - * - * @param parameterTypes - * the parameter types of the requested constructor. - * {@code (Class[]) null} is equivalent to the empty array. - * @return the constructor described by {@code parameterTypes}. - * @throws NoSuchMethodException - * if the requested constructor can not be found. - * @throws SecurityException - * if a security manager exists and it does not allow member - * access. - * @see #getConstructor(Class...) - */ - @SuppressWarnings("unchecked") - public Constructor<T> getDeclaredConstructor(Class... parameterTypes) - throws NoSuchMethodException, SecurityException { - checkDeclaredMemberAccess(); - return getMatchingConstructor(getDeclaredConstructors(this, false), parameterTypes); - } - - /** - * Returns an array containing {@code Constructor} objects for all - * constructors declared in the class represented by this {@code Class}. If - * there are no constructors or if this {@code Class} represents an array - * class, a primitive type or void then an empty array is returned. - * - * @return an array with the constructors declared in the class represented - * by this {@code Class}. - * - * @throws SecurityException - * if a security manager exists and it does not allow member - * access. - * @see #getConstructors() - */ - public Constructor[] getDeclaredConstructors() throws SecurityException { - // BEGIN android-note - // trying to get closer to the RI which returns a raw constructor array. - // copied from newer version of harmony - // END android-note - checkDeclaredMemberAccess(); - return getDeclaredConstructors(this, false); - } - - /* - * Returns the list of constructors without performing any security checks - * first. If no constructors exist, an empty array is returned. - * - * @param clazz the class of interest - * @param publicOnly reflects whether we want only public constructors or all of them - * @return the list of constructors - */ - private static native <T> Constructor<T>[] getDeclaredConstructors(Class<T> clazz, boolean publicOnly); - - /* - * Finds a constructor with a given signature. - * - * @param list the list of constructors to search through - * @param parameterTypes the formal parameter list - * @return the matching constructor - * @throws NoSuchMethodException if the constructor does not exist. - */ - private Constructor<T> getMatchingConstructor( - Constructor<T>[] list, Class<?>[] parameterTypes) - throws NoSuchMethodException { - for (int i = 0; i < list.length; i++) { - if (compareClassLists(list[i].getParameterTypes(), parameterTypes)) { - return list[i]; - } - } - - // BEGIN android-changed - StringBuilder sb = new StringBuilder(); - sb.append(getSimpleName()); - sb.append('('); - boolean first = true; - if (parameterTypes != null) { - for (Class<?> p : parameterTypes) { - if (!first) { - sb.append(','); - } - first = false; - sb.append(p.getSimpleName()); - } - } - sb.append(')'); - throw new NoSuchMethodException(sb.toString()); - // END android-changed - } - - /** - * Returns a {@code Field} object for the field with the specified name - * which is declared in the class represented by this {@code Class}. - * - * @param name - * the name of the requested field. - * @return the requested field in the class represented by this class. - * @throws NoSuchFieldException - * if the requested field can not be found. - * @throws SecurityException - * if a security manager exists and it does not allow member - * access. - * @see #getField(String) - */ - public Field getDeclaredField(String name) - throws NoSuchFieldException, SecurityException { - checkDeclaredMemberAccess(); - - Field[] fields = getClassCache().getDeclaredFields(); - Field field = findFieldByName(fields, name); - - /* - * Make a copy of the private (to the package) object, so that - * setAccessible() won't alter the private instance. - */ - return REFLECT.clone(field); - } - - /** - * Returns an array containing {@code Field} objects for all fields declared - * in the class represented by this {@code Class}. If there are no fields or - * if this {@code Class} represents an array class, a primitive type or void - * then an empty array is returned. - * - * @return an array with the fields declared in the class represented by - * this class. - * @throws SecurityException - * if a security manager exists and it does not allow member - * access. - * @see #getFields() - */ - public Field[] getDeclaredFields() throws SecurityException { - checkDeclaredMemberAccess(); - - // Return a copy of the private (to the package) array. - Field[] fields = getClassCache().getDeclaredFields(); - return ClassCache.deepCopy(fields); - } - - /* - * Returns the list of fields without performing any security checks - * first. If no fields exist at all, an empty array is returned. - * - * @param clazz the class of interest - * @param publicOnly reflects whether we want only public fields or all of them - * @return the list of fields - */ - static native Field[] getDeclaredFields(Class<?> clazz, boolean publicOnly); - - /** - * Returns a {@code Method} object which represents the method matching the - * specified name and parameter types that is declared by the class - * represented by this {@code Class}. - * - * @param name - * the requested method's name. - * @param parameterTypes - * the parameter types of the requested method. - * {@code (Class[]) null} is equivalent to the empty array. - * @return the method described by {@code name} and {@code parameterTypes}. - * @throws NoSuchMethodException - * if the requested constructor can not be found. - * @throws NullPointerException - * if {@code name} is {@code null}. - * @throws SecurityException - * if a security manager exists and it does not allow member - * access. - * @see #getMethod(String, Class...) - */ - public Method getDeclaredMethod(String name, Class... parameterTypes) - throws NoSuchMethodException, SecurityException { - checkDeclaredMemberAccess(); - - Method[] methods = getClassCache().getDeclaredMethods(); - Method method = findMethodByName(methods, name, parameterTypes); - - /* - * Make a copy of the private (to the package) object, so that - * setAccessible() won't alter the private instance. - */ - return REFLECT.clone(method); - } - - /** - * Returns an array containing {@code Method} objects for all methods - * declared in the class represented by this {@code Class}. If there are no - * methods or if this {@code Class} represents an array class, a primitive - * type or void then an empty array is returned. - * - * @return an array with the methods declared in the class represented by - * this {@code Class}. - * @throws SecurityException - * if a security manager exists and it does not allow member - * access. - * @see #getMethods() - */ - public Method[] getDeclaredMethods() throws SecurityException { - checkDeclaredMemberAccess(); - - // Return a copy of the private (to the package) array. - Method[] methods = getClassCache().getDeclaredMethods(); - return ClassCache.deepCopy(methods); - } - - /** - * Returns the list of methods without performing any security checks - * first. If no methods exist, an empty array is returned. - */ - static native Method[] getDeclaredMethods(Class<?> clazz, boolean publicOnly); - - /** - * Gets the {@link ClassCache} for this instance. - * - * @return non-null; the cache object - */ - /*package*/ ClassCache<T> getClassCache() { - /* - * Note: It is innocuous if two threads try to simultaneously - * create the cache, so we don't bother protecting against that. - */ - ClassCache<T> cache = null; - - if (cacheRef != null) { - cache = cacheRef.get(); - } - - if (cache == null) { - cache = new ClassCache<T>(this); - cacheRef = new SoftReference<ClassCache<T>>(cache); - } - - return cache; - } - - /** - * Returns the declaring {@code Class} of this {@code Class}. Returns - * {@code null} if the class is not a member of another class or if this - * {@code Class} represents an array class, a primitive type or void. - * - * @return the declaring {@code Class} or {@code null}. - */ - native public Class<?> getDeclaringClass(); - - /** - * Returns the enclosing {@code Class} of this {@code Class}. If there is no - * enclosing class the method returns {@code null}. - * - * @return the enclosing {@code Class} or {@code null}. - */ - native public Class<?> getEnclosingClass(); - - /** - * Gets the enclosing {@code Constructor} of this {@code Class}, if it is an - * anonymous or local/automatic class; otherwise {@code null}. - * - * @return the enclosing {@code Constructor} instance or {@code null}. - */ - native public Constructor<?> getEnclosingConstructor(); - - /** - * Gets the enclosing {@code Method} of this {@code Class}, if it is an - * anonymous or local/automatic class; otherwise {@code null}. - * - * @return the enclosing {@code Method} instance or {@code null}. - */ - native public Method getEnclosingMethod(); - - /** - * Gets the {@code enum} constants associated with this {@code Class}. - * Returns {@code null} if this {@code Class} does not represent an {@code - * enum} type. - * - * @return an array with the {@code enum} constants or {@code null}. - */ - @SuppressWarnings("unchecked") - public T[] getEnumConstants() { - if (isEnum()) { - checkPublicMemberAccess(); - T[] values = getClassCache().getEnumValuesInOrder(); - - // Copy the private (to the package) array. - return (T[]) values.clone(); - } - - return null; - } - - /** - * Returns a {@code Field} object which represents the public field with the - * specified name. This method first searches the class C represented by - * this {@code Class}, then the interfaces implemented by C and finally the - * superclasses of C. - * - * @param name - * the name of the requested field. - * @return the public field specified by {@code name}. - * @throws NoSuchFieldException - * if the field can not be found. - * @throws SecurityException - * if a security manager exists and it does not allow member - * access. - * @see #getDeclaredField(String) - */ - public Field getField(String name) throws NoSuchFieldException, SecurityException { - checkPublicMemberAccess(); - - Field[] fields = getClassCache().getAllPublicFields(); - Field field = findFieldByName(fields, name); - - /* - * Make a copy of the private (to the package) object, so that - * setAccessible() won't alter the private instance. - */ - return REFLECT.clone(field); - } - - /** - * Returns an array containing {@code Field} objects for all public fields - * for the class C represented by this {@code Class}. Fields may be declared - * in C, the interfaces it implements or in the superclasses of C. The - * elements in the returned array are in no particular order. - * <p> - * If there are no public fields or if this class represents an array class, - * a primitive type or {@code void} then an empty array is returned. - * </p> - * - * @return an array with the public fields of the class represented by this - * {@code Class}. - * @throws SecurityException - * if a security manager exists and it does not allow member - * access. - * @see #getDeclaredFields() - */ - public Field[] getFields() throws SecurityException { - checkPublicMemberAccess(); - - // Return a copy of the private (to the package) array. - Field[] fields = getClassCache().getAllPublicFields(); - return ClassCache.deepCopy(fields); - } - - /** - * Gets the {@link Type}s of the interfaces that this {@code Class} directly - * implements. If the {@code Class} represents a primitive type or {@code - * void} then an empty array is returned. - * - * @return an array of {@link Type} instances directly implemented by the - * class represented by this {@code class}. - */ - public Type[] getGenericInterfaces() { - GenericSignatureParser parser = new GenericSignatureParser( - VMStack.getCallingClassLoader2()); - parser.parseForClass(this, getSignatureAttribute()); - return Types.getClonedTypeArray(parser.interfaceTypes); - } - - /** - * Gets the {@code Type} that represents the superclass of this {@code - * class}. - * - * @return an instance of {@code Type} representing the superclass. - */ - public Type getGenericSuperclass() { - GenericSignatureParser parser = new GenericSignatureParser( - VMStack.getCallingClassLoader2()); - parser.parseForClass(this, getSignatureAttribute()); - return Types.getType(parser.superclassType); - } - - /** - * Returns an array of {@code Class} objects that match the interfaces - * specified in the {@code implements} declaration of the class represented - * by this {@code Class}. The order of the elements in the array is - * identical to the order in the original class declaration. If the class - * does not implement any interfaces, an empty array is returned. - * - * @return an array with the interfaces of the class represented by this - * class. - */ - public native Class[] getInterfaces(); - // BEGIN android-note - // trying to get closer to the RI which returns a raw class array. - // copied from newer version of harmony - // END android-note - - // Changed to raw type to be closer to the RI - /** - * Returns a {@code Method} object which represents the public method with - * the specified name and parameter types. This method first searches the - * class C represented by this {@code Class}, then the superclasses of C and - * finally the interfaces implemented by C and finally the superclasses of C - * for a method with matching name. - * - * @param name - * the requested method's name. - * @param parameterTypes - * the parameter types of the requested method. - * {@code (Class[]) null} is equivalent to the empty array. - * @return the public field specified by {@code name}. - * @throws NoSuchMethodException - * if the method can not be found. - * @throws SecurityException - * if a security manager exists and it does not allow member - * access. - * @see #getDeclaredMethod(String, Class...) - */ - public Method getMethod(String name, Class... parameterTypes) throws NoSuchMethodException, - SecurityException { - checkPublicMemberAccess(); - - Method[] methods = getClassCache().getAllPublicMethods(); - Method method = findMethodByName(methods, name, parameterTypes); - - /* - * Make a copy of the private (to the package) object, so that - * setAccessible() won't alter the private instance. - */ - return REFLECT.clone(method); - } - - /** - * Returns an array containing {@code Method} objects for all public methods - * for the class C represented by this {@code Class}. Methods may be - * declared in C, the interfaces it implements or in the superclasses of C. - * The elements in the returned array are in no particular order. - * <p> - * If there are no public methods or if this {@code Class} represents a - * primitive type or {@code void} then an empty array is returned. - * </p> - * - * @return an array with the methods of the class represented by this - * {@code Class}. - * @throws SecurityException - * if a security manager exists and it does not allow member - * access. - * @see #getDeclaredMethods() - */ - public Method[] getMethods() throws SecurityException { - checkPublicMemberAccess(); - - // Return a copy of the private (to the package) array. - Method[] methods = getClassCache().getAllPublicMethods(); - return ClassCache.deepCopy(methods); - } - - /** - * Performs the security checks regarding the access of a public - * member of this {@code Class}. - * - * <p><b>Note:</b> Because of the {@code getCallingClassLoader2()} - * check, this method must be called exactly one level deep into a - * public method on this instance.</p> - */ - /*package*/ void checkPublicMemberAccess() { - SecurityManager smgr = System.getSecurityManager(); - - if (smgr != null) { - smgr.checkMemberAccess(this, Member.PUBLIC); - - ClassLoader calling = VMStack.getCallingClassLoader2(); - ClassLoader current = getClassLoader(); - - if (calling != null && !calling.isAncestorOf(current)) { - smgr.checkPackageAccess(this.getPackage().getName()); - } - } - } - - /** - * Performs the security checks regarding the access of a declared - * member of this {@code Class}. - * - * <p><b>Note:</b> Because of the {@code getCallingClassLoader2()} - * check, this method must be called exactly one level deep into a - * public method on this instance.</p> - */ - private void checkDeclaredMemberAccess() { - SecurityManager smgr = System.getSecurityManager(); - if (smgr != null) { - smgr.checkMemberAccess(this, Member.DECLARED); - - ClassLoader calling = VMStack.getCallingClassLoader2(); - ClassLoader current = getClassLoader(); - - if (calling != null && !calling.isAncestorOf(current)) { - smgr.checkPackageAccess(this.getPackage().getName()); - } - } - } - - /** - * Returns an integer that represents the modifiers of the class represented - * by this {@code Class}. The returned value is a combination of bits - * defined by constants in the {@link Modifier} class. - * - * @return the modifiers of the class represented by this {@code Class}. - */ - public int getModifiers() { - return getModifiers(this, false); - } - - /* - * Return the modifiers for the given class. - * - * @param clazz the class of interest - * @ignoreInnerClassesAttrib determines whether we look for and use the - * flags from an "inner class" attribute - */ - private static native int getModifiers(Class<?> clazz, boolean ignoreInnerClassesAttrib); - - /** - * Returns the name of the class represented by this {@code Class}. For a - * description of the format which is used, see the class definition of - * {@link Class}. - * - * @return the name of the class represented by this {@code Class}. - */ - public native String getName(); - - /** - * Returns the simple name of the class represented by this {@code Class} as - * defined in the source code. If there is no name (that is, the class is - * anonymous) then an empty string is returned. If the receiver is an array - * then the name of the underlying type with square braces appended (for - * example {@code "Integer[]"}) is returned. - * - * @return the simple name of the class represented by this {@code Class}. - */ - public String getSimpleName() { - if (isArray()) { - return getComponentType().getSimpleName() + "[]"; - } - - String name = getName(); - - if (isAnonymousClass()) { - return ""; - } - - if (isMemberClass() || isLocalClass()) { - return getInnerClassName(); - } - - int dot = name.lastIndexOf('.'); - if (dot != -1) { - return name.substring(dot + 1); - } - - return name; - } - - /* - * Returns the simple name of a member or local class, or null otherwise. - * - * @return The name. - */ - private native String getInnerClassName(); - - /** - * Returns the {@code ProtectionDomain} of the class represented by this - * class. - * <p> - * Note: In order to conserve space in an embedded target like Android, we - * allow this method to return {@code null} for classes in the system - * protection domain (that is, for system classes). System classes are - * always given full permissions (that is, AllPermission). This can not be - * changed through the {@link java.security.Policy} class. - * </p> - * - * @return the {@code ProtectionDomain} of the class represented by this - * class. - * @throws SecurityException - * if a security manager exists and it does not allow member - * access. - */ - public ProtectionDomain getProtectionDomain() { - SecurityManager smgr = System.getSecurityManager(); - if (smgr != null) { - // Security check is independent of calling class loader. - smgr.checkPermission(new RuntimePermission("getProtectionDomain")); - } - - return pd; - } - - /** - * Returns the URL of the resource specified by {@code resName}. The mapping - * between the resource name and the URL is managed by the class' class - * loader. - * - * @param resName - * the name of the resource. - * @return the requested resource's {@code URL} object or {@code null} if - * the resource can not be found. - * @see ClassLoader - */ - public URL getResource(String resName) { - // Get absolute resource name, but without the leading slash - if (resName.startsWith("/")) { - resName = resName.substring(1); - } else { - String pkg = getName(); - int dot = pkg.lastIndexOf('.'); - if (dot != -1) { - pkg = pkg.substring(0, dot).replace('.', '/'); - } else { - pkg = ""; - } - - resName = pkg + "/" + resName; - } - - // Delegate to proper class loader - ClassLoader loader = getClassLoader(); - if (loader != null) { - return loader.getResource(resName); - } else { - return ClassLoader.getSystemResource(resName); - } - } - - /** - * Returns a read-only stream for the contents of the resource specified by - * {@code resName}. The mapping between the resource name and the stream is - * managed by the class' class loader. - * - * @param resName - * the name of the resource. - * @return a stream for the requested resource or {@code null} if no - * resource with the specified name can be found. - * @see ClassLoader - */ - public InputStream getResourceAsStream(String resName) { - // Get absolute resource name, but without the leading slash - if (resName.startsWith("/")) { - resName = resName.substring(1); - } else { - String pkg = getName(); - int dot = pkg.lastIndexOf('.'); - if (dot != -1) { - pkg = pkg.substring(0, dot).replace('.', '/'); - } else { - pkg = ""; - } - - resName = pkg + "/" + resName; - } - - // Delegate to proper class loader - ClassLoader loader = getClassLoader(); - if (loader != null) { - return loader.getResourceAsStream(resName); - } else { - return ClassLoader.getSystemResourceAsStream(resName); - } - } - - /** - * Returns null. (On Android, a {@code ClassLoader} can load classes from multiple dex files. - * All classes from any given dex file will have the same signers, but different dex - * files may have different signers. This does not fit well with the original - * {@code ClassLoader}-based model of {@code getSigners}.) - * - * @return null. - */ - public Object[] getSigners() { - // See http://code.google.com/p/android/issues/detail?id=1766. - return null; - } - - /** - * Returns the {@code Class} object which represents the superclass of the - * class represented by this {@code Class}. If this {@code Class} represents - * the {@code Object} class, a primitive type, an interface or void then the - * method returns {@code null}. If this {@code Class} represents an array - * class then the {@code Object} class is returned. - * - * @return the superclass of the class represented by this {@code Class}. - */ - public native Class<? super T> getSuperclass(); - - /** - * Returns an array containing {@code TypeVariable} objects for type - * variables declared by the generic class represented by this {@code - * Class}. Returns an empty array if the class is not generic. - * - * @return an array with the type variables of the class represented by this - * class. - */ - @SuppressWarnings("unchecked") - public synchronized TypeVariable<Class<T>>[] getTypeParameters() { - GenericSignatureParser parser = new GenericSignatureParser( - VMStack.getCallingClassLoader2()); - parser.parseForClass(this, getSignatureAttribute()); - return parser.formalTypeParameters.clone(); - } - - /** - * Indicates whether this {@code Class} represents an annotation class. - * - * @return {@code true} if this {@code Class} represents an annotation - * class; {@code false} otherwise. - */ - public boolean isAnnotation() { - final int ACC_ANNOTATION = 0x2000; // not public in reflect.Modifiers - int mod = getModifiers(this, true); - return (mod & ACC_ANNOTATION) != 0; - } - - /** - * Indicates whether the specified annotation is present for the class - * represented by this {@code Class}. - * - * @param annotationClass - * the annotation to look for. - * @return {@code true} if the class represented by this {@code Class} is - * annotated with {@code annotationClass}; {@code false} otherwise. - */ - public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) { - return getAnnotation(annotationClass) != null; - } - - /** - * Indicates whether the class represented by this {@code Class} is - * anonymously declared. - * - * @return {@code true} if the class represented by this {@code Class} is - * anonymous; {@code false} otherwise. - */ - native public boolean isAnonymousClass(); - - /** - * Indicates whether the class represented by this {@code Class} is an array - * class. - * - * @return {@code true} if the class represented by this {@code Class} is an - * array class; {@code false} otherwise. - */ - public boolean isArray() { - return getComponentType() != null; - } - - /** - * Indicates whether the specified class type can be converted to the class - * represented by this {@code Class}. Conversion may be done via an identity - * conversion or a widening reference conversion (if either the receiver or - * the argument represent primitive types, only the identity conversion - * applies). - * - * @param cls - * the class to check. - * @return {@code true} if {@code cls} can be converted to the class - * represented by this {@code Class}; {@code false} otherwise. - * @throws NullPointerException - * if {@code cls} is {@code null}. - */ - public native boolean isAssignableFrom(Class<?> cls); - - /** - * Indicates whether the class represented by this {@code Class} is an - * {@code enum}. - * - * @return {@code true} if the class represented by this {@code Class} is an - * {@code enum}; {@code false} otherwise. - */ - public boolean isEnum() { - return ((getModifiers() & 0x4000) != 0) && (getSuperclass() == Enum.class); - } - - /** - * Indicates whether the specified object can be cast to the class - * represented by this {@code Class}. This is the runtime version of the - * {@code instanceof} operator. - * - * @param object - * the object to check. - * @return {@code true} if {@code object} can be cast to the type - * represented by this {@code Class}; {@code false} if {@code - * object} is {@code null} or cannot be cast. - */ - public native boolean isInstance(Object object); - - /** - * Indicates whether this {@code Class} represents an interface. - * - * @return {@code true} if this {@code Class} represents an interface; - * {@code false} otherwise. - */ - public native boolean isInterface(); - - /** - * Indicates whether the class represented by this {@code Class} is defined - * locally. - * - * @return {@code true} if the class represented by this {@code Class} is - * defined locally; {@code false} otherwise. - */ - public boolean isLocalClass() { - boolean enclosed = (getEnclosingMethod() != null || - getEnclosingConstructor() != null); - return enclosed && !isAnonymousClass(); - } - - /** - * Indicates whether the class represented by this {@code Class} is a member - * class. - * - * @return {@code true} if the class represented by this {@code Class} is a - * member class; {@code false} otherwise. - */ - public boolean isMemberClass() { - return getDeclaringClass() != null; - } - - /** - * Indicates whether this {@code Class} represents a primitive type. - * - * @return {@code true} if this {@code Class} represents a primitive type; - * {@code false} otherwise. - */ - public native boolean isPrimitive(); - - /** - * Indicates whether this {@code Class} represents a synthetic type. - * - * @return {@code true} if this {@code Class} represents a synthetic type; - * {@code false} otherwise. - */ - public boolean isSynthetic() { - final int ACC_SYNTHETIC = 0x1000; // not public in reflect.Modifiers - int mod = getModifiers(this, true); - return (mod & ACC_SYNTHETIC) != 0; - } - - /** - * Returns a new instance of the class represented by this {@code Class}, - * created by invoking the default (that is, zero-argument) constructor. If - * there is no such constructor, or if the creation fails (either because of - * a lack of available memory or because an exception is thrown by the - * constructor), an {@code InstantiationException} is thrown. If the default - * constructor exists but is not accessible from the context where this - * method is invoked, an {@code IllegalAccessException} is thrown. - * - * @return a new instance of the class represented by this {@code Class}. - * @throws IllegalAccessException - * if the default constructor is not visible. - * @throws InstantiationException - * if the instance can not be created. - * @throws SecurityException - * if a security manager exists and it does not allow creating - * new instances. - */ - public T newInstance() throws InstantiationException, IllegalAccessException { - checkPublicMemberAccess(); - return newInstanceImpl(); - } - - private native T newInstanceImpl() throws IllegalAccessException, - InstantiationException; - - @Override - public String toString() { - if (isPrimitive()) { - return getSimpleName().toLowerCase(); - } else { - return (isInterface() ? "interface " : "class ") + getName(); - } - } - - /** - * Returns the {@code Package} of which the class represented by this - * {@code Class} is a member. Returns {@code null} if no {@code Package} - * object was created by the class loader of the class. - * - * @return Package the {@code Package} of which this {@code Class} is a - * member or {@code null}. - */ - public Package getPackage() { - // TODO This might be a hack, but the VM doesn't have the necessary info. - ClassLoader loader = getClassLoader(); - if (loader != null) { - String name = getName(); - int dot = name.lastIndexOf('.'); - return (dot != -1 ? ClassLoader.getPackage(loader, name.substring(0, dot)) : null); - } - - return null; - } - - /** - * Returns the assertion status for the class represented by this {@code - * Class}. Assertion is enabled / disabled based on the class loader, - * package or class default at runtime. - * - * @return the assertion status for the class represented by this {@code - * Class}. - */ - public native boolean desiredAssertionStatus(); - - /** - * Casts this {@code Class} to represent a subclass of the specified class. - * If successful, this {@code Class} is returned; otherwise a {@code - * ClassCastException} is thrown. - * - * @param clazz - * the required type. - * @return this {@code Class} cast as a subclass of the given type. - * @throws ClassCastException - * if this {@code Class} cannot be cast to the specified type. - */ - @SuppressWarnings("unchecked") - public <U> Class<? extends U> asSubclass(Class<U> clazz) { - if (clazz.isAssignableFrom(this)) { - return (Class<? extends U>)this; - } - throw new ClassCastException(); - } - - /** - * Casts the specified object to the type represented by this {@code Class}. - * If the object is {@code null} then the result is also {@code null}. - * - * @param obj - * the object to cast. - * @return the object that has been cast. - * @throws ClassCastException - * if the object cannot be cast to the specified type. - */ - @SuppressWarnings("unchecked") - public T cast(Object obj) { - if (obj == null) { - return null; - } else if (this.isInstance(obj)) { - return (T)obj; - } - throw new ClassCastException(); - } - - /** - * Set the "accessible" flag of the given object, without doing any - * access checks. - * - * <p><b>Note:</b> This method is implemented in native code, and, - * as such, is less efficient than using {@link ClassCache#REFLECT} - * to achieve the same goal. This method exists solely to help - * bootstrap the reflection bridge.</p> - * - * @param ao non-null; the object to modify - * @param flag the new value for the accessible flag - */ - /*package*/ static native void setAccessibleNoCheck(AccessibleObject ao, - boolean flag); - - /** - * Copies two arrays into one. Assumes that the destination array is large - * enough. - * - * @param result the destination array - * @param head the first source array - * @param tail the second source array - * @return the destination array, that is, result - */ - private static <T extends Object> T[] arraycopy(T[] result, T[] head, T[] tail) { - System.arraycopy(head, 0, result, 0, head.length); - System.arraycopy(tail, 0, result, head.length, tail.length); - return result; - } - - /** - * This must be provided by the vm vendor, as it is used by other provided - * class implementations in this package. This method is used by - * SecurityManager.classDepth(), and getClassContext() which use the - * parameters (-1, false) and SecurityManager.classLoaderDepth(), - * currentClassLoader(), and currentLoadedClass() which use the parameters - * (-1, true). Walk the stack and answer an array containing the maxDepth - * most recent classes on the stack of the calling thread. Starting with the - * caller of the caller of getStackClasses(), return an array of not more - * than maxDepth Classes representing the classes of running methods on the - * stack (including native methods). Frames representing the VM - * implementation of java.lang.reflect are not included in the list. If - * stopAtPrivileged is true, the walk will terminate at any frame running - * one of the following methods: <code><ul> - * <li>java/security/AccessController.doPrivileged(Ljava/security/PrivilegedAction;)Ljava/lang/Object;</li> - * <li>java/security/AccessController.doPrivileged(Ljava/security/PrivilegedExceptionAction;)Ljava/lang/Object;</li> - * <li>java/security/AccessController.doPrivileged(Ljava/security/PrivilegedAction;Ljava/security/AccessControlContext;)Ljava/lang/Object;</li> - * <li>java/security/AccessController.doPrivileged(Ljava/security/PrivilegedExceptionAction;Ljava/security/AccessControlContext;)Ljava/lang/Object;</li> - * </ul></code> If one of the doPrivileged methods is found, the walk terminate - * and that frame is NOT included in the returned array. Notes: - * <ul> - * <li>This method operates on the defining classes of methods on stack. - * NOT the classes of receivers.</li> - * <li>The item at index zero in the result array describes the caller of - * the caller of this method.</li> - * </ul> - * - * @param maxDepth - * maximum depth to walk the stack, -1 for the entire stack - * @param stopAtPrivileged - * stop at privileged classes - * @return the array of the most recent classes on the stack - */ - static final Class<?>[] getStackClasses(int maxDepth, boolean stopAtPrivileged) { - return VMStack.getClasses(maxDepth, stopAtPrivileged); - } - -} diff --git a/luni-kernel/src/main/java/java/lang/ClassCache.java b/luni-kernel/src/main/java/java/lang/ClassCache.java deleted file mode 100644 index 5ea6992..0000000 --- a/luni-kernel/src/main/java/java/lang/ClassCache.java +++ /dev/null @@ -1,702 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang; - -import org.apache.harmony.kernel.vm.LangAccess; -import org.apache.harmony.kernel.vm.ReflectionAccess; - -import java.lang.reflect.AccessibleObject; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.EnumSet; -import java.util.HashSet; - -/** - * Cache of per-class data, meant to help the performance of reflection - * methods. - * - * <p><b>Note:</b> None of the methods perform access checks. It is up - * to the (package internal) clients of this code to perform such - * checks as necessary.</p> - * - * <p><b>Also Note:</b> None of the returned array values are - * protected in any way. It is up to the (again, package internal) - * clients of this code to protect the arrays if they should ever - * escape the package.</p> - */ -/*package*/ class ClassCache<T> { - // TODO: Add caching for constructors and fields. - - /** non-null; comparator used for enumerated values */ - private static final EnumComparator ENUM_COMPARATOR = - new EnumComparator(); - - /** non-null; reflection access bridge */ - /*package*/ static final ReflectionAccess REFLECT = getReflectionAccess(); - - /** non-null; class that this instance represents */ - private final Class<T> clazz; - - /** null-ok; list of all declared methods */ - private volatile Method[] declaredMethods; - - /** null-ok; list of all public declared methods */ - private volatile Method[] declaredPublicMethods; - - /** null-ok; list of all methods, both direct and inherited */ - private volatile Method[] allMethods; - - /** null-ok; list of all public methods, both direct and inherited */ - private volatile Method[] allPublicMethods; - - /** null-ok; list of all declared fields */ - private volatile Field[] declaredFields; - - /** null-ok; list of all public declared fields */ - private volatile Field[] declaredPublicFields; - - /** null-ok; list of all fields, both direct and inherited */ - private volatile Field[] allFields; - - /** null-ok; list of all public fields, both direct and inherited */ - private volatile Field[] allPublicFields; - - /** - * null-ok; array of enumerated values in their original order, if this - * instance's class is an enumeration - */ - private volatile T[] enumValuesInOrder; - - /** - * null-ok; array of enumerated values sorted by name, if this - * instance's class is an enumeration - */ - private volatile T[] enumValuesByName; - - static { - /* - * Provide access to this package from java.util as part of - * bootstrap. TODO: See if this can be removed in favor of the - * simpler mechanism below. (That is, see if EnumSet will be - * happy calling LangAccess.getInstance().) - */ - Field field; - - try { - field = EnumSet.class.getDeclaredField("LANG_BOOTSTRAP"); - REFLECT.setAccessibleNoCheck(field, true); - } catch (NoSuchFieldException ex) { - // This shouldn't happen because the field is in fact defined. - throw new AssertionError(ex); - } - - try { - field.set(null, LangAccessImpl.THE_ONE); - } catch (IllegalAccessException ex) { - // This shouldn't happen because we made the field accessible. - throw new AssertionError(ex); - } - - // Also set up the bootstrap-classpath-wide access mechanism. - LangAccess.setInstance(LangAccessImpl.THE_ONE); - } - - /** - * Constructs an instance. - * - * @param clazz non-null; class that this instance represents - */ - /*package*/ ClassCache(Class<T> clazz) { - if (clazz == null) { - throw new NullPointerException("clazz == null"); - } - - this.clazz = clazz; - this.declaredMethods = null; - this.declaredPublicMethods = null; - this.allMethods = null; - this.allPublicMethods = null; - this.enumValuesInOrder = null; - this.enumValuesByName = null; - this.declaredFields = null; - this.declaredPublicFields = null; - this.allFields = null; - this.allPublicFields = null; - } - - /** - * Gets the list of all declared methods. - * - * @return non-null; the list of all declared methods - */ - public Method[] getDeclaredMethods() { - if (declaredMethods == null) { - declaredMethods = Class.getDeclaredMethods(clazz, false); - } - - return declaredMethods; - } - - /** - * Gets the list of all declared public methods. - * - * @return non-null; the list of all declared public methods - */ - public Method[] getDeclaredPublicMethods() { - if (declaredPublicMethods == null) { - declaredPublicMethods = Class.getDeclaredMethods(clazz, true); - } - - return declaredPublicMethods; - } - - /** - * Gets either the list of declared methods or the list of declared - * public methods. - * - * @param publicOnly whether to only return public methods - */ - public Method[] getDeclaredMethods(boolean publicOnly) { - return publicOnly ? getDeclaredPublicMethods() : getDeclaredMethods(); - } - - /** - * Gets the list of all methods, both directly - * declared and inherited. - * - * @return non-null; the list of all methods - */ - public Method[] getAllMethods() { - if (allMethods == null) { - allMethods = getFullListOfMethods(false); - } - - return allMethods; - } - - /** - * Gets the list of all public methods, both directly - * declared and inherited. - * - * @return non-null; the list of all public methods - */ - public Method[] getAllPublicMethods() { - if (allPublicMethods == null) { - allPublicMethods = getFullListOfMethods(true); - } - - return allPublicMethods; - } - - /* - * Returns the list of methods without performing any security checks - * first. This includes the methods inherited from superclasses. If no - * methods exist at all, an empty array is returned. - * - * @param publicOnly reflects whether we want only public methods - * or all of them - * @return the list of methods - */ - private Method[] getFullListOfMethods(boolean publicOnly) { - ArrayList<Method> methods = new ArrayList<Method>(); - HashSet<String> seen = new HashSet<String>(); - - findAllMethods(clazz, methods, seen, publicOnly); - - return methods.toArray(new Method[methods.size()]); - } - - /** - * Collects the list of methods without performing any security checks - * first. This includes the methods inherited from superclasses and from - * all implemented interfaces. The latter may also implement multiple - * interfaces, so we (potentially) recursively walk through a whole tree of - * classes. If no methods exist at all, an empty array is returned. - * - * @param clazz non-null; class to inspect - * @param methods non-null; the target list to add the results to - * @param seen non-null; a set of signatures we've already seen - * @param publicOnly reflects whether we want only public methods - * or all of them - */ - private static void findAllMethods(Class<?> clazz, - ArrayList<Method> methods, HashSet<String> seen, - boolean publicOnly) { - StringBuilder builder = new StringBuilder(); - Class<?> origClass = clazz; - - // Traverse class and superclasses, get rid of dupes by signature - while (clazz != null) { - Method[] declaredMethods = - clazz.getClassCache().getDeclaredMethods(publicOnly); - int length = declaredMethods.length; - if (length != 0) { - for (Method method : declaredMethods) { - builder.setLength(0); - builder.append(method.getName()); - builder.append('('); - Class<?>[] types = method.getParameterTypes(); - if (types.length != 0) { - builder.append(types[0].getName()); - for (int j = 1; j < types.length; j++) { - builder.append(','); - builder.append(types[j].getName()); - } - } - builder.append(')'); - - String signature = builder.toString(); - if (!seen.contains(signature)) { - methods.add(method); - seen.add(signature); - } - } - } - - clazz = clazz.getSuperclass(); - } - - // Traverse all interfaces, and do the same recursively. - Class<?>[] interfaces = origClass.getInterfaces(); - for (Class<?> intf : interfaces) { - findAllMethods(intf, methods, seen, publicOnly); - } - } - - /** - * Finds and returns a method with a given name and signature. Use - * this with one of the method lists returned by instances of this class. - * - * @param list non-null; the list of methods to search through - * @param parameterTypes non-null; the formal parameter list - * @return non-null; the matching method - * @throws NoSuchMethodException thrown if the method does not exist - */ - public static Method findMethodByName(Method[] list, String name, - Class<?>[] parameterTypes) throws NoSuchMethodException { - if (name == null) { - throw new NullPointerException("Method name must not be null."); - } - for (int i = list.length - 1; i >= 0; i--) { - Method method = list[i]; - if (method.getName().equals(name) - && compareClassLists( - method.getParameterTypes(), parameterTypes)) { - return method; - } - } - - throw new NoSuchMethodException(name); - } - - /** - * Compares two class lists for equality. Empty and - * <code>null</code> lists are considered equal. This is useful - * for matching methods and constructors. - * - * <p>TODO: Take into account assignment compatibility?</p> - * - * @param a null-ok; the first list of types - * @param b null-ok; the second list of types - * @return true if and only if the lists are equal - */ - public static boolean compareClassLists(Class<?>[] a, Class<?>[] b) { - if (a == null) { - return (b == null) || (b.length == 0); - } - - int length = a.length; - - if (b == null) { - return (length == 0); - } - - if (length != b.length) { - return false; - } - - for (int i = length - 1; i >= 0; i--) { - if (a[i] != b[i]) { - return false; - } - } - - return true; - } - - /** - * Makes a deep copy of the given array of methods. This is useful - * when handing out arrays from the public API. - * - * <p><b>Note:</b> In such cases, it is insufficient to just make - * a shallow copy of the array, since method objects aren't - * immutable due to the existence of {@link - * AccessibleObject#setAccessible}.</p> - * - * @param orig non-null; array to copy - * @return non-null; a deep copy of the given array - */ - public static Method[] deepCopy(Method[] orig) { - int length = orig.length; - Method[] result = new Method[length]; - - for (int i = length - 1; i >= 0; i--) { - result[i] = REFLECT.clone(orig[i]); - } - - return result; - } - - /** - * Gets the list of all declared fields. - * - * @return non-null; the list of all declared fields - */ - public Field[] getDeclaredFields() { - if (declaredFields == null) { - declaredFields = Class.getDeclaredFields(clazz, false); - } - - return declaredFields; - } - - /** - * Gets the list of all declared public fields. - * - * @return non-null; the list of all declared public fields - */ - public Field[] getDeclaredPublicFields() { - if (declaredPublicFields == null) { - declaredPublicFields = Class.getDeclaredFields(clazz, true); - } - - return declaredPublicFields; - } - - /** - * Gets either the list of declared fields or the list of declared - * public fields. - * - * @param publicOnly whether to only return public fields - */ - public Field[] getDeclaredFields(boolean publicOnly) { - return publicOnly ? getDeclaredPublicFields() : getDeclaredFields(); - } - - /** - * Gets the list of all fields, both directly - * declared and inherited. - * - * @return non-null; the list of all fields - */ - public Field[] getAllFields() { - if (allFields == null) { - allFields = getFullListOfFields(false); - } - - return allFields; - } - - /** - * Gets the list of all public fields, both directly - * declared and inherited. - * - * @return non-null; the list of all public fields - */ - public Field[] getAllPublicFields() { - if (allPublicFields == null) { - allPublicFields = getFullListOfFields(true); - } - - return allPublicFields; - } - - /* - * Returns the list of fields without performing any security checks - * first. This includes the fields inherited from superclasses. If no - * fields exist at all, an empty array is returned. - * - * @param publicOnly reflects whether we want only public fields - * or all of them - * @return the list of fields - */ - private Field[] getFullListOfFields(boolean publicOnly) { - ArrayList<Field> fields = new ArrayList<Field>(); - HashSet<String> seen = new HashSet<String>(); - - findAllfields(clazz, fields, seen, publicOnly); - - return fields.toArray(new Field[fields.size()]); - } - - /** - * Collects the list of fields without performing any security checks - * first. This includes the fields inherited from superclasses and from - * all implemented interfaces. The latter may also implement multiple - * interfaces, so we (potentially) recursively walk through a whole tree of - * classes. If no fields exist at all, an empty array is returned. - * - * @param clazz non-null; class to inspect - * @param fields non-null; the target list to add the results to - * @param seen non-null; a set of signatures we've already seen - * @param publicOnly reflects whether we want only public fields - * or all of them - */ - private static void findAllfields(Class<?> clazz, - ArrayList<Field> fields, HashSet<String> seen, - boolean publicOnly) { - - // Traverse class and superclasses, get rid of dupes by signature - while (clazz != null) { - Field[] declaredFields = - clazz.getClassCache().getDeclaredFields(publicOnly); - for (Field field : declaredFields) { - String signature = field.toString(); - if (!seen.contains(signature)) { - fields.add(field); - seen.add(signature); - } - } - - // Traverse all interfaces, and do the same recursively. - Class<?>[] interfaces = clazz.getInterfaces(); - for (Class<?> intf : interfaces) { - findAllfields(intf, fields, seen, publicOnly); - } - - clazz = clazz.getSuperclass(); - } - } - - /** - * Finds and returns a field with a given name and signature. Use - * this with one of the field lists returned by instances of this class. - * - * @param list non-null; the list of fields to search through - * @return non-null; the matching field - * @throws NoSuchFieldException thrown if the field does not exist - */ - public static Field findFieldByName(Field[] list, String name) - throws NoSuchFieldException { - if (name == null) { - throw new NullPointerException("Field name must not be null."); - } - for (int i = 0; i < list.length; i++) { - Field field = list[i]; - if (field.getName().equals(name)) { - return field; - } - } - - throw new NoSuchFieldException(name); - } - - /** - * Makes a deep copy of the given array of fields. This is useful - * when handing out arrays from the public API. - * - * <p><b>Note:</b> In such cases, it is insufficient to just make - * a shallow copy of the array, since field objects aren't - * immutable due to the existence of {@link - * AccessibleObject#setAccessible}.</p> - * - * @param orig non-null; array to copy - * @return non-null; a deep copy of the given array - */ - public static Field[] deepCopy(Field[] orig) { - int length = orig.length; - Field[] result = new Field[length]; - - for (int i = length - 1; i >= 0; i--) { - result[i] = REFLECT.clone(orig[i]); - } - - return result; - } - - /** - * Gets the enumerated value with a given name. - * - * @param name non-null; name of the value - * @return null-ok; the named enumerated value or <code>null</code> - * if this instance's class doesn't have such a value (including - * if this instance isn't in fact an enumeration) - */ - @SuppressWarnings("unchecked") - public T getEnumValue(String name) { - Enum[] values = (Enum[]) getEnumValuesByName(); - - if (values == null) { - return null; - } - - // Binary search. - - int min = 0; - int max = values.length - 1; - - while (min <= max) { - /* - * The guessIdx calculation is equivalent to ((min + max) - * / 2) but won't go wonky when min and max are close to - * Integer.MAX_VALUE. - */ - int guessIdx = min + ((max - min) >> 1); - Enum guess = values[guessIdx]; - int cmp = name.compareTo(guess.name()); - - if (cmp < 0) { - max = guessIdx - 1; - } else if (cmp > 0) { - min = guessIdx + 1; - } else { - return (T) guess; - } - } - - return null; - } - - /** - * Gets the array of enumerated values, sorted by name. - * - * @return null-ok; the value array, or <code>null</code> if this - * instance's class isn't in fact an enumeration - */ - public T[] getEnumValuesByName() { - if (enumValuesByName == null) { - T[] values = getEnumValuesInOrder(); - - if (values != null) { - values = (T[]) values.clone(); - Arrays.sort((Enum<?>[]) values, ENUM_COMPARATOR); - - /* - * Note: It's only safe (concurrency-wise) to set the - * instance variable after the array is properly sorted. - */ - enumValuesByName = values; - } - } - - return enumValuesByName; - } - - /** - * Gets the array of enumerated values, in their original declared - * order. - * - * @return null-ok; the value array, or <code>null</code> if this - * instance's class isn't in fact an enumeration - */ - public T[] getEnumValuesInOrder() { - if ((enumValuesInOrder == null) && clazz.isEnum()) { - enumValuesInOrder = callEnumValues(); - } - - return enumValuesInOrder; - } - - /** - * Calls the static method <code>values()</code> on this - * instance's class, which is presumed to be a properly-formed - * enumeration class, using proper privilege hygiene. - * - * @return non-null; the array of values as reported by - * <code>value()</code> - */ - @SuppressWarnings("unchecked") - private T[] callEnumValues() { - Method method; - - try { - Method[] methods = getDeclaredPublicMethods(); - method = findMethodByName(methods, "values", (Class[]) null); - method = REFLECT.accessibleClone(method); - } catch (NoSuchMethodException ex) { - // This shouldn't happen if the class is a well-formed enum. - throw new UnsupportedOperationException(ex); - } - - try { - return (T[]) method.invoke((Object[]) null); - } catch (IllegalAccessException ex) { - // This shouldn't happen because the method is "accessible." - throw new Error(ex); - } catch (InvocationTargetException ex) { - Throwable te = ex.getTargetException(); - if (te instanceof RuntimeException) { - throw (RuntimeException) te; - } else if (te instanceof Error) { - throw (Error) te; - } else { - throw new Error(te); - } - } - } - - /** - * Gets the reflection access object. This uses reflection to do - * so. My head is spinning. - * - * @return non-null; the reflection access object - */ - private static ReflectionAccess getReflectionAccess() { - /* - * Note: We can't do AccessibleObject.class.getCache() to - * get the cache, since that would cause a circularity in - * initialization. So instead, we do a direct call into the - * native side. - */ - Method[] methods = - Class.getDeclaredMethods(AccessibleObject.class, false); - - try { - Method method = findMethodByName(methods, "getReflectionAccess", - (Class[]) null); - Class.setAccessibleNoCheck(method, true); - return (ReflectionAccess) method.invoke((Object[]) null); - } catch (NoSuchMethodException ex) { - /* - * This shouldn't happen because the method - * AccessibleObject.getReflectionAccess() really is defined - * in this module. - */ - throw new Error(ex); - } catch (IllegalAccessException ex) { - // This shouldn't happen because the method is "accessible." - throw new Error(ex); - } catch (InvocationTargetException ex) { - throw new Error(ex); - } - } - - /** - * Comparator class for enumerated values. It compares strictly - * by name. - */ - private static class EnumComparator implements Comparator<Enum<?>> { - public int compare(Enum<?> e1, Enum<?> e2) { - return e1.name().compareTo(e2.name()); - } - } -} diff --git a/luni-kernel/src/main/java/java/lang/ClassLoader.java b/luni-kernel/src/main/java/java/lang/ClassLoader.java deleted file mode 100644 index aae807e..0000000 --- a/luni-kernel/src/main/java/java/lang/ClassLoader.java +++ /dev/null @@ -1,1103 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.nio.ByteBuffer; -import java.security.ProtectionDomain; -import java.util.Collection; -import java.util.Enumeration; -import java.util.Map; -import java.util.HashMap; - -import dalvik.system.PathClassLoader; -import dalvik.system.VMStack; - -/** - * Loads classes and resources from a repository. One or more class loaders are - * installed at runtime. These are consulted whenever the runtime system needs a - * specific class that is not yet available in-memory. Typically, class loaders - * are grouped into a tree where child class loaders delegate all requests to - * parent class loaders. Only if the parent class loader cannot satisfy the - * request, the child class loader itself tries to handle it. - * <p> - * {@code ClassLoader} is an abstract class that implements the common - * infrastructure required by all class loaders. Android provides several - * concrete implementations of the class, with - * {@link dalvik.system.PathClassLoader} being the one typically used. Other - * applications may implement subclasses of {@code ClassLoader} to provide - * special ways for loading classes. - * </p> - * @see Class - */ -public abstract class ClassLoader { - - // BEGIN android-note - /* - * Because of a potential class initialization race between ClassLoader and - * java.lang.System, reproducible when using JDWP with "suspend=y", we defer - * creation of the system class loader until first use. We use a static - * inner class to get synchronization at init time without having to sync on - * every access. - */ - // END android-note - /** - * The 'System' ClassLoader - the one that is responsible for loading - * classes from the classpath. It is not equal to the bootstrap class loader - - * that one handles the built-in classes. - * - * @see #getSystemClassLoader() - */ - static private class SystemClassLoader { - public static ClassLoader loader = ClassLoader.createSystemClassLoader(); - } - - /** - * The parent ClassLoader. - */ - private ClassLoader parent; - - /** - * The packages known to the class loader. - */ - private Map<String, Package> packages = new HashMap<String, Package>(); - - /** - * Create the system class loader. Note this is NOT the bootstrap class - * loader (which is managed by the VM). We use a null value for the parent - * to indicate that the bootstrap loader is our parent. - */ - private static ClassLoader createSystemClassLoader() { - String classPath = System.getProperty("java.class.path", "."); - - // String[] paths = classPath.split(":"); - // URL[] urls = new URL[paths.length]; - // for (int i = 0; i < paths.length; i++) { - // try { - // urls[i] = new URL("file://" + paths[i]); - // } - // catch (Exception ex) { - // ex.printStackTrace(); - // } - // } - // - // return new java.net.URLClassLoader(urls, null); - - // TODO Make this a java.net.URLClassLoader once we have those? - return new PathClassLoader(classPath, BootClassLoader.getInstance()); - } - - /** - * Returns the system class loader. This is the parent for new - * {@code ClassLoader} instances and is typically the class loader used to - * start the application. If a security manager is present and the caller's - * class loader is neither {@code null} nor the same as or an ancestor of - * the system class loader, then this method calls the security manager's - * checkPermission method with a RuntimePermission("getClassLoader") - * permission to ensure that it is ok to access the system class loader. If - * not, a {@code SecurityException} is thrown. - * - * @return the system class loader. - * @throws SecurityException - * if a security manager exists and it does not allow access to - * the system class loader. - */ - public static ClassLoader getSystemClassLoader() { - SecurityManager smgr = System.getSecurityManager(); - if (smgr != null) { - ClassLoader caller = VMStack.getCallingClassLoader(); - if (caller != null && !caller.isAncestorOf(SystemClassLoader.loader)) { - smgr.checkPermission(new RuntimePermission("getClassLoader")); - } - } - - return SystemClassLoader.loader; - } - - /** - * Finds the URL of the resource with the specified name. The system class - * loader's resource lookup algorithm is used to find the resource. - * - * @return the {@code URL} object for the requested resource or {@code null} - * if the resource can not be found. - * @param resName - * the name of the resource to find. - * @see Class#getResource - */ - public static URL getSystemResource(String resName) { - return SystemClassLoader.loader.getResource(resName); - } - - /** - * Returns an enumeration of URLs for the resource with the specified name. - * The system class loader's resource lookup algorithm is used to find the - * resource. - * - * @return an enumeration of {@code URL} objects containing the requested - * resources. - * @param resName - * the name of the resource to find. - * @throws IOException - * if an I/O error occurs. - */ - public static Enumeration<URL> getSystemResources(String resName) throws IOException { - return SystemClassLoader.loader.getResources(resName); - } - - /** - * Returns a stream for the resource with the specified name. The system - * class loader's resource lookup algorithm is used to find the resource. - * Basically, the contents of the java.class.path are searched in order, - * looking for a path which matches the specified resource. - * - * @return a stream for the resource or {@code null}. - * @param resName - * the name of the resource to find. - * @see Class#getResourceAsStream - */ - public static InputStream getSystemResourceAsStream(String resName) { - return SystemClassLoader.loader.getResourceAsStream(resName); - } - - /** - * Constructs a new instance of this class with the system class loader as - * its parent. - * - * @throws SecurityException - * if a security manager exists and it does not allow the - * creation of a new {@code ClassLoader}. - */ - protected ClassLoader() { - this(getSystemClassLoader(), false); - } - - /** - * Constructs a new instance of this class with the specified class loader - * as its parent. - * - * @param parentLoader - * The {@code ClassLoader} to use as the new class loader's - * parent. - * @throws SecurityException - * if a security manager exists and it does not allow the - * creation of new a new {@code ClassLoader}. - */ - protected ClassLoader(ClassLoader parentLoader) { - this(parentLoader, false); - } - - /* - * constructor for the BootClassLoader which needs parent to be null. - */ - ClassLoader(ClassLoader parentLoader, boolean nullAllowed) { - SecurityManager smgr = System.getSecurityManager(); - if (smgr != null) { - smgr.checkCreateClassLoader(); - } - - if (parentLoader == null && !nullAllowed) { - throw new NullPointerException( - "Parent ClassLoader may not be null"); - } - - parent = parentLoader; - } - - /** - * Constructs a new class from an array of bytes containing a class - * definition in class file format. - * - * @param classRep - * the memory image of a class file. - * @param offset - * the offset into {@code classRep}. - * @param length - * the length of the class file. - * @return the {@code Class} object created from the specified subset of - * data in {@code classRep}. - * @throws ClassFormatError - * if {@code classRep} does not contain a valid class. - * @throws IndexOutOfBoundsException - * if {@code offset < 0}, {@code length < 0} or if - * {@code offset + length} is greater than the length of - * {@code classRep}. - * @deprecated Use {@link #defineClass(String, byte[], int, int)} - */ - @Deprecated - protected final Class<?> defineClass(byte[] classRep, int offset, int length) - throws ClassFormatError { - - return VMClassLoader.defineClass(this, classRep, offset, length, null); - } - - /** - * Constructs a new class from an array of bytes containing a class - * definition in class file format. - * - * @param className - * the expected name of the new class, may be {@code null} if not - * known. - * @param classRep - * the memory image of a class file. - * @param offset - * the offset into {@code classRep}. - * @param length - * the length of the class file. - * @return the {@code Class} object created from the specified subset of - * data in {@code classRep}. - * @throws ClassFormatError - * if {@code classRep} does not contain a valid class. - * @throws IndexOutOfBoundsException - * if {@code offset < 0}, {@code length < 0} or if - * {@code offset + length} is greater than the length of - * {@code classRep}. - */ - protected final Class<?> defineClass(String className, byte[] classRep, int offset, int length) - throws ClassFormatError { - - // TODO Define a default ProtectionDomain on first use - return defineClass(className, classRep, offset, length, null); - } - - /** - * Constructs a new class from an array of bytes containing a class - * definition in class file format and assigns the specified protection - * domain to the new class. If the provided protection domain is - * {@code null} then a default protection domain is assigned to the class. - * - * @param className - * the expected name of the new class, may be {@code null} if not - * known. - * @param classRep - * the memory image of a class file. - * @param offset - * the offset into {@code classRep}. - * @param length - * the length of the class file. - * @param protectionDomain - * the protection domain to assign to the loaded class, may be - * {@code null}. - * @return the {@code Class} object created from the specified subset of - * data in {@code classRep}. - * @throws ClassFormatError - * if {@code classRep} does not contain a valid class. - * @throws IndexOutOfBoundsException - * if {@code offset < 0}, {@code length < 0} or if - * {@code offset + length} is greater than the length of - * {@code classRep}. - * @throws NoClassDefFoundError - * if {@code className} is not equal to the name of the class - * contained in {@code classRep}. - */ - protected final Class<?> defineClass(String className, byte[] classRep, int offset, int length, - ProtectionDomain protectionDomain) throws java.lang.ClassFormatError { - - return VMClassLoader.defineClass(this, className, classRep, offset, length, - protectionDomain); - } - - /** - * Defines a new class with the specified name, byte code from the byte - * buffer and the optional protection domain. If the provided protection - * domain is {@code null} then a default protection domain is assigned to - * the class. - * - * @param name - * the expected name of the new class, may be {@code null} if not - * known. - * @param b - * the byte buffer containing the byte code of the new class. - * @param protectionDomain - * the protection domain to assign to the loaded class, may be - * {@code null}. - * @return the {@code Class} object created from the data in {@code b}. - * @throws ClassFormatError - * if {@code b} does not contain a valid class. - * @throws NoClassDefFoundError - * if {@code className} is not equal to the name of the class - * contained in {@code b}. - */ - protected final Class<?> defineClass(String name, ByteBuffer b, - ProtectionDomain protectionDomain) throws ClassFormatError { - - byte[] temp = new byte[b.remaining()]; - b.get(temp); - return defineClass(name, temp, 0, temp.length, protectionDomain); - } - - /** - * Overridden by subclasses, throws a {@code ClassNotFoundException} by - * default. This method is called by {@code loadClass} after the parent - * {@code ClassLoader} has failed to find a loaded class of the same name. - * - * @param className - * the name of the class to look for. - * @return the {@code Class} object that is found. - * @throws ClassNotFoundException - * if the class cannot be found. - */ - protected Class<?> findClass(String className) throws ClassNotFoundException { - throw new ClassNotFoundException(className); - } - - /** - * Returns the class with the specified name if it has already been loaded - * by the virtual machine or {@code null} if it has not yet been loaded. - * - * @param className - * the name of the class to look for. - * @return the {@code Class} object or {@code null} if the requested class - * has not been loaded. - */ - protected final Class<?> findLoadedClass(String className) { - ClassLoader loader; - if (this == BootClassLoader.getInstance()) - loader = null; - else - loader = this; - return VMClassLoader.findLoadedClass(loader, className); - } - - /** - * Finds the class with the specified name, loading it using the system - * class loader if necessary. - * - * @param className - * the name of the class to look for. - * @return the {@code Class} object with the requested {@code className}. - * @throws ClassNotFoundException - * if the class can not be found. - */ - protected final Class<?> findSystemClass(String className) throws ClassNotFoundException { - return Class.forName(className, false, getSystemClassLoader()); - } - - /** - * Returns this class loader's parent. - * - * @return this class loader's parent or {@code null}. - * @throws SecurityException - * if a security manager exists and it does not allow to - * retrieve the parent class loader. - */ - public final ClassLoader getParent() { - SecurityManager smgr = System.getSecurityManager(); - if (smgr != null) { - smgr.checkPermission(new RuntimePermission("getClassLoader")); - } - - return parent; - } - - /** - * Returns the URL of the resource with the specified name. This - * implementation first tries to use the parent class loader to find the - * resource; if this fails then {@link #findResource(String)} is called to - * find the requested resource. - * - * @param resName - * the name of the resource to find. - * @return the {@code URL} object for the requested resource or {@code null} - * if either the resource can not be found or a security manager - * does not allow to access the resource. - * @see Class#getResource - */ - public URL getResource(String resName) { - URL resource = null; - - resource = parent.getResource(resName); - - if (resource == null) { - resource = findResource(resName); - } - - return resource; - } - - /** - * Returns an enumeration of URLs for the resource with the specified name. - * This implementation first uses this class loader's parent to find the - * resource, then it calls {@link #findResources(String)} to get additional - * URLs. The returned enumeration contains the {@code URL} objects of both - * find operations. - * - * @return an enumeration of {@code URL} objects for the requested resource. - * @param resName - * the name of the resource to find. - * @throws IOException - * if an I/O error occurs. - */ - @SuppressWarnings("unchecked") - public Enumeration<URL> getResources(String resName) throws IOException { - - Enumeration first = parent.getResources(resName); - Enumeration second = findResources(resName); - - return new TwoEnumerationsInOne(first, second); - } - - /** - * Returns a stream for the resource with the specified name. See - * {@link #getResource(String)} for a description of the lookup algorithm - * used to find the resource. - * - * @return a stream for the resource or {@code null} if either the resource - * can not be found or a security manager does not allow to access - * the resource. - * @param resName - * the name of the resource to find. - * @see Class#getResourceAsStream - */ - public InputStream getResourceAsStream(String resName) { - try { - URL url = getResource(resName); - if (url != null) { - return url.openStream(); - } - } catch (IOException ex) { - // Don't want to see the exception. - } - - return null; - } - - /** - * Loads the class with the specified name. Invoking this method is - * equivalent to calling {@code loadClass(className, false)}. - * <p> - * <strong>Note:</strong> In the Android reference implementation, the - * second parameter of {@link #loadClass(String, boolean)} is ignored - * anyway. - * </p> - * - * @return the {@code Class} object. - * @param className - * the name of the class to look for. - * @throws ClassNotFoundException - * if the class can not be found. - */ - public Class<?> loadClass(String className) throws ClassNotFoundException { - return loadClass(className, false); - } - - /** - * Loads the class with the specified name, optionally linking it after - * loading. The following steps are performed: - * <ol> - * <li> Call {@link #findLoadedClass(String)} to determine if the requested - * class has already been loaded.</li> - * <li>If the class has not yet been loaded: Invoke this method on the - * parent class loader.</li> - * <li>If the class has still not been loaded: Call - * {@link #findClass(String)} to find the class.</li> - * </ol> - * <p> - * <strong>Note:</strong> In the Android reference implementation, the - * {@code resolve} parameter is ignored; classes are never linked. - * </p> - * - * @return the {@code Class} object. - * @param className - * the name of the class to look for. - * @param resolve - * Indicates if the class should be resolved after loading. This - * parameter is ignored on the Android reference implementation; - * classes are not resolved. - * @throws ClassNotFoundException - * if the class can not be found. - */ - protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException { - Class<?> clazz = findLoadedClass(className); - - if (clazz == null) { - try { - clazz = parent.loadClass(className, false); - } catch (ClassNotFoundException e) { - // Don't want to see this. - } - - if (clazz == null) { - clazz = findClass(className); - } - } - - return clazz; - } - - /** - * Forces a class to be linked (initialized). If the class has already been - * linked this operation has no effect. - * <p> - * <strong>Note:</strong> In the Android reference implementation, this - * method has no effect. - * </p> - * - * @param clazz - * the class to link. - */ - protected final void resolveClass(Class<?> clazz) { - // no-op, doesn't make sense on android. - } - - /** - * Indicates whether this class loader is the system class loader. This - * method must be provided by the virtual machine vendor, as it is used by - * other provided class implementations in this package. A sample - * implementation of this method is provided by the reference - * implementation. This method is used by - * SecurityManager.classLoaderDepth(), currentClassLoader() and - * currentLoadedClass(). Returns true if the receiver is a system class - * loader. - * <p> - * Note that this method has package visibility only. It is defined here to - * avoid the security manager check in getSystemClassLoader, which would be - * required to implement this method anywhere else. - * </p> - * - * @return {@code true} if the receiver is a system class loader - * @see Class#getClassLoaderImpl() - */ - final boolean isSystemClassLoader() { - return false; - } - - /** - * <p> - * Returns true if the receiver is ancestor of another class loader. It also - * returns true if the two class loader are equal. - * </p> - * <p> - * Note that this method has package visibility only. It is defined here to - * avoid the security manager check in getParent, which would be required to - * implement this method anywhere else. The method is also required in other - * places where class loaders are accesses. - * </p> - * - * @param child - * A child candidate - * @return {@code true} if the receiver is ancestor of, or equal to, - * the parameter - */ - final boolean isAncestorOf(ClassLoader child) { - for (ClassLoader current = child; current != null; - current = current.parent) { - if (current == this) { - return true; - } - } - return false; - } - - /** - * Finds the URL of the resource with the specified name. This - * implementation just returns {@code null}; it should be overridden in - * subclasses. - * - * @param resName - * the name of the resource to find. - * @return the {@code URL} object for the requested resource. - */ - protected URL findResource(String resName) { - return null; - } - - /** - * Finds an enumeration of URLs for the resource with the specified name. - * This implementation just returns an empty {@code Enumeration}; it should - * be overridden in subclasses. - * - * @param resName - * the name of the resource to find. - * @return an enumeration of {@code URL} objects for the requested resource. - * @throws IOException - * if an I/O error occurs. - */ - @SuppressWarnings( { - "unchecked", "unused" - }) - protected Enumeration<URL> findResources(String resName) throws IOException { - return EmptyEnumeration.getInstance(); - } - - /** - * Returns the absolute path of the native library with the specified name, - * or {@code null}. If this method returns {@code null} then the virtual - * machine searches the directories specified by the system property - * "java.library.path". - * <p> - * This implementation always returns {@code null}. - * </p> - * - * @param libName - * the name of the library to find. - * @return the absolute path of the library. - */ - protected String findLibrary(String libName) { - return null; - } - - /** - * Returns the package with the specified name. Package information is - * searched in this class loader. - * - * @param name - * the name of the package to find. - * @return the package with the requested name; {@code null} if the package - * can not be found. - */ - protected Package getPackage(String name) { - synchronized (packages) { - Package p = packages.get(name); - return p; - } - } - - /** - * Gets the package with the specified name, searching it in the specified - * class loader. - * - * @param loader - * the class loader to search the package in. - * @param name - * the name of the package to find. - * @return the package with the requested name; {@code null} if the package - * can not be found. - */ - static Package getPackage(ClassLoader loader, String name) { - return loader.getPackage(name); - } - - /** - * Returns all the packages known to this class loader. - * - * @return an array with all packages known to this class loader. - */ - protected Package[] getPackages() { - synchronized (packages) { - Collection<Package> col = packages.values(); - Package[] result = new Package[col.size()]; - col.toArray(result); - return result; - } - } - - /** - * Defines and returns a new {@code Package} using the specified - * information. If {@code sealBase} is {@code null}, the package is left - * unsealed. Otherwise, the package is sealed using this URL. - * - * @param name - * the name of the package. - * @param specTitle - * the title of the specification. - * @param specVersion - * the version of the specification. - * @param specVendor - * the vendor of the specification. - * @param implTitle - * the implementation title. - * @param implVersion - * the implementation version. - * @param implVendor - * the specification vendor. - * @param sealBase - * the URL used to seal this package or {@code null} to leave the - * package unsealed. - * @return the {@code Package} object that has been created. - * @throws IllegalArgumentException - * if a package with the specified name already exists. - */ - protected Package definePackage(String name, String specTitle, String specVersion, - String specVendor, String implTitle, String implVersion, String implVendor, URL sealBase) - throws IllegalArgumentException { - - synchronized (packages) { - if (packages.containsKey(name)) { - throw new IllegalArgumentException("Package " + name + " already defined"); - } - - Package newPackage = new Package(name, specTitle, specVersion, specVendor, implTitle, - implVersion, implVendor, sealBase); - - packages.put(name, newPackage); - - return newPackage; - } - } - - /** - * Gets the signers of the specified class. This implementation returns - * {@code null}. - * - * @param c - * the {@code Class} object for which to get the signers. - * @return signers the signers of {@code c}. - */ - final Object[] getSigners(Class<?> c) { - return null; - } - - /** - * Sets the signers of the specified class. This implementation does - * nothing. - * - * @param c - * the {@code Class} object for which to set the signers. - * @param signers - * the signers for {@code c}. - */ - protected final void setSigners(Class<?> c, Object[] signers) { - return; - } - - /** - * <p> - * This must be provided by the VM vendor. It is used by - * SecurityManager.checkMemberAccess() with depth = 3. Note that - * checkMemberAccess() assumes the following stack when called:<br> - * </p> - * - * <pre> - * < user code &gt; <- want this class - * Class.getDeclared*(); - * Class.checkMemberAccess(); - * SecurityManager.checkMemberAccess(); <- current frame - * </pre> - * - * <p> - * Returns the ClassLoader of the method (including natives) at the - * specified depth on the stack of the calling thread. Frames representing - * the VM implementation of java.lang.reflect are not included in the list. - * </p> - * Notes: - * <ul> - * <li>This method operates on the defining classes of methods on stack. - * NOT the classes of receivers.</li> - * <li>The item at depth zero is the caller of this method</li> - * </ul> - * - * @param depth - * the stack depth of the requested ClassLoader - * @return the ClassLoader at the specified depth - */ - static final ClassLoader getStackClassLoader(int depth) { - Class<?>[] stack = VMStack.getClasses(depth + 1, false); - if(stack.length < depth + 1) { - return null; - } - return stack[depth].getClassLoader(); - } - - /** - * This method must be provided by the VM vendor, as it is called by - * java.lang.System.loadLibrary(). System.loadLibrary() cannot call - * Runtime.loadLibrary() because this method loads the library using the - * ClassLoader of the calling method. Loads and links the library specified - * by the argument. - * - * @param libName - * the name of the library to load - * @param loader - * the classloader in which to load the library - * @throws UnsatisfiedLinkError - * if the library could not be loaded - * @throws SecurityException - * if the library was not allowed to be loaded - * <p> - * <strong>Note: </strong>This method does nothing in the Android reference - * implementation. - * </p> - */ - static void loadLibraryWithClassLoader(String libName, ClassLoader loader) { - return; - } - - /** - * This method must be provided by the VM vendor, as it is called by - * java.lang.System.load(). System.load() cannot call Runtime.load() because - * the library is loaded using the ClassLoader of the calling method. Loads - * and links the library specified by the argument. No security check is - * done. - * <p> - * <strong>Note: </strong>This method does nothing in the Android reference - * implementation. - * </p> - * - * @param libName - * the name of the library to load - * @param loader - * the classloader in which to load the library - * @param libraryPath - * the library path to search, or null - * @throws UnsatisfiedLinkError - * if the library could not be loaded - */ - static void loadLibraryWithPath(String libName, ClassLoader loader, String libraryPath) { - return; - } - - /** - * Sets the assertion status of the class with the specified name. - * <p> - * <strong>Note: </strong>This method does nothing in the Android reference - * implementation. - * </p> - * - * @param cname - * the name of the class for which to set the assertion status. - * @param enable - * the new assertion status. - */ - public void setClassAssertionStatus(String cname, boolean enable) { - return; - } - - /** - * Sets the assertion status of the package with the specified name. - * <p> - * <strong>Note: </strong>This method does nothing in the Android reference - * implementation. - * </p> - * - * @param pname - * the name of the package for which to set the assertion status. - * @param enable - * the new assertion status. - */ - public void setPackageAssertionStatus(String pname, boolean enable) { - return; - } - - /** - * Sets the default assertion status for this class loader. - * <p> - * <strong>Note: </strong>This method does nothing in the Android reference - * implementation. - * </p> - * - * @param enable - * the new assertion status. - */ - public void setDefaultAssertionStatus(boolean enable) { - return; - } - - /** - * Sets the default assertion status for this class loader to {@code false} - * and removes any package default and class assertion status settings. - * <p> - * <strong>Note:</strong> This method does nothing in the Android reference - * implementation. - * </p> - */ - public void clearAssertionStatus() { - return; - } - - /** - * Returns the assertion status of the named class Returns the assertion - * status of the class or nested class if it has been set. Otherwise returns - * the assertion status of its package or superpackage if that has been set. - * Otherwise returns the default assertion status. Returns 1 for enabled and - * 0 for disabled. - * - * @return the assertion status. - * @param cname - * the name of class. - */ - boolean getClassAssertionStatus(String cname) { - return false; - } - - /** - * Returns the assertion status of the named package Returns the assertion - * status of the named package or superpackage if that has been set. - * Otherwise returns the default assertion status. Returns 1 for enabled and - * 0 for disabled. - * - * @return the assertion status. - * @param pname - * the name of package. - */ - boolean getPackageAssertionStatus(String pname) { - return false; - } - - /** - * Returns the default assertion status - * - * @return the default assertion status. - */ - boolean getDefaultAssertionStatus() { - return false; - } -} - -/* - * Provides a helper class that combines two existing URL enumerations into one. - * It is required for the getResources() methods. Items are fetched from the - * first enumeration until it's empty, then from the second one. - */ -class TwoEnumerationsInOne implements Enumeration<URL> { - - private Enumeration<URL> first; - - private Enumeration<URL> second; - - public TwoEnumerationsInOne(Enumeration<URL> first, Enumeration<URL> second) { - this.first = first; - this.second = second; - } - - public boolean hasMoreElements() { - return first.hasMoreElements() || second.hasMoreElements(); - } - - public URL nextElement() { - if (first.hasMoreElements()) { - return first.nextElement(); - } else { - return second.nextElement(); - } - } - -} - -/** - * Provides an explicit representation of the boot class loader. It sits at the - * head of the class loader chain and delegates requests to the VM's internal - * class loading mechanism. - */ -class BootClassLoader extends ClassLoader { - - static BootClassLoader instance; - - public static synchronized BootClassLoader getInstance() { - if (instance == null) { - instance = new BootClassLoader(); - } - - return instance; - } - - public BootClassLoader() { - super(null, true); - } - - @Override - protected Class<?> findClass(String name) throws ClassNotFoundException { - return VMClassLoader.loadClass(name, false); - } - - @Override - protected URL findResource(String name) { - return VMClassLoader.getResource(name); - } - - @SuppressWarnings("unused") - @Override - protected Enumeration<URL> findResources(String resName) throws IOException { - Enumeration<URL> result = VMClassLoader.getResources(resName); - - // VMClassLoader doesn't keep the contract for getResources() - if (result == null) { - result = EmptyEnumeration.getInstance(); - } - - return result; - } - - /** - * Returns package information for the given package. Unfortunately, the - * Android BootClassLoader doesn't really have this information, and as a - * non-secure ClassLoader, it isn't even required to, according to the spec. - * Yet, we want to provide it, in order to make all those hopeful callers of - * {@code myClass.getPackage().getName()} happy. Thus we construct a Package - * object the first time it is being requested and fill most of the fields - * with dummy values. The Package object is then put into the ClassLoader's - * Package cache, so we see the same one next time. We don't create Package - * objects for null arguments or for the default package. - * <p> - * There a limited chance that we end up with multiple Package objects - * representing the same package: It can happen when when a package is - * scattered across different JAR files being loaded by different - * ClassLoaders. Rather unlikely, and given that this whole thing is more or - * less a workaround, probably not worth the effort. - */ - @Override - protected Package getPackage(String name) { - if (name != null && !"".equals(name)) { - synchronized (this) { - Package pack = super.getPackage(name); - - if (pack == null) { - pack = definePackage(name, "Unknown", "0.0", "Unknown", "Unknown", "0.0", - "Unknown", null); - } - - return pack; - } - } - - return null; - } - - @Override - public URL getResource(String resName) { - return findResource(resName); - } - - @Override - protected Class<?> loadClass(String className, boolean resolve) - throws ClassNotFoundException { - Class<?> clazz = findLoadedClass(className); - - if (clazz == null) { - clazz = findClass(className); - } - - return clazz; - } - - @Override - public Enumeration<URL> getResources(String resName) throws IOException { - return findResources(resName); - } -} - -/** - * TODO Open issues - Missing / empty methods - Signer stuff - Protection - * domains - Assertions - */ diff --git a/luni-kernel/src/main/java/java/lang/Compiler.java b/luni-kernel/src/main/java/java/lang/Compiler.java deleted file mode 100644 index 88251e7..0000000 --- a/luni-kernel/src/main/java/java/lang/Compiler.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang; - -/** - * Placeholder class for environments which explicitly manage the action of a - * <em>Just In Time (JIT)</em> compiler. This class is usually implemented by - * the virtual machine vendor. - */ -public final class Compiler { - - /** - * Prevent this class from being instantiated. - */ - private Compiler(){ - //do nothing - } - - /** - * Executes an operation according to the specified command object. This - * method is the low-level interface to the JIT compiler. It may return any - * object or {@code null} if no JIT compiler is available. Returns null - * on Android, whether or not the system has a JIT. - * - * @param cmd - * the command object for the JIT compiler. - * @return the result of executing command or {@code null}. - */ - public static Object command(Object cmd) { - return null; - } - - /** - * Compiles the specified class using the JIT compiler and indicates if - * compilation has been successful. Does nothing and returns false on - * Android. - * - * @param classToCompile - * java.lang.Class the class to JIT compile - * @return {@code true} if the compilation has been successful; - * {@code false} if it has failed or if there is no JIT compiler - * available. - */ - public static boolean compileClass(Class<?> classToCompile) { - return false; - } - - /** - * Compiles all classes whose name matches the specified name using the JIT - * compiler and indicates if compilation has been successful. Does nothing - * and returns false on Android. - * - * @param nameRoot - * the string to match class names with. - * @return {@code true} if the compilation has been successful; - * {@code false} if it has failed or if there is no JIT compiler - * available. - */ - public static boolean compileClasses(String nameRoot) { - return false; - } - - /** - * Disables the JIT compiler. Does nothing on Android. - */ - public static void disable() { - return; - } - - /** - * Enables the JIT compiler. Does nothing on Android. - */ - public static void enable() { - return; - } - -} diff --git a/luni-kernel/src/main/java/java/lang/LangAccessImpl.java b/luni-kernel/src/main/java/java/lang/LangAccessImpl.java deleted file mode 100644 index 44d4aac..0000000 --- a/luni-kernel/src/main/java/java/lang/LangAccessImpl.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang; - -import org.apache.harmony.kernel.vm.LangAccess; - -/** - * Implementation of bridge into <code>java.lang</code>. - */ -/*package*/ final class LangAccessImpl extends LangAccess { - /** non-null; unique instance of this class */ - /*package*/ static final LangAccessImpl THE_ONE = new LangAccessImpl(); - - /** - * This class is not publicly instantiable. Use {@link #THE_ONE}. - */ - private LangAccessImpl() { - // This space intentionally left blank. - } - - /** {@inheritDoc} */ - public <T> T[] getEnumValuesInOrder(Class<T> clazz) { - ClassCache<T> cache = clazz.getClassCache(); - return cache.getEnumValuesInOrder(); - } - - /** {@inheritDoc} */ - public void unpark(Thread thread) { - thread.unpark(); - } - - /** {@inheritDoc} */ - public void parkFor(long nanos) { - Thread.currentThread().parkFor(nanos); - } - - /** {@inheritDoc} */ - public void parkUntil(long time) { - Thread.currentThread().parkUntil(time); - } -} diff --git a/luni-kernel/src/main/java/java/lang/Object.java b/luni-kernel/src/main/java/java/lang/Object.java deleted file mode 100644 index bdb66b9..0000000 --- a/luni-kernel/src/main/java/java/lang/Object.java +++ /dev/null @@ -1,354 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang; - -/** - * The root class of the Java class hierarchy. All non-primitive types - * (including arrays) inherit either directly or indirectly from this class. - * <p> - * {@code Object} provides some fundamental methods for accessing the - * {@link Class} of an object, getting its {@link #hashCode()}, or checking - * whether one object {@link #equals(Object)} another. The {@link #toString()} - * method can be used to convert an object reference into a printable string and - * is often overridden in subclasses. - * <p> - * The {@link #wait()} and {@link #notify()} methods provide a foundation for - * synchronization, acquiring and releasing an internal monitor associated with - * each {@code Object}. - */ -public class Object { - - /** - * Constructs a new instance of {@code Object}. - */ - public Object() { - } - - /** - * Creates and returns a copy of this {@code Object}. The default - * implementation returns a so-called "shallow" copy: It creates a new - * instance of the same class and then copies the field values (including - * object references) from this instance to the new instance. A "deep" copy, - * in contrast, would also recursively clone nested objects. A subclass that - * needs to implement this kind of cloning should call {@code super.clone()} - * to create the new instance and then create deep copies of the nested, - * mutable objects. - * - * @return a copy of this object. - * @throws CloneNotSupportedException - * if this object's class does not implement the {@code - * Cloneable} interface. - */ - protected Object clone() throws CloneNotSupportedException { - if (!(this instanceof Cloneable)) { - throw new CloneNotSupportedException("Class doesn't implement Cloneable"); - } - - return internalClone((Cloneable) this); - } - - /* - * Native helper method for cloning. - */ - private native Object internalClone(Cloneable o); - - /** - * Compares this instance with the specified object and indicates if they - * are equal. In order to be equal, {@code o} must represent the same object - * as this instance using a class-specific comparison. The general contract - * is that this comparison should be both transitive and reflexive. - * <p> - * The implementation in {@code Object} returns {@code true} only if {@code - * o} is the exact same object as the receiver (using the == operator for - * comparison). Subclasses often implement {@code equals(Object)} so that - * it takes into account the two object's types and states. - * </p> - * <p> - * The general contract for the {@code equals(Object)} and {@link - * #hashCode()} methods is that if {@code equals} returns {@code true} for - * any two objects, then {@code hashCode()} must return the same value for - * these objects. This means that subclasses of {@code Object} usually - * override either both methods or none of them. - * </p> - * - * @param o - * the object to compare this instance with. - * @return {@code true} if the specified object is equal to this {@code - * Object}; {@code false} otherwise. - * @see #hashCode - */ - public boolean equals(Object o) { - return this == o; - } - - /** - * Is called before the object's memory is being reclaimed by the VM. This - * can only happen once the VM has detected, during a run of the garbage - * collector, that the object is no longer reachable by any thread of the - * running application. - * <p> - * The method can be used to free system resources or perform other cleanup - * before the object is garbage collected. The default implementation of the - * method is empty, which is also expected by the VM, but subclasses can - * override {@code finalize()} as required. Uncaught exceptions which are - * thrown during the execution of this method cause it to terminate - * immediately but are otherwise ignored. - * <p> - * Note that the VM does guarantee that {@code finalize()} is called at most - * once for any object, but it doesn't guarantee when (if at all) {@code - * finalize()} will be called. For example, object B's {@code finalize()} - * can delay the execution of object A's {@code finalize()} method and - * therefore it can delay the reclamation of A's memory. To be safe, use a - * {@link java.lang.ref.ReferenceQueue}, because it provides more control - * over the way the VM deals with references during garbage collection. - * </p> - * - * @throws Throwable - * any exception which is raised during finalization; these are - * ignored by the virtual machine. - */ - protected void finalize() throws Throwable { - } - - /** - * Returns the unique instance of {@link Class} that represents this - * object's class. Note that {@code getClass()} is a special case in that it - * actually returns {@code Class<? extends Foo>} where {@code Foo} is the - * erasure of the type of the expression {@code getClass()} was called upon. - * <p> - * As an example, the following code actually compiles, although one might - * think it shouldn't: - * <p> - * <pre> - * List<Integer> l = new ArrayList<Integer>(); - * Class<? extends List> c = l.getClass(); - * </pre> - * - * @return this object's {@code Class} instance. - */ - public final native Class<? extends Object> getClass(); - - /** - * Returns an integer hash code for this object. By contract, any two - * objects for which {@code equals(Object)} returns {@code true} must return - * the same hash code value. This means that subclasses of {@code Object} - * usually override both methods or neither method. - * - * @return this object's hash code. - * @see #equals - */ - public native int hashCode(); - - /** - * Causes a thread which is waiting on this object's monitor (by means of - * calling one of the {@code wait()} methods) to be woken up. If more than - * one thread is waiting, one of them is chosen at the discretion of the - * virtual machine. The chosen thread will not run immediately. The thread - * that called {@code notify()} has to release the object's monitor first. - * Also, the chosen thread still has to compete against other threads that - * try to synchronize on the same object. - * <p> - * This method can only be invoked by a thread which owns this object's - * monitor. A thread becomes owner of an object's monitor - * </p> - * <ul> - * <li>by executing a synchronized method of that object;</li> - * <li>by executing the body of a {@code synchronized} statement that - * synchronizes on the object;</li> - * <li>by executing a synchronized static method if the object is of type - * {@code Class}.</li> - * </ul> - * - * @see #notifyAll - * @see #wait() - * @see #wait(long) - * @see #wait(long,int) - * @see java.lang.Thread - */ - public final native void notify(); - - /** - * Causes all threads which are waiting on this object's monitor (by means - * of calling one of the {@code wait()} methods) to be woken up. The threads - * will not run immediately. The thread that called {@code notify()} has to - * release the object's monitor first. Also, the threads still have to - * compete against other threads that try to synchronize on the same object. - * <p> - * This method can only be invoked by a thread which owns this object's - * monitor. A thread becomes owner of an object's monitor - * </p> - * <ul> - * <li>by executing a synchronized method of that object;</li> - * <li>by executing the body of a {@code synchronized} statement that - * synchronizes on the object;</li> - * <li>by executing a synchronized static method if the object is of type - * {@code Class}.</li> - * </ul> - * - * @throws IllegalMonitorStateException - * if the thread calling this method is not the owner of this - * object's monitor. - * @see #notify - * @see #wait() - * @see #wait(long) - * @see #wait(long,int) - * @see java.lang.Thread - */ - public final native void notifyAll(); - - /** - * Returns a string containing a concise, human-readable description of this - * object. Subclasses are encouraged to override this method and provide an - * implementation that takes into account the object's type and data. The - * default implementation simply concatenates the class name, the '@' sign - * and a hexadecimal representation of the object's {@link #hashCode()}, - * that is, it is equivalent to the following expression: - * - * <pre> - * getClass().getName() + '@' + Integer.toHexString(hashCode()) - * </pre> - * - * @return a printable representation of this object. - */ - public String toString() { - return getClass().getName() + '@' + Integer.toHexString(hashCode()); - } - - /** - * Causes the calling thread to wait until another thread calls the {@code - * notify()} or {@code notifyAll()} method of this object. This method can - * only be invoked by a thread which owns this object's monitor; see - * {@link #notify()} on how a thread can become the owner of a monitor. - * <p> - * A waiting thread can be sent {@code interrupt()} to cause it to - * prematurely stop waiting, so {@code wait} should be called in a loop to - * check that the condition that has been waited for has been met before - * continuing. - * </p> - * <p> - * While the thread waits, it gives up ownership of this object's monitor. - * When it is notified (or interrupted), it re-acquires the monitor before - * it starts running. - * </p> - * - * @throws IllegalMonitorStateException - * if the thread calling this method is not the owner of this - * object's monitor. - * @throws InterruptedException - * if another thread interrupts this thread while it is waiting. - * @see #notify - * @see #notifyAll - * @see #wait(long) - * @see #wait(long,int) - * @see java.lang.Thread - */ - public final void wait() throws InterruptedException { - wait(0 ,0); - } - - /** - * Causes the calling thread to wait until another thread calls the {@code - * notify()} or {@code notifyAll()} method of this object or until the - * specified timeout expires. This method can only be invoked by a thread - * which owns this object's monitor; see {@link #notify()} on how a thread - * can become the owner of a monitor. - * <p> - * A waiting thread can be sent {@code interrupt()} to cause it to - * prematurely stop waiting, so {@code wait} should be called in a loop to - * check that the condition that has been waited for has been met before - * continuing. - * </p> - * <p> - * While the thread waits, it gives up ownership of this object's monitor. - * When it is notified (or interrupted), it re-acquires the monitor before - * it starts running. - * </p> - * - * @param millis - * the maximum time to wait in milliseconds. - * @throws IllegalArgumentException - * if {@code millis < 0}. - * @throws IllegalMonitorStateException - * if the thread calling this method is not the owner of this - * object's monitor. - * @throws InterruptedException - * if another thread interrupts this thread while it is waiting. - * @see #notify - * @see #notifyAll - * @see #wait() - * @see #wait(long,int) - * @see java.lang.Thread - */ - public final void wait(long millis) throws InterruptedException { - wait(millis, 0); - } - - /** - * Causes the calling thread to wait until another thread calls the {@code - * notify()} or {@code notifyAll()} method of this object or until the - * specified timeout expires. This method can only be invoked by a thread - * that owns this object's monitor; see {@link #notify()} on how a thread - * can become the owner of a monitor. - * <p> - * A waiting thread can be sent {@code interrupt()} to cause it to - * prematurely stop waiting, so {@code wait} should be called in a loop to - * check that the condition that has been waited for has been met before - * continuing. - * </p> - * <p> - * While the thread waits, it gives up ownership of this object's monitor. - * When it is notified (or interrupted), it re-acquires the monitor before - * it starts running. - * </p> - * - * @param millis - * the maximum time to wait in milliseconds. - * @param nanos - * the fraction of a millisecond to wait, specified in - * nanoseconds. - * @throws IllegalArgumentException - * if {@code millis < 0}, {@code nanos < 0} or {@code nanos > - * 999999}. - * @throws IllegalMonitorStateException - * if the thread calling this method is not the owner of this - * object's monitor. - * @throws InterruptedException - * if another thread interrupts this thread while it is waiting. - * @see #notify - * @see #notifyAll - * @see #wait() - * @see #wait(long,int) - * @see java.lang.Thread - */ - public final native void wait(long millis, int nanos) throws InterruptedException; -} diff --git a/luni-kernel/src/main/java/java/lang/Package.java b/luni-kernel/src/main/java/java/lang/Package.java deleted file mode 100644 index 9ad40b8..0000000 --- a/luni-kernel/src/main/java/java/lang/Package.java +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang; - -import dalvik.system.VMStack; - -import java.lang.annotation.Annotation; -import java.lang.reflect.AnnotatedElement; -import java.net.URL; - -/** - * Contains information about a Java package. This includes implementation and - * specification versions. Typically this information is retrieved from the - * manifest. - * <p> - * Packages are managed by class loaders. All classes loaded by the same loader - * from the same package share a {@code Package} instance. - * </p> - * - * @see java.lang.ClassLoader - */ -public class Package implements AnnotatedElement { - - private final String name, specTitle, specVersion, specVendor, implTitle, - implVersion, implVendor; - private final URL sealBase; - - Package(String name, String specTitle, String specVersion, String specVendor, - String implTitle, String implVersion, String implVendor, URL sealBase) { - this.name = name; - this.specTitle = specTitle; - this.specVersion = specVersion; - this.specVendor = specVendor; - this.implTitle = implTitle; - this.implVersion = implVersion; - this.implVendor = implVendor; - this.sealBase = sealBase; - } - - /** - * Gets the annotation associated with the specified annotation type and - * this package, if present. - * - * @param annotationType - * the annotation type to look for. - * @return an instance of {@link Annotation} or {@code null}. - * @see java.lang.reflect.AnnotatedElement#getAnnotation(java.lang.Class) - */ - @SuppressWarnings("unchecked") - public <A extends Annotation> A getAnnotation(Class<A> annotationType) { - Annotation[] list = getAnnotations(); - for (int i = 0; i < list.length; i++) { - if (annotationType.isInstance(list[i])) { - return (A) list[i]; - } - } - - return null; - } - - /** - * Gets all annotations associated with this package, if any. - * - * @return an array of {@link Annotation} instances, which may be empty. - * @see java.lang.reflect.AnnotatedElement#getAnnotations() - */ - public Annotation[] getAnnotations() { - return getDeclaredAnnotations(this, true); - } - - /** - * Gets all annotations directly declared on this package, if any. - * - * @return an array of {@link Annotation} instances, which may be empty. - * @see java.lang.reflect.AnnotatedElement#getDeclaredAnnotations() - */ - public Annotation[] getDeclaredAnnotations() { - return getDeclaredAnnotations(this, false); - } - - /* - * Returns the list of declared annotations of the given package. - * If no annotations exist, an empty array is returned. - * - * @param pkg the package of interest - * @param publicOnly reflects whether we want only public annotation or all - * of them. - * @return the list of annotations - */ - // TODO(Google) Provide proper (native) implementation. - private static native Annotation[] getDeclaredAnnotations(Package pkg, - boolean publicOnly); - - /** - * Indicates whether the specified annotation is present. - * - * @param annotationType - * the annotation type to look for. - * @return {@code true} if the annotation is present; {@code false} - * otherwise. - * @see java.lang.reflect.AnnotatedElement#isAnnotationPresent(java.lang.Class) - */ - public boolean isAnnotationPresent( - Class<? extends Annotation> annotationType) { - return getAnnotation(annotationType) != null; - } - - /** - * Returns the title of the implementation of this package, or {@code null} - * if this is unknown. The format of this string is unspecified. - * - * @return the implementation title, may be {@code null}. - */ - public String getImplementationTitle() { - return implTitle; - } - - /** - * Returns the name of the vendor or organization that provides this - * implementation of the package, or {@code null} if this is unknown. The - * format of this string is unspecified. - * - * @return the implementation vendor name, may be {@code null}. - */ - public String getImplementationVendor() { - return implVendor; - } - - /** - * Returns the version of the implementation of this package, or {@code - * null} if this is unknown. The format of this string is unspecified. - * - * @return the implementation version, may be {@code null}. - */ - public String getImplementationVersion() { - return implVersion; - } - - /** - * Returns the name of this package in the standard dot notation; for - * example: "java.lang". - * - * @return the name of this package. - */ - public String getName() { - return name; - } - - /** - * Attempts to locate the requested package in the caller's class loader. If - * no package information can be located, {@code null} is returned. - * - * @param packageName - * the name of the package to find. - * @return the requested package, or {@code null}. - * @see ClassLoader#getPackage(java.lang.String) - */ - public static Package getPackage(String packageName) { - ClassLoader classloader = VMStack.getCallingClassLoader(); - return classloader.getPackage(packageName); - } - - /** - * Returns all the packages known to the caller's class loader. - * - * @return all the packages known to the caller's class loader. - * @see ClassLoader#getPackages - */ - public static Package[] getPackages() { - ClassLoader classloader = VMStack.getCallingClassLoader(); - return classloader.getPackages(); - } - - /** - * Returns the title of the specification this package implements, or - * {@code null} if this is unknown. - * - * @return the specification title, may be {@code null}. - */ - public String getSpecificationTitle() { - return specTitle; - } - - /** - * Returns the name of the vendor or organization that owns and maintains - * the specification this package implements, or {@code null} if this is - * unknown. - * - * @return the specification vendor name, may be {@code null}. - */ - public String getSpecificationVendor() { - return specVendor; - } - - /** - * Returns the version of the specification this package implements, or - * {@code null} if this is unknown. The version string is a sequence of - * non-negative integers separated by dots; for example: "1.2.3". - * - * @return the specification version string, may be {@code null}. - */ - public String getSpecificationVersion() { - return specVersion; - } - - @Override - public int hashCode() { - return name.hashCode(); - } - - /** - * Indicates whether this package's specification version is compatible with - * the specified version string. Version strings are compared by comparing - * each dot separated part of the version as an integer. - * - * @param version - * the version string to compare against. - * @return {@code true} if the package versions are compatible; {@code - * false} otherwise. - * @throws NumberFormatException - * if this package's version string or the one provided are not - * in the correct format. - */ - public boolean isCompatibleWith(String version) - throws NumberFormatException { - String[] requested = version.split("\\."); - String[] provided = specVersion.split("\\."); - - for (int i = 0; i < Math.min(requested.length, provided.length); i++) { - int reqNum = Integer.parseInt(requested[i]); - int provNum = Integer.parseInt(provided[i]); - - if (reqNum > provNum) { - return false; - } else if (reqNum < provNum) { - return true; - } - } - - if (requested.length > provided.length) { - return false; - } - - return true; - } - - /** - * Indicates whether this package is sealed. - * - * @return {@code true} if this package is sealed; {@code false} otherwise. - */ - public boolean isSealed() { - return sealBase != null; - } - - /** - * Indicates whether this package is sealed with respect to the specified - * URL. - * - * @param url - * the URL to check. - * @return {@code true} if this package is sealed with {@code url}; {@code - * false} otherwise - */ - public boolean isSealed(URL url) { - return sealBase != null && sealBase.sameFile(url); - } - - @Override - public String toString() { - return "package " + name; - } -} diff --git a/luni-kernel/src/main/java/java/lang/ProcessManager.java b/luni-kernel/src/main/java/java/lang/ProcessManager.java deleted file mode 100644 index 318fe9a..0000000 --- a/luni-kernel/src/main/java/java/lang/ProcessManager.java +++ /dev/null @@ -1,414 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang; - -import java.io.File; -import java.io.FileDescriptor; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; -import java.util.HashMap; -import java.util.Map; -import java.util.Arrays; -import java.util.logging.Logger; -import java.util.logging.Level; - -/** - * Manages child processes. - * - * <p>Harmony's native implementation (for comparison purposes): - * http://tinyurl.com/3ytwuq - */ -final class ProcessManager { - - /** - * constant communicated from native code indicating that a - * child died, but it was unable to determine the status - */ - private static final int WAIT_STATUS_UNKNOWN = -1; - - /** - * constant communicated from native code indicating that there - * are currently no children to wait for - */ - private static final int WAIT_STATUS_NO_CHILDREN = -2; - - /** - * constant communicated from native code indicating that a wait() - * call returned -1 and set an undocumented (and hence unexpected) errno - */ - private static final int WAIT_STATUS_STRANGE_ERRNO = -3; - - /** - * Initializes native static state. - */ - static native void staticInitialize(); - static { - staticInitialize(); - } - - /** - * Map from pid to Process. We keep weak references to the Process objects - * and clean up the entries when no more external references are left. The - * process objects themselves don't require much memory, but file - * descriptors (associated with stdin/out/err in this case) can be - * a scarce resource. - */ - private final Map<Integer, ProcessReference> processReferences - = new HashMap<Integer, ProcessReference>(); - - /** Keeps track of garbage-collected Processes. */ - private final ProcessReferenceQueue referenceQueue - = new ProcessReferenceQueue(); - - private ProcessManager() { - // Spawn a thread to listen for signals from child processes. - Thread processThread = new Thread(ProcessManager.class.getName()) { - @Override - public void run() { - watchChildren(); - } - }; - processThread.setDaemon(true); - processThread.start(); - } - - /** - * Kills the process with the given ID. - * - * @parm pid ID of process to kill - */ - private static native void kill(int pid) throws IOException; - - /** - * Cleans up after garbage collected processes. Requires the lock on the - * map. - */ - void cleanUp() { - ProcessReference reference; - while ((reference = referenceQueue.poll()) != null) { - synchronized (processReferences) { - processReferences.remove(reference.processId); - } - } - } - - /** - * Listens for signals from processes and calls back to - * {@link #onExit(int,int)}. - */ - native void watchChildren(); - - /** - * Called by {@link #watchChildren()} when a child process exits. - * - * @param pid ID of process that exited - * @param exitValue value the process returned upon exit - */ - void onExit(int pid, int exitValue) { - ProcessReference processReference = null; - - synchronized (processReferences) { - cleanUp(); - if (pid >= 0) { - processReference = processReferences.remove(pid); - } else if (exitValue == WAIT_STATUS_NO_CHILDREN) { - if (processReferences.isEmpty()) { - /* - * There are no eligible children; wait for one to be - * added. The wait() will return due to the - * notifyAll() call below. - */ - try { - processReferences.wait(); - } catch (InterruptedException ex) { - // This should never happen. - throw new AssertionError("unexpected interrupt"); - } - } else { - /* - * A new child was spawned just before we entered - * the synchronized block. We can just fall through - * without doing anything special and land back in - * the native wait(). - */ - } - } else { - // Something weird is happening; abort! - throw new AssertionError("unexpected wait() behavior"); - } - } - - if (processReference != null) { - ProcessImpl process = processReference.get(); - if (process != null) { - process.setExitValue(exitValue); - } - } - } - - /** - * Executes a native process. Fills in in, out, and err and returns the - * new process ID upon success. - */ - static native int exec(String[] command, String[] environment, - String workingDirectory, FileDescriptor in, FileDescriptor out, - FileDescriptor err, boolean redirectErrorStream) throws IOException; - - /** - * Executes a process and returns an object representing it. - */ - Process exec(String[] taintedCommand, String[] taintedEnvironment, File workingDirectory, - boolean redirectErrorStream) throws IOException { - // Make sure we throw the same exceptions as the RI. - if (taintedCommand == null) { - throw new NullPointerException(); - } - if (taintedCommand.length == 0) { - throw new IndexOutOfBoundsException(); - } - - // Handle security and safety by copying mutable inputs and checking them. - String[] command = taintedCommand.clone(); - String[] environment = taintedEnvironment != null ? taintedEnvironment.clone() : null; - SecurityManager securityManager = System.getSecurityManager(); - if (securityManager != null) { - securityManager.checkExec(command[0]); - } - // Check we're not passing null Strings to the native exec. - for (String arg : command) { - if (arg == null) { - throw new NullPointerException(); - } - } - // The environment is allowed to be null or empty, but no element may be null. - if (environment != null) { - for (String env : environment) { - if (env == null) { - throw new NullPointerException(); - } - } - } - - FileDescriptor in = new FileDescriptor(); - FileDescriptor out = new FileDescriptor(); - FileDescriptor err = new FileDescriptor(); - - String workingPath = (workingDirectory == null) - ? null - : workingDirectory.getPath(); - - // Ensure onExit() doesn't access the process map before we add our - // entry. - synchronized (processReferences) { - int pid; - try { - pid = exec(command, environment, workingPath, in, out, err, redirectErrorStream); - } catch (IOException e) { - IOException wrapper = new IOException("Error running exec()." - + " Command: " + Arrays.toString(command) - + " Working Directory: " + workingDirectory - + " Environment: " + Arrays.toString(environment)); - wrapper.initCause(e); - throw wrapper; - } - ProcessImpl process = new ProcessImpl(pid, in, out, err); - ProcessReference processReference - = new ProcessReference(process, referenceQueue); - processReferences.put(pid, processReference); - - /* - * This will wake up the child monitor thread in case there - * weren't previously any children to wait on. - */ - processReferences.notifyAll(); - - return process; - } - } - - static class ProcessImpl extends Process { - - /** Process ID. */ - final int id; - - final InputStream errorStream; - - /** Reads output from process. */ - final InputStream inputStream; - - /** Sends output to process. */ - final OutputStream outputStream; - - /** The process's exit value. */ - Integer exitValue = null; - final Object exitValueMutex = new Object(); - - ProcessImpl(int id, FileDescriptor in, FileDescriptor out, - FileDescriptor err) { - this.id = id; - - this.errorStream = new ProcessInputStream(err); - this.inputStream = new ProcessInputStream(in); - this.outputStream = new ProcessOutputStream(out); - } - - public void destroy() { - try { - kill(this.id); - } catch (IOException e) { - Logger.getLogger(Runtime.class.getName()).log(Level.FINE, - "Failed to destroy process " + id + ".", e); - } - } - - public int exitValue() { - synchronized (exitValueMutex) { - if (exitValue == null) { - throw new IllegalThreadStateException( - "Process has not yet terminated."); - } - - return exitValue; - } - } - - public InputStream getErrorStream() { - return this.errorStream; - } - - public InputStream getInputStream() { - return this.inputStream; - } - - public OutputStream getOutputStream() { - return this.outputStream; - } - - public int waitFor() throws InterruptedException { - synchronized (exitValueMutex) { - while (exitValue == null) { - exitValueMutex.wait(); - } - return exitValue; - } - } - - void setExitValue(int exitValue) { - synchronized (exitValueMutex) { - this.exitValue = exitValue; - exitValueMutex.notifyAll(); - } - } - - @Override - public String toString() { - return "Process[id=" + id + "]"; - } - } - - static class ProcessReference extends WeakReference<ProcessImpl> { - - final int processId; - - public ProcessReference(ProcessImpl referent, - ProcessReferenceQueue referenceQueue) { - super(referent, referenceQueue); - this.processId = referent.id; - } - } - - static class ProcessReferenceQueue extends ReferenceQueue<ProcessImpl> { - - @Override - public ProcessReference poll() { - // Why couldn't they get the generics right on ReferenceQueue? :( - Object reference = super.poll(); - return (ProcessReference) reference; - } - } - - static final ProcessManager instance = new ProcessManager(); - - /** Gets the process manager. */ - static ProcessManager getInstance() { - return instance; - } - - /** Automatically closes fd when collected. */ - private static class ProcessInputStream extends FileInputStream { - - private FileDescriptor fd; - - private ProcessInputStream(FileDescriptor fd) { - super(fd); - this.fd = fd; - } - - @Override - public void close() throws IOException { - try { - super.close(); - } finally { - synchronized (this) { - if (fd != null && fd.valid()) { - try { - ProcessManager.close(fd); - } finally { - fd = null; - } - } - } - } - } - } - - /** Automatically closes fd when collected. */ - private static class ProcessOutputStream extends FileOutputStream { - - private FileDescriptor fd; - - private ProcessOutputStream(FileDescriptor fd) { - super(fd); - this.fd = fd; - } - - @Override - public void close() throws IOException { - try { - super.close(); - } finally { - synchronized (this) { - if (fd != null && fd.valid()) { - try { - ProcessManager.close(fd); - } finally { - fd = null; - } - } - } - } - } - } - - /** Closes the given file descriptor. */ - private static native void close(FileDescriptor fd) throws IOException; -} diff --git a/luni-kernel/src/main/java/java/lang/Runtime.java b/luni-kernel/src/main/java/java/lang/Runtime.java deleted file mode 100644 index 6d928f7..0000000 --- a/luni-kernel/src/main/java/java/lang/Runtime.java +++ /dev/null @@ -1,836 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PipedInputStream; -import java.io.PipedOutputStream; -import java.io.Reader; -import java.io.InputStreamReader; -import java.io.UnsupportedEncodingException; -import java.io.Writer; - -import java.util.StringTokenizer; -import java.util.List; -import java.util.ArrayList; - -import dalvik.system.VMDebug; -import dalvik.system.VMStack; - -/** - * Allows Java applications to interface with the environment in which they are - * running. Applications can not create an instance of this class, but they can - * get a singleton instance by invoking {@link #getRuntime()}. - * - * @see System - */ -public class Runtime { - - /** - * Holds the Singleton global instance of Runtime. - */ - private static final Runtime mRuntime = new Runtime(); - - /** - * Holds the library paths, used for native library lookup. - */ - private final String[] mLibPaths; - - /** - * Holds the list of threads to run when the VM terminates - */ - private List<Thread> shutdownHooks = new ArrayList<Thread>(); - - /** - * Reflects whether finalization should be run for all objects - * when the VM terminates. - */ - private static boolean finalizeOnExit; - - /** - * Reflects whether we are already shutting down the VM. - */ - private boolean shuttingDown; - - /** - * Reflects whether we are tracing method calls. - */ - private boolean tracingMethods; - - /** - * Prevent this class from being instantiated. - */ - private Runtime(){ - String pathList = System.getProperty("java.library.path", "."); - String pathSep = System.getProperty("path.separator", ":"); - String fileSep = System.getProperty("file.separator", "/"); - - mLibPaths = pathList.split(pathSep); - - int i; - - if (false) - System.out.println("Runtime paths:"); - - // Add a '/' to the end so we don't have to do the property lookup - // and concatenation later. - for (i = 0; i < mLibPaths.length; i++) { - if (!mLibPaths[i].endsWith(fileSep)) - mLibPaths[i] += fileSep; - if (false) - System.out.println(" " + mLibPaths[i]); - } - } - - /** - * Executes the specified command and its arguments in a separate native - * process. The new process inherits the environment of the caller. Calling - * this method is equivalent to calling {@code exec(progArray, null, null)}. - * - * @param progArray - * the array containing the program to execute as well as any - * arguments to the program. - * @return the new {@code Process} object that represents the native - * process. - * @throws IOException - * if the requested program can not be executed. - * @throws SecurityException - * if the current {@code SecurityManager} disallows program - * execution. - * @see SecurityManager#checkExec - */ - public Process exec(String[] progArray) throws java.io.IOException { - return exec(progArray, null, null); - } - - /** - * Executes the specified command and its arguments in a separate native - * process. The new process uses the environment provided in {@code envp}. - * Calling this method is equivalent to calling - * {@code exec(progArray, envp, null)}. - * - * @param progArray - * the array containing the program to execute as well as any - * arguments to the program. - * @param envp - * the array containing the environment to start the new process - * in. - * @return the new {@code Process} object that represents the native - * process. - * @throws IOException - * if the requested program can not be executed. - * @throws SecurityException - * if the current {@code SecurityManager} disallows program - * execution. - * @see SecurityManager#checkExec - */ - public Process exec(String[] progArray, String[] envp) throws java.io.IOException { - return exec(progArray, envp, null); - } - - /** - * Executes the specified command and its arguments in a separate native - * process. The new process uses the environment provided in {@code envp} - * and the working directory specified by {@code directory}. - * - * @param progArray - * the array containing the program to execute as well as any - * arguments to the program. - * @param envp - * the array containing the environment to start the new process - * in. - * @param directory - * the directory in which to execute the program. If {@code null}, - * execute if in the same directory as the parent process. - * @return the new {@code Process} object that represents the native - * process. - * @throws IOException - * if the requested program can not be executed. - * @throws SecurityException - * if the current {@code SecurityManager} disallows program - * execution. - * @see SecurityManager#checkExec - */ - public Process exec(String[] progArray, String[] envp, File directory) throws IOException { - // BEGIN android-changed: push responsibility for argument checking into ProcessManager - return ProcessManager.getInstance().exec(progArray, envp, directory, false); - // END android-changed - } - - /** - * Executes the specified program in a separate native process. The new - * process inherits the environment of the caller. Calling this method is - * equivalent to calling {@code exec(prog, null, null)}. - * - * @param prog - * the name of the program to execute. - * @return the new {@code Process} object that represents the native - * process. - * @throws IOException - * if the requested program can not be executed. - * @throws SecurityException - * if the current {@code SecurityManager} disallows program - * execution. - * @see SecurityManager#checkExec - */ - public Process exec(String prog) throws java.io.IOException { - return exec(prog, null, null); - } - - /** - * Executes the specified program in a separate native process. The new - * process uses the environment provided in {@code envp}. Calling this - * method is equivalent to calling {@code exec(prog, envp, null)}. - * - * @param prog - * the name of the program to execute. - * @param envp - * the array containing the environment to start the new process - * in. - * @return the new {@code Process} object that represents the native - * process. - * @throws IOException - * if the requested program can not be executed. - * @throws SecurityException - * if the current {@code SecurityManager} disallows program - * execution. - * @see SecurityManager#checkExec - */ - public Process exec(String prog, String[] envp) throws java.io.IOException { - return exec(prog, envp, null); - } - - /** - * Executes the specified program in a separate native process. The new - * process uses the environment provided in {@code envp} and the working - * directory specified by {@code directory}. - * - * @param prog - * the name of the program to execute. - * @param envp - * the array containing the environment to start the new process - * in. - * @param directory - * the directory in which to execute the program. If {@code null}, - * execute if in the same directory as the parent process. - * @return the new {@code Process} object that represents the native - * process. - * @throws IOException - * if the requested program can not be executed. - * @throws SecurityException - * if the current {@code SecurityManager} disallows program - * execution. - * @see SecurityManager#checkExec - */ - public Process exec(String prog, String[] envp, File directory) throws java.io.IOException { - // Sanity checks - if (prog == null) { - throw new NullPointerException(); - } else if (prog.length() == 0) { - throw new IllegalArgumentException(); - } - - // Break down into tokens, as described in Java docs - StringTokenizer tokenizer = new StringTokenizer(prog); - int length = tokenizer.countTokens(); - String[] progArray = new String[length]; - for (int i = 0; i < length; i++) { - progArray[i] = tokenizer.nextToken(); - } - - // Delegate - return exec(progArray, envp, directory); - } - - /** - * Causes the virtual machine to stop running and the program to exit. If - * {@link #runFinalizersOnExit(boolean)} has been previously invoked with a - * {@code true} argument, then all objects will be properly - * garbage-collected and finalized first. - * - * @param code - * the return code. By convention, non-zero return codes indicate - * abnormal terminations. - * @throws SecurityException - * if the current {@code SecurityManager} does not allow the - * running thread to terminate the virtual machine. - * @see SecurityManager#checkExit - */ - public void exit(int code) { - // Security checks - SecurityManager smgr = System.getSecurityManager(); - if (smgr != null) { - smgr.checkExit(code); - } - - // Make sure we don't try this several times - synchronized(this) { - if (!shuttingDown) { - shuttingDown = true; - - Thread[] hooks; - synchronized (shutdownHooks) { - // create a copy of the hooks - hooks = new Thread[shutdownHooks.size()]; - shutdownHooks.toArray(hooks); - } - - // Start all shutdown hooks concurrently - for (int i = 0; i < hooks.length; i++) { - hooks[i].start(); - } - - // Wait for all shutdown hooks to finish - for (Thread hook : hooks) { - try { - hook.join(); - } catch (InterruptedException ex) { - // Ignore, since we are at VM shutdown. - } - } - - // Ensure finalization on exit, if requested - if (finalizeOnExit) { - runFinalization(true); - } - - // Get out of here finally... - nativeExit(code, true); - } - } - } - - /** - * Returns the amount of free memory resources which are available to the - * running program. - * - * @return the approximate amount of free memory, measured in bytes. - */ - public native long freeMemory(); - - /** - * Indicates to the virtual machine that it would be a good time to run the - * garbage collector. Note that this is a hint only. There is no guarantee - * that the garbage collector will actually be run. - */ - public native void gc(); - - /** - * Returns the single {@code Runtime} instance. - * - * @return the {@code Runtime} object for the current application. - */ - public static Runtime getRuntime() { - return mRuntime; - } - - /** - * Loads and links the dynamic library that is identified through the - * specified path. This method is similar to {@link #loadLibrary(String)}, - * but it accepts a full path specification whereas {@code loadLibrary} just - * accepts the name of the library to load. - * - * @param pathName - * the absolute (platform dependent) path to the library to load. - * @throws UnsatisfiedLinkError - * if the library can not be loaded. - * @throws SecurityException - * if the current {@code SecurityManager} does not allow to load - * the library. - * @see SecurityManager#checkLink - */ - public void load(String pathName) { - // Security checks - SecurityManager smgr = System.getSecurityManager(); - if (smgr != null) { - smgr.checkLink(pathName); - } - - load(pathName, VMStack.getCallingClassLoader()); - } - - /* - * Loads and links a library without security checks. - */ - void load(String filename, ClassLoader loader) { - if (filename == null) { - throw new NullPointerException("library path was null."); - } - if (!nativeLoad(filename, loader)) { - throw new UnsatisfiedLinkError( - "Library " + filename + " not found"); - } - } - - /** - * Loads and links the library with the specified name. The mapping of the - * specified library name to the full path for loading the library is - * implementation-dependent. - * - * @param libName - * the name of the library to load. - * @throws UnsatisfiedLinkError - * if the library can not be loaded. - * @throws SecurityException - * if the current {@code SecurityManager} does not allow to load - * the library. - * @see SecurityManager#checkLink - */ - public void loadLibrary(String libName) { - // Security checks - SecurityManager smgr = System.getSecurityManager(); - if (smgr != null) { - smgr.checkLink(libName); - } - - loadLibrary(libName, VMStack.getCallingClassLoader()); - } - - /* - * Loads and links a library without security checks. - */ - void loadLibrary(String libname, ClassLoader loader) { - String filename; - int i; - - if (loader != null) { - filename = loader.findLibrary(libname); - if (filename != null && nativeLoad(filename, loader)) - return; - // else fall through to exception - } else { - filename = System.mapLibraryName(libname); - for (i = 0; i < mLibPaths.length; i++) { - if (false) - System.out.println("Trying " + mLibPaths[i] + filename); - if (nativeLoad(mLibPaths[i] + filename, loader)) - return; - } - } - - throw new UnsatisfiedLinkError("Library " + libname + " not found"); - } - - private static native void nativeExit(int code, boolean isExit); - - private static native boolean nativeLoad(String filename, - ClassLoader loader); - - /** - * Requests proper finalization for all Objects on the heap. - * - * @param forced Decides whether the VM really needs to do this (true) - * or if this is just a suggestion that can safely be ignored - * (false). - */ - private native void runFinalization(boolean forced); - - /** - * Provides a hint to the virtual machine that it would be useful to attempt - * to perform any outstanding object finalizations. - * - */ - public void runFinalization() { - runFinalization(false); - } - - /** - * Sets the flag that indicates whether all objects are finalized when the - * virtual machine is about to exit. Note that all finalization which occurs - * when the system is exiting is performed after all running threads have - * been terminated. - * - * @param run - * {@code true} to enable finalization on exit, {@code false} to - * disable it. - * @deprecated This method is unsafe. - */ - @Deprecated - public static void runFinalizersOnExit(boolean run) { - SecurityManager smgr = System.getSecurityManager(); - if (smgr != null) { - smgr.checkExit(0); - } - finalizeOnExit = run; - } - - /** - * Returns the total amount of memory which is available to the running - * program. - * - * @return the total amount of memory, measured in bytes. - */ - public native long totalMemory(); - - /** - * Switches the output of debug information for instructions on or off. - * For the Android 1.0 reference implementation, this method does nothing. - * - * @param enable - * {@code true} to switch tracing on, {@code false} to switch it - * off. - */ - public void traceInstructions(boolean enable) { - // TODO(Google) Provide some implementation for this. - return; - } - - /** - * Switches the output of debug information for methods on or off. - * - * @param enable - * {@code true} to switch tracing on, {@code false} to switch it - * off. - */ - public void traceMethodCalls(boolean enable) { - if (enable != tracingMethods) { - if (enable) { - VMDebug.startMethodTracing(); - } else { - VMDebug.stopMethodTracing(); - } - tracingMethods = enable; - } - } - - /** - * Returns the localized version of the specified input stream. The input - * stream that is returned automatically converts all characters from the - * local character set to Unicode after reading them from the underlying - * stream. - * - * @param stream - * the input stream to localize. - * @return the localized input stream. - * @deprecated Use {@link InputStreamReader}. - */ - @Deprecated - public InputStream getLocalizedInputStream(InputStream stream) { - if (System.getProperty("file.encoding", "UTF-8").equals("UTF-8")) { - return stream; - } - return new ReaderInputStream(stream); - } - - /** - * Returns the localized version of the specified output stream. The output - * stream that is returned automatically converts all characters from - * Unicode to the local character set before writing them to the underlying - * stream. - * - * @param stream - * the output stream to localize. - * @return the localized output stream. - * @deprecated Use {@link OutputStreamWriter}. - */ - @Deprecated - public OutputStream getLocalizedOutputStream(OutputStream stream) { - if (System.getProperty("file.encoding", "UTF-8").equals("UTF-8")) { - return stream; - } - return new WriterOutputStream(stream ); - } - - /** - * Registers a virtual-machine shutdown hook. A shutdown hook is a - * {@code Thread} that is ready to run, but has not yet been started. All - * registered shutdown hooks will be executed once the virtual machine shuts - * down properly. A proper shutdown happens when either the - * {@link #exit(int)} method is called or the surrounding system decides to - * terminate the application, for example in response to a {@code CTRL-C} or - * a system-wide shutdown. A termination of the virtual machine due to the - * {@link #halt(int)} method, an {@link Error} or a {@code SIGKILL}, in - * contrast, is not considered a proper shutdown. In these cases the - * shutdown hooks will not be run. - * <p> - * Shutdown hooks are run concurrently and in an unspecified order. Hooks - * failing due to an unhandled exception are not a problem, but the stack - * trace might be printed to the console. Once initiated, the whole shutdown - * process can only be terminated by calling {@code halt()}. - * <p> - * If {@link #runFinalizersOnExit(boolean)} has been called with a {@code - * true} argument, garbage collection and finalization will take place after - * all hooks are either finished or have failed. Then the virtual machine - * terminates. - * <p> - * It is recommended that shutdown hooks do not do any time-consuming - * activities, in order to not hold up the shutdown process longer than - * necessary. - * - * @param hook - * the shutdown hook to register. - * @throws IllegalArgumentException - * if the hook has already been started or if it has already - * been registered. - * @throws IllegalStateException - * if the virtual machine is already shutting down. - * @throws SecurityException - * if a SecurityManager is registered and the calling code - * doesn't have the RuntimePermission("shutdownHooks"). - */ - public void addShutdownHook(Thread hook) { - // Sanity checks - if (hook == null) { - throw new NullPointerException("Hook may not be null."); - } - - if (shuttingDown) { - throw new IllegalStateException("VM already shutting down"); - } - - if (hook.hasBeenStarted) { - throw new IllegalArgumentException("Hook has already been started"); - } - - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new RuntimePermission("shutdownHooks")); - } - - synchronized (shutdownHooks) { - if (shutdownHooks.contains(hook)) { - throw new IllegalArgumentException("Hook already registered."); - } - - shutdownHooks.add(hook); - } - } - - /** - * Unregisters a previously registered virtual machine shutdown hook. - * - * @param hook - * the shutdown hook to remove. - * @return {@code true} if the hook has been removed successfully; {@code - * false} otherwise. - * @throws IllegalStateException - * if the virtual machine is already shutting down. - * @throws SecurityException - * if a SecurityManager is registered and the calling code - * doesn't have the RuntimePermission("shutdownHooks"). - */ - public boolean removeShutdownHook(Thread hook) { - // Sanity checks - if (hook == null) { - throw new NullPointerException("Hook may not be null."); - } - - if (shuttingDown) { - throw new IllegalStateException("VM already shutting down"); - } - - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new RuntimePermission("shutdownHooks")); - } - - synchronized (shutdownHooks) { - return shutdownHooks.remove(hook); - } - } - - /** - * Causes the virtual machine to stop running, and the program to exit. - * Neither shutdown hooks nor finalizers are run before. - * - * @param code - * the return code. By convention, non-zero return codes indicate - * abnormal terminations. - * @throws SecurityException - * if the current {@code SecurityManager} does not allow the - * running thread to terminate the virtual machine. - * @see SecurityManager#checkExit - * @see #addShutdownHook(Thread) - * @see #removeShutdownHook(Thread) - * @see #runFinalizersOnExit(boolean) - */ - public void halt(int code) { - // Security checks - SecurityManager smgr = System.getSecurityManager(); - if (smgr != null) { - smgr.checkExit(code); - } - - // Get out of here... - nativeExit(code, false); - } - - /** - * Returns the number of processors available to the virtual machine. The - * Android reference implementation (currently) always returns 1. - * - * @return the number of available processors, at least 1. - */ - public int availableProcessors() { - return 1; - } - - /** - * Returns the maximum amount of memory that may be used by the virtual - * machine, or {@code Long.MAX_VALUE} if there is no such limit. - * - * @return the maximum amount of memory that the virtual machine will try to - * allocate, measured in bytes. - */ - public native long maxMemory(); - -} - -/* - * Internal helper class for creating a localized InputStream. A reader - * wrapped in an InputStream. - */ -class ReaderInputStream extends InputStream { - - private Reader reader; - - private Writer writer; - - ByteArrayOutputStream out = new ByteArrayOutputStream(256); - - private byte[] bytes; - - private int nextByte; - - private int numBytes; - - String encoding = System.getProperty("file.encoding", "UTF-8"); - - public ReaderInputStream(InputStream stream) { - try { - reader = new InputStreamReader(stream, "UTF-8"); - writer = new OutputStreamWriter(out, encoding); - } catch (UnsupportedEncodingException e) { - // Should never happen, since UTF-8 and platform encoding must be - // supported. - throw new RuntimeException(e); - } - } - - @Override - public int read() throws IOException { - if (nextByte >= numBytes) { - readBuffer(); - } - - return (numBytes < 0) ? -1 : bytes[nextByte++]; - } - - private void readBuffer() throws IOException { - char[] chars = new char[128]; - int read = reader.read(chars); - if (read < 0) { - numBytes = read; - return; - } - - writer.write(chars, 0, read); - writer.flush(); - bytes = out.toByteArray(); - numBytes = bytes.length; - nextByte = 0; - } - -} - -/* - * Internal helper class for creating a localized OutputStream. A writer - * wrapped in an OutputStream. Bytes are written to characters in big-endian - * fashion. - */ -class WriterOutputStream extends OutputStream { - - private Reader reader; - - private Writer writer; - - private PipedOutputStream out; - - private PipedInputStream pipe; - - private int numBytes; - - private String enc = System.getProperty("file.encoding", "UTF-8"); - - public WriterOutputStream(OutputStream stream) { - try { - // sink - this.writer = new OutputStreamWriter(stream, enc); - - // transcriber - out = new PipedOutputStream(); - pipe = new PipedInputStream(out); - this.reader = new InputStreamReader(pipe, "UTF-8"); - - } catch (UnsupportedEncodingException e) { - // Should never happen, since platform encoding must be supported. - throw new RuntimeException(e); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public void write(int b) throws IOException { - out.write(b); - if( ++numBytes > 256) { - flush(); - numBytes = 0; - } - } - - @Override - public void flush() throws IOException { - out.flush(); - char[] chars = new char[128]; - if (pipe.available() > 0) { - int read = reader.read(chars); - if (read > 0) { - writer.write(chars, 0, read); - } - } - writer.flush(); - } - - @Override - public void close() throws IOException { - out.close(); - flush(); - writer.close(); - } -} diff --git a/luni-kernel/src/main/java/java/lang/StackTraceElement.java b/luni-kernel/src/main/java/java/lang/StackTraceElement.java deleted file mode 100644 index 88fe1ab..0000000 --- a/luni-kernel/src/main/java/java/lang/StackTraceElement.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang; - -import java.io.Serializable; - -/** - * A representation of a single stack frame. Arrays of {@code StackTraceElement} - * are stored in {@link Throwable} objects to represent the whole state of the - * call stack at the time a {@code Throwable} gets thrown. - * - * @see Throwable#getStackTrace() - */ -public final class StackTraceElement implements Serializable { - - private static final long serialVersionUID = 6992337162326171013L; - - // BEGIN android-added - private static final int NATIVE_LINE_NUMBER = -2; - // END android-added - - String declaringClass; - - String methodName; - - String fileName; - - int lineNumber; - - /** - * Constructs a new {@code StackTraceElement} for a specified execution - * point. - * - * @param cls - * the fully qualified name of the class where execution is at. - * @param method - * the name of the method where execution is at. - * @param file - * The name of the file where execution is at or {@code null}. - * @param line - * the line of the file where execution is at, a negative number - * if unknown or {@code -2} if the execution is in a native - * method. - * @throws NullPointerException - * if {@code cls} or {@code method} is {@code null}. - */ - public StackTraceElement(String cls, String method, String file, int line) { - super(); - if (cls == null || method == null) { - throw new NullPointerException(); - } - declaringClass = cls; - methodName = method; - fileName = file; - lineNumber = line; - } - - /** - * <p> - * Private, nullary constructor for VM use only. - * </p> - */ - private StackTraceElement() { - super(); - } - - /** - * Compares this instance with the specified object and indicates if they - * are equal. In order to be equal, the following conditions must be - * fulfilled: - * <ul> - * <li>{@code obj} must be a stack trace element,</li> - * <li>the method names of this stack trace element and of {@code obj} must - * not be {@code null},</li> - * <li>the class, method and file names as well as the line number of this - * stack trace element and of {@code obj} must be equal.</li> - * </ul> - * - * @param obj - * the object to compare this instance with. - * @return {@code true} if the specified object is equal to this - * {@code StackTraceElement}; {@code false} otherwise. - * @see #hashCode - */ - @Override - public boolean equals(Object obj) { - if (!(obj instanceof StackTraceElement)) { - return false; - } - StackTraceElement castObj = (StackTraceElement) obj; - - /* - * Unknown methods are never equal to anything (not strictly to spec, - * but spec does not allow null method/class names) - */ - if ((methodName == null) || (castObj.methodName == null)) { - return false; - } - - if (!getMethodName().equals(castObj.getMethodName())) { - return false; - } - if (!getClassName().equals(castObj.getClassName())) { - return false; - } - String localFileName = getFileName(); - if (localFileName == null) { - if (castObj.getFileName() != null) { - return false; - } - } else { - if (!localFileName.equals(castObj.getFileName())) { - return false; - } - } - if (getLineNumber() != castObj.getLineNumber()) { - return false; - } - - return true; - } - - /** - * Returns the fully qualified name of the class belonging to this - * {@code StackTraceElement}. - * - * @return the fully qualified type name of the class - */ - public String getClassName() { - return (declaringClass == null) ? "<unknown class>" : declaringClass; - } - - /** - * Returns the name of the Java source file containing class belonging to - * this {@code StackTraceElement}. - * - * @return the name of the file, or {@code null} if this information is not - * available. - */ - public String getFileName() { - return fileName; - } - - /** - * Returns the line number in the source for the class belonging to this - * {@code StackTraceElement}. - * - * @return the line number, or a negative number if this information is not - * available. - */ - public int getLineNumber() { - return lineNumber; - } - - /** - * Returns the name of the method belonging to this {@code - * StackTraceElement}. - * - * @return the name of the method, or "<unknown method>" if this information - * is not available. - */ - public String getMethodName() { - return (methodName == null) ? "<unknown method>" : methodName; - } - - @Override - public int hashCode() { - /* - * Either both methodName and declaringClass are null, or neither are - * null. - */ - if (methodName == null) { - // all unknown methods hash the same - return 0; - } - // declaringClass never null if methodName is non-null - return methodName.hashCode() ^ declaringClass.hashCode(); - } - - /** - * Indicates if the method name returned by {@link #getMethodName()} is - * implemented as a native method. - * - * @return {@code true} if the method in which this stack trace element is - * executing is a native method; {@code false} otherwise. - */ - public boolean isNativeMethod() { - // BEGIN android-changed - return lineNumber == NATIVE_LINE_NUMBER; - // END android-changed - } - - @Override - public String toString() { - StringBuilder buf = new StringBuilder(80); - - buf.append(getClassName()); - buf.append('.'); - buf.append(getMethodName()); - - if (isNativeMethod()) { - buf.append("(Native Method)"); - } else { - String fName = getFileName(); - - if (fName == null) { - buf.append("(Unknown Source)"); - } else { - int lineNum = getLineNumber(); - - buf.append('('); - buf.append(fName); - if (lineNum >= 0) { - buf.append(':'); - buf.append(lineNum); - } - buf.append(')'); - } - } - return buf.toString(); - } -} diff --git a/luni-kernel/src/main/java/java/lang/System.java b/luni-kernel/src/main/java/java/lang/System.java deleted file mode 100644 index 095307a..0000000 --- a/luni-kernel/src/main/java/java/lang/System.java +++ /dev/null @@ -1,713 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang; - -import java.io.Console; -import java.io.FileDescriptor; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintStream; -import java.nio.channels.Channel; -import java.nio.channels.spi.SelectorProvider; -import java.security.SecurityPermission; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; -import java.util.PropertyPermission; -import java.util.Set; - -import dalvik.system.VMStack; - -/** - * Provides access to system-related information and resources including - * standard input and output. Enables clients to dynamically load native - * libraries. All methods of this class are accessed in a static way and the - * class itself can not be instantiated. - * - * @see Runtime - */ -public final class System { - - /** - * Default input stream. - */ - public static final InputStream in; - - /** - * Default output stream. - */ - public static final PrintStream out; - - /** - * Default error output stream. - */ - public static final PrintStream err; - - /** - * The System Properties table. - */ - private static Properties systemProperties; - - /** - * Initialize all the slots in System on first use. - */ - static { - /* - * Set up standard in, out, and err. TODO err and out are - * String.ConsolePrintStream. All three are buffered in Harmony. Check - * and possibly change this later. - */ - err = new PrintStream(new FileOutputStream(FileDescriptor.err)); - out = new PrintStream(new FileOutputStream(FileDescriptor.out)); - in = new FileInputStream(FileDescriptor.in); - } - - /** - * Sets the standard input stream to the given user defined input stream. - * - * @param newIn - * the user defined input stream to set as the standard input - * stream. - * @throws SecurityException - * if a {@link SecurityManager} is installed and its {@code - * checkPermission()} method does not allow the change of the - * stream. - */ - public static void setIn(InputStream newIn) { - SecurityManager secMgr = System.getSecurityManager(); - if(secMgr != null) { - secMgr.checkPermission(RuntimePermission.permissionToSetIO); - } - setFieldImpl("in", "Ljava/io/InputStream;", newIn); - } - - /** - * Sets the standard output stream to the given user defined output stream. - * - * @param newOut - * the user defined output stream to set as the standard output - * stream. - * @throws SecurityException - * if a {@link SecurityManager} is installed and its {@code - * checkPermission()} method does not allow the change of the - * stream. - */ - public static void setOut(java.io.PrintStream newOut) { - SecurityManager secMgr = System.getSecurityManager(); - if(secMgr != null) { - secMgr.checkPermission(RuntimePermission.permissionToSetIO); - } - setFieldImpl("out", "Ljava/io/PrintStream;", newOut); - } - - /** - * Sets the standard error output stream to the given user defined output - * stream. - * - * @param newErr - * the user defined output stream to set as the standard error - * output stream. - * @throws SecurityException - * if a {@link SecurityManager} is installed and its {@code - * checkPermission()} method does not allow the change of the - * stream. - */ - public static void setErr(java.io.PrintStream newErr) { - SecurityManager secMgr = System.getSecurityManager(); - if(secMgr != null) { - secMgr.checkPermission(RuntimePermission.permissionToSetIO); - } - setFieldImpl("err", "Ljava/io/PrintStream;", newErr); - } - - /** - * Prevents this class from being instantiated. - */ - private System() { - } - - /** - * Copies the number of {@code length} elements of the Array {@code src} - * starting at the offset {@code srcPos} into the Array {@code dest} at - * the position {@code destPos}. - * - * @param src - * the source array to copy the content. - * @param srcPos - * the starting index of the content in {@code src}. - * @param dest - * the destination array to copy the data into. - * @param destPos - * the starting index for the copied content in {@code dest}. - * @param length - * the number of elements of the {@code array1} content they have - * to be copied. - */ - public static native void arraycopy(Object src, int srcPos, Object dest, - int destPos, int length); - - /** - * Returns the current system time in milliseconds since January 1, 1970 - * 00:00:00 UTC. This method shouldn't be used for measuring timeouts or - * other elapsed time measurements, as changing the system time can affect - * the results. - * - * @return the local system time in milliseconds. - */ - public static native long currentTimeMillis(); - - /** - * Returns the current timestamp of the most precise timer available on the - * local system. This timestamp can only be used to measure an elapsed - * period by comparing it against another timestamp. It cannot be used as a - * very exact system time expression. - * - * @return the current timestamp in nanoseconds. - */ - public static native long nanoTime(); - - /** - * Causes the virtual machine to stop running and the program to exit. If - * {@link #runFinalizersOnExit(boolean)} has been previously invoked with a - * {@code true} argument, then all objects will be properly - * garbage-collected and finalized first. - * - * @param code - * the return code. - * @throws SecurityException - * if the running thread has not enough permission to exit the - * virtual machine. - * @see SecurityManager#checkExit - */ - public static void exit(int code) { - Runtime.getRuntime().exit(code); - } - - /** - * Indicates to the virtual machine that it would be a good time to run the - * garbage collector. Note that this is a hint only. There is no guarantee - * that the garbage collector will actually be run. - */ - public static void gc() { - Runtime.getRuntime().gc(); - } - - /** - * Returns the value of the environment variable with the given name {@code - * var}. - * - * @param name - * the name of the environment variable. - * @return the value of the specified environment variable or {@code null} - * if no variable exists with the given name. - * @throws SecurityException - * if a {@link SecurityManager} is installed and its {@code - * checkPermission()} method does not allow the querying of - * single environment variables. - */ - public static String getenv(String name) { - if (name == null) { - throw new NullPointerException(); - } - SecurityManager secMgr = System.getSecurityManager(); - if (secMgr != null) { - secMgr.checkPermission(new RuntimePermission("getenv." + name)); - } - - return getEnvByName(name); - } - - /* - * Returns an environment variable. No security checks are performed. - * @param var the name of the environment variable - * @return the value of the specified environment variable - */ - private static native String getEnvByName(String name); - - /** - * Returns an unmodifiable map of all available environment variables. - * - * @return the map representing all environment variables. - * @throws SecurityException - * if a {@link SecurityManager} is installed and its {@code - * checkPermission()} method does not allow the querying of - * all environment variables. - */ - public static Map<String, String> getenv() { - SecurityManager secMgr = System.getSecurityManager(); - if (secMgr != null) { - secMgr.checkPermission(new RuntimePermission("getenv.*")); - } - - Map<String, String> map = new HashMap<String, String>(); - - int index = 0; - String entry = getEnvByIndex(index++); - while (entry != null) { - int pos = entry.indexOf('='); - if (pos != -1) { - map.put(entry.substring(0, pos), entry.substring(pos + 1)); - } - - entry = getEnvByIndex(index++); - } - - return new SystemEnvironment(map); - } - - /* - * Returns an environment variable. No security checks are performed. The - * safe way of traversing the environment is to start at index zero and - * count upwards until a null pointer is encountered. This marks the end of - * the Unix environment. - * @param index the index of the environment variable - * @return the value of the specified environment variable - */ - private static native String getEnvByIndex(int index); - - /** - * Returns the inherited channel from the creator of the current virtual - * machine. - * - * @return the inherited {@link Channel} or {@code null} if none exists. - * @throws IOException - * if an I/O error occurred. - * @see SelectorProvider - * @see SelectorProvider#inheritedChannel() - */ - public static Channel inheritedChannel() throws IOException { - return SelectorProvider.provider().inheritedChannel(); - } - - /** - * Returns the system properties. Note that this is not a copy, so that - * changes made to the returned Properties object will be reflected in - * subsequent calls to getProperty and getProperties. - * - * @return the system properties. - * @throws SecurityException - * if a {@link SecurityManager} is installed and its {@code - * checkPropertiesAccess()} method does not allow the operation. - */ - public static Properties getProperties() { - SecurityManager secMgr = System.getSecurityManager(); - if (secMgr != null) { - secMgr.checkPropertiesAccess(); - } - - return internalGetProperties(); - } - - /** - * Returns the system properties without any security checks. This is used - * for access from within java.lang. - * - * @return the system properties - */ - static Properties internalGetProperties() { - if (System.systemProperties == null) { - SystemProperties props = new SystemProperties(); - props.preInit(); - props.postInit(); - System.systemProperties = props; - } - - return systemProperties; - } - - /** - * Returns the value of a particular system property or {@code null} if no - * such property exists. - * <p> - * The properties currently provided by the virtual machine are: - * - * <pre> - * java.vendor.url - * java.class.path - * user.home - * java.class.version - * os.version - * java.vendor - * user.dir - * user.timezone - * path.separator - * os.name - * os.arch - * line.separator - * file.separator - * user.name - * java.version - * java.home - * </pre> - * - * @param prop - * the name of the system property to look up. - * @return the value of the specified system property or {@code null} if the - * property doesn't exist. - * @throws SecurityException - * if a {@link SecurityManager} is installed and its {@code - * checkPropertyAccess()} method does not allow the operation. - */ - public static String getProperty(String prop) { - return getProperty(prop, null); - } - - /** - * Returns the value of a particular system property. The {@code - * defaultValue} will be returned if no such property has been found. - * - * @param prop - * the name of the system property to look up. - * @param defaultValue - * the return value if the system property with the given name - * does not exist. - * @return the value of the specified system property or the {@code - * defaultValue} if the property does not exist. - * @throws SecurityException - * if a {@link SecurityManager} is installed and its {@code - * checkPropertyAccess()} method does not allow the operation. - */ - public static String getProperty(String prop, String defaultValue) { - if (prop.length() == 0) { - throw new IllegalArgumentException(); - } - SecurityManager secMgr = System.getSecurityManager(); - if (secMgr != null) { - secMgr.checkPropertyAccess(prop); - } - - return internalGetProperties().getProperty(prop, defaultValue); - } - - /** - * Sets the value of a particular system property. - * - * @param prop - * the name of the system property to be changed. - * @param value - * the value to associate with the given property {@code prop}. - * @return the old value of the property or {@code null} if the property - * didn't exist. - * @throws SecurityException - * if a security manager exists and write access to the - * specified property is not allowed. - */ - public static String setProperty(String prop, String value) { - if (prop.length() == 0) { - throw new IllegalArgumentException(); - } - SecurityManager secMgr = System.getSecurityManager(); - if (secMgr != null) { - secMgr.checkPermission(new PropertyPermission(prop, "write")); - } - return (String)internalGetProperties().setProperty(prop, value); - } - - /** - * Removes a specific system property. - * - * @param key - * the name of the system property to be removed. - * @return the property value or {@code null} if the property didn't exist. - * @throws NullPointerException - * if the argument {@code key} is {@code null}. - * @throws IllegalArgumentException - * if the argument {@code key} is empty. - * @throws SecurityException - * if a security manager exists and write access to the - * specified property is not allowed. - */ - public static String clearProperty(String key) { - if (key == null) { - throw new NullPointerException(); - } - if (key.length() == 0) { - throw new IllegalArgumentException(); - } - - SecurityManager secMgr = System.getSecurityManager(); - if (secMgr != null) { - secMgr.checkPermission(new PropertyPermission(key, "write")); - } - return (String)internalGetProperties().remove(key); - } - - /** - * Returns the {@link java.io.Console} associated with this VM, or null. - * Not all VMs will have an associated console. A console is typically only - * available for programs run from the command line. - * @since 1.6 - * @hide - */ - public static Console console() { - return Console.getConsole(); - } - - /** - * Returns null. Android does not use {@code SecurityManager}. This method - * is only provided for source compatibility. - * - * @return null - */ - public static SecurityManager getSecurityManager() { - return null; - } - - /** - * Returns an integer hash code for the parameter. The hash code returned is - * the same one that would be returned by the method {@code - * java.lang.Object.hashCode()}, whether or not the object's class has - * overridden hashCode(). The hash code for {@code null} is {@code 0}. - * - * @param anObject - * the object to calculate the hash code. - * @return the hash code for the given object. - * @see java.lang.Object#hashCode - */ - public static native int identityHashCode(Object anObject); - - /** - * Loads the specified file as a dynamic library. - * - * @param pathName - * the path of the file to be loaded. - * @throws SecurityException - * if the library was not allowed to be loaded. - */ - public static void load(String pathName) { - SecurityManager smngr = System.getSecurityManager(); - if (smngr != null) { - smngr.checkLink(pathName); - } - Runtime.getRuntime().load(pathName, VMStack.getCallingClassLoader()); - } - - /** - * Loads and links the shared library with the given name {@code libName}. - * The file will be searched in the default directory for shared libraries - * of the local system. - * - * @param libName - * the name of the library to load. - * @throws UnsatisfiedLinkError - * if the library could not be loaded. - * @throws SecurityException - * if the library was not allowed to be loaded. - */ - public static void loadLibrary(String libName) { - SecurityManager smngr = System.getSecurityManager(); - if (smngr != null) { - smngr.checkLink(libName); - } - Runtime.getRuntime().loadLibrary(libName, VMStack.getCallingClassLoader()); - } - - /** - * Provides a hint to the virtual machine that it would be useful to attempt - * to perform any outstanding object finalization. - */ - public static void runFinalization() { - Runtime.getRuntime().runFinalization(); - } - - /** - * Ensures that, when the virtual machine is about to exit, all objects are - * finalized. Note that all finalization which occurs when the system is - * exiting is performed after all running threads have been terminated. - * - * @param flag - * the flag determines if finalization on exit is enabled. - * @deprecated this method is unsafe. - */ - @SuppressWarnings("deprecation") - @Deprecated - public static void runFinalizersOnExit(boolean flag) { - Runtime.runFinalizersOnExit(flag); - } - - /** - * Sets all system properties. - * - * @param p - * the new system property. - * @throws SecurityException - * if a {@link SecurityManager} is installed and its {@code - * checkPropertiesAccess()} method does not allow the operation. - */ - public static void setProperties(Properties p) { - SecurityManager secMgr = System.getSecurityManager(); - if (secMgr != null) { - secMgr.checkPropertiesAccess(); - } - - systemProperties = p; - } - - /** - * Throws {@code UnsupportedOperationException}. - * - * <p>Security managers do <i>not</i> provide a secure environment for - * executing untrusted code and are unsupported on Android. Untrusted code - * cannot be safely isolated within the Dalvik VM. - * - * @param sm - * the new security manager. - * @throws SecurityException - * if the security manager has already been set and if its - * checkPermission method does not allow to redefine the - * security manager. - */ - public static void setSecurityManager(SecurityManager sm) { - if (sm != null) { - throw new UnsupportedOperationException(); - } - } - - /** - * Returns the platform specific file name format for the shared library - * named by the argument. - * - * @param userLibName - * the name of the library to look up. - * @return the platform specific filename for the library. - */ - public static native String mapLibraryName(String userLibName); - - /** - * Sets the value of the named static field in the receiver to the passed in - * argument. - * - * @param fieldName - * the name of the field to set, one of in, out, or err - * @param stream - * the new value of the field - */ - private static native void setFieldImpl(String fieldName, String signature, Object stream); - -} - -/** - * Internal class holding the System properties. Needed by the Dalvik VM for the - * two native methods. Must not be a local class, since we don't have a System - * instance. - */ -class SystemProperties extends Properties { - // Dummy, just to make the compiler happy. - - native void preInit(); - - native void postInit(); -} - -/** - * Internal class holding the System environment variables. The Java spec - * mandates that this map be read-only, so we wrap our real map into this one - * and make sure no one touches the contents. We also check for null parameters - * and do some (seemingly unnecessary) type casts to fulfill the contract layed - * out in the spec. - */ -class SystemEnvironment implements Map { - - private Map<String, String> map; - - public SystemEnvironment(Map<String, String> map) { - this.map = map; - } - - public void clear() { - throw new UnsupportedOperationException("Can't modify environment"); - } - - @SuppressWarnings("cast") - public boolean containsKey(Object key) { - if (key == null) { - throw new NullPointerException(); - } - - return map.containsKey((String)key); - } - - @SuppressWarnings("cast") - public boolean containsValue(Object value) { - if (value == null) { - throw new NullPointerException(); - } - - return map.containsValue((String)value); - } - - public Set entrySet() { - return map.entrySet(); - } - - @SuppressWarnings("cast") - public String get(Object key) { - if (key == null) { - throw new NullPointerException(); - } - - return map.get((String)key); - } - - public boolean isEmpty() { - return map.isEmpty(); - } - - public Set<String> keySet() { - return map.keySet(); - } - - public String put(Object key, Object value) { - throw new UnsupportedOperationException("Can't modify environment"); - } - - public void putAll(Map map) { - throw new UnsupportedOperationException("Can't modify environment"); - } - - public String remove(Object key) { - throw new UnsupportedOperationException("Can't modify environment"); - } - - public int size() { - return map.size(); - } - - public Collection values() { - return map.values(); - } - -} diff --git a/luni-kernel/src/main/java/java/lang/Thread.java b/luni-kernel/src/main/java/java/lang/Thread.java deleted file mode 100644 index 625d718..0000000 --- a/luni-kernel/src/main/java/java/lang/Thread.java +++ /dev/null @@ -1,1488 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang; - -import dalvik.system.VMStack; - -import java.security.AccessController; -import java.util.Map; -import java.util.HashMap; - -import org.apache.harmony.security.fortress.SecurityUtils; - -/** - * A {@code Thread} is a concurrent unit of execution. It has its own call stack - * for methods being invoked, their arguments and local variables. Each virtual - * machine instance has at least one main {@code Thread} running when it is - * started; typically, there are several others for housekeeping. The - * application might decide to launch additional {@code Thread}s for specific - * purposes. - * <p> - * {@code Thread}s in the same VM interact and synchronize by the use of shared - * objects and monitors associated with these objects. Synchronized methods and - * part of the API in {@link Object} also allow {@code Thread}s to cooperate. - * <p> - * There are basically two main ways of having a {@code Thread} execute - * application code. One is providing a new class that extends {@code Thread} - * and overriding its {@link #run()} method. The other is providing a new - * {@code Thread} instance with a {@link Runnable} object during its creation. - * In both cases, the {@link #start()} method must be called to actually execute - * the new {@code Thread}. - * <p> - * Each {@code Thread} has an integer priority that basically determines the - * amount of CPU time the {@code Thread} gets. It can be set using the - * {@link #setPriority(int)} method. A {@code Thread} can also be made a daemon, - * which makes it run in the background. The latter also affects VM termination - * behavior: the VM does not terminate automatically as long as there are - * non-daemon threads running. - * - * @see java.lang.Object - * @see java.lang.ThreadGroup - * - */ -public class Thread implements Runnable { - - private static final int NANOS_PER_MILLI = 1000000; - - /** Park states */ - private static class ParkState { - /** park state indicating unparked */ - private static final int UNPARKED = 1; - - /** park state indicating preemptively unparked */ - private static final int PREEMPTIVELY_UNPARKED = 2; - - /** park state indicating parked */ - private static final int PARKED = 3; - } - - /** - * A representation of a thread's state. A given thread may only be in one - * state at a time. - */ - public enum State { - /** - * The thread has been created, but has never been started. - */ - NEW, - /** - * The thread may be run. - */ - RUNNABLE, - /** - * The thread is blocked and waiting for a lock. - */ - BLOCKED, - /** - * The thread is waiting. - */ - WAITING, - /** - * The thread is waiting for a specified amount of time. - */ - TIMED_WAITING, - /** - * The thread has been terminated. - */ - TERMINATED - } - - /** - * The maximum priority value allowed for a thread. - */ - public final static int MAX_PRIORITY = 10; - - /** - * The minimum priority value allowed for a thread. - */ - public final static int MIN_PRIORITY = 1; - - /** - * The normal (default) priority value assigned to threads. - */ - public final static int NORM_PRIORITY = 5; - - /* some of these are accessed directly by the VM; do not rename them */ - volatile VMThread vmThread; - volatile ThreadGroup group; - volatile boolean daemon; - volatile String name; - volatile int priority; - volatile long stackSize; - Runnable target; - private static int count = 0; - - /** - * Holds the thread's ID. We simply count upwards, so - * each Thread has a unique ID. - */ - private long id; - - /** - * Normal thread local values. - */ - ThreadLocal.Values localValues; - - /** - * Inheritable thread local values. - */ - ThreadLocal.Values inheritableValues; - - /** - * Holds the interrupt action for this Thread, if any. - * <p> - * This is required internally by NIO, so even if it looks like it's - * useless, don't delete it! - */ - private Runnable interruptAction; - - /** - * Holds the class loader for this Thread, in case there is one. - */ - private ClassLoader contextClassLoader; - - /** - * Holds the handler for uncaught exceptions in this Thread, - * in case there is one. - */ - private UncaughtExceptionHandler uncaughtHandler; - - /** - * Holds the default handler for uncaught exceptions, in case there is one. - */ - private static UncaughtExceptionHandler defaultUncaughtHandler; - - /** - * Reflects whether this Thread has already been started. A Thread - * can only be started once (no recycling). Also, we need it to deduce - * the proper Thread status. - */ - boolean hasBeenStarted = false; - - /** the park state of the thread */ - private int parkState = ParkState.UNPARKED; - - /** The synchronization object responsible for this thread parking. */ - private Object parkBlocker; - - /** - * Constructs a new {@code Thread} with no {@code Runnable} object and a - * newly generated name. The new {@code Thread} will belong to the same - * {@code ThreadGroup} as the {@code Thread} calling this constructor. - * - * @see java.lang.ThreadGroup - * @see java.lang.Runnable - */ - public Thread() { - create(null, null, null, 0); - } - - /** - * Constructs a new {@code Thread} with a {@code Runnable} object and a - * newly generated name. The new {@code Thread} will belong to the same - * {@code ThreadGroup} as the {@code Thread} calling this constructor. - * - * @param runnable - * a {@code Runnable} whose method <code>run</code> will be - * executed by the new {@code Thread} - * - * @see java.lang.ThreadGroup - * @see java.lang.Runnable - */ - public Thread(Runnable runnable) { - create(null, runnable, null, 0); - } - - /** - * Constructs a new {@code Thread} with a {@code Runnable} object and name - * provided. The new {@code Thread} will belong to the same {@code - * ThreadGroup} as the {@code Thread} calling this constructor. - * - * @param runnable - * a {@code Runnable} whose method <code>run</code> will be - * executed by the new {@code Thread} - * @param threadName - * the name for the {@code Thread} being created - * - * @see java.lang.ThreadGroup - * @see java.lang.Runnable - */ - public Thread(Runnable runnable, String threadName) { - if (threadName == null) { - throw new NullPointerException(); - } - - create(null, runnable, threadName, 0); - } - - /** - * Constructs a new {@code Thread} with no {@code Runnable} object and the - * name provided. The new {@code Thread} will belong to the same {@code - * ThreadGroup} as the {@code Thread} calling this constructor. - * - * @param threadName - * the name for the {@code Thread} being created - * - * @see java.lang.ThreadGroup - * @see java.lang.Runnable - * - */ - public Thread(String threadName) { - if (threadName == null) { - throw new NullPointerException(); - } - - create(null, null, threadName, 0); - } - - /** - * Constructs a new {@code Thread} with a {@code Runnable} object and a - * newly generated name. The new {@code Thread} will belong to the {@code - * ThreadGroup} passed as parameter. - * - * @param group - * {@code ThreadGroup} to which the new {@code Thread} will - * belong - * @param runnable - * a {@code Runnable} whose method <code>run</code> will be - * executed by the new {@code Thread} - * @throws SecurityException - * if <code>group.checkAccess()</code> fails with a - * SecurityException - * @throws IllegalThreadStateException - * if <code>group.destroy()</code> has already been done - * @see java.lang.ThreadGroup - * @see java.lang.Runnable - * @see java.lang.SecurityException - * @see java.lang.SecurityManager - */ - public Thread(ThreadGroup group, Runnable runnable) { - create(group, runnable, null, 0); - } - - /** - * Constructs a new {@code Thread} with a {@code Runnable} object, the given - * name and belonging to the {@code ThreadGroup} passed as parameter. - * - * @param group - * ThreadGroup to which the new {@code Thread} will belong - * @param runnable - * a {@code Runnable} whose method <code>run</code> will be - * executed by the new {@code Thread} - * @param threadName - * the name for the {@code Thread} being created - * @throws SecurityException - * if <code>group.checkAccess()</code> fails with a - * SecurityException - * @throws IllegalThreadStateException - * if <code>group.destroy()</code> has already been done - * @see java.lang.ThreadGroup - * @see java.lang.Runnable - * @see java.lang.SecurityException - * @see java.lang.SecurityManager - */ - public Thread(ThreadGroup group, Runnable runnable, String threadName) { - if (threadName == null) { - throw new NullPointerException(); - } - - create(group, runnable, threadName, 0); - } - - /** - * Constructs a new {@code Thread} with no {@code Runnable} object, the - * given name and belonging to the {@code ThreadGroup} passed as parameter. - * - * @param group - * {@code ThreadGroup} to which the new {@code Thread} will belong - * @param threadName - * the name for the {@code Thread} being created - * @throws SecurityException - * if <code>group.checkAccess()</code> fails with a - * SecurityException - * @throws IllegalThreadStateException - * if <code>group.destroy()</code> has already been done - * @see java.lang.ThreadGroup - * @see java.lang.Runnable - * @see java.lang.SecurityException - * @see java.lang.SecurityManager - */ - public Thread(ThreadGroup group, String threadName) { - if (threadName == null) { - throw new NullPointerException(); - } - - create(group, null, threadName, 0); - } - - /** - * Constructs a new {@code Thread} with a {@code Runnable} object, the given - * name and belonging to the {@code ThreadGroup} passed as parameter. - * - * @param group - * {@code ThreadGroup} to which the new {@code Thread} will - * belong - * @param runnable - * a {@code Runnable} whose method <code>run</code> will be - * executed by the new {@code Thread} - * @param threadName - * the name for the {@code Thread} being created - * @param stackSize - * a stack size for the new {@code Thread}. This has a highly - * platform-dependent interpretation. It may even be ignored - * completely. - * @throws SecurityException - * if <code>group.checkAccess()</code> fails with a - * SecurityException - * @throws IllegalThreadStateException - * if <code>group.destroy()</code> has already been done - * @see java.lang.ThreadGroup - * @see java.lang.Runnable - * @see java.lang.SecurityException - * @see java.lang.SecurityManager - */ - public Thread(ThreadGroup group, Runnable runnable, String threadName, long stackSize) { - if (threadName == null) { - throw new NullPointerException(); - } - create(group, runnable, threadName, stackSize); - } - - /** - * Package-scope method invoked by Dalvik VM to create "internal" - * threads or attach threads created externally. - * - * Don't call Thread.currentThread(), since there may not be such - * a thing (e.g. for Main). - */ - Thread(ThreadGroup group, String name, int priority, boolean daemon) { - synchronized (Thread.class) { - id = ++Thread.count; - } - - if (name == null) { - this.name = "Thread-" + id; - } else - this.name = name; - - if (group == null) { - throw new InternalError("group not specified"); - } - - this.group = group; - - this.target = null; - this.stackSize = 0; - this.priority = priority; - this.daemon = daemon; - - /* add ourselves to our ThreadGroup of choice */ - this.group.addThread(this); - } - - /** - * Initializes a new, existing Thread object with a runnable object, - * the given name and belonging to the ThreadGroup passed as parameter. - * This is the method that the several public constructors delegate their - * work to. - * - * @param group ThreadGroup to which the new Thread will belong - * @param runnable a java.lang.Runnable whose method <code>run</code> will - * be executed by the new Thread - * @param threadName Name for the Thread being created - * @param stackSize Platform dependent stack size - * @throws SecurityException if <code>group.checkAccess()</code> fails - * with a SecurityException - * @throws IllegalThreadStateException if <code>group.destroy()</code> has - * already been done - * @see java.lang.ThreadGroup - * @see java.lang.Runnable - * @see java.lang.SecurityException - * @see java.lang.SecurityManager - */ - private void create(ThreadGroup group, Runnable runnable, String threadName, long stackSize) { - SecurityManager smgr = System.getSecurityManager(); - if (smgr != null) { - if (group == null) { - group = smgr.getThreadGroup(); - } - - /* - * Freaky security requirement: If the Thread's class is actually - * a subclass of Thread and it tries to override either - * getContextClassLoader() or setContextClassLoader(), the - * SecurityManager has to allow this. - */ - if (getClass() != Thread.class) { - Class[] signature = new Class[] { ClassLoader.class }; - - try { - getClass().getDeclaredMethod("getContextClassLoader", signature); - smgr.checkPermission(new RuntimePermission("enableContextClassLoaderOverride")); - } catch (NoSuchMethodException ex) { - // Ignore. Just interested in the method's existence. - } - - try { - getClass().getDeclaredMethod("setContextClassLoader", signature); - smgr.checkPermission(new RuntimePermission("enableContextClassLoaderOverride")); - } catch (NoSuchMethodException ex) { - // Ignore. Just interested in the method's existence. - } - } - } - - Thread currentThread = Thread.currentThread(); - if (group == null) { - group = currentThread.getThreadGroup(); - } - - group.checkAccess(); - if (group.isDestroyed()) { - throw new IllegalThreadStateException("Group already destroyed"); - } - - this.group = group; - - synchronized (Thread.class) { - id = ++Thread.count; - } - - if (threadName == null) { - this.name = "Thread-" + id; - } else { - this.name = threadName; - } - - this.target = runnable; - this.stackSize = stackSize; - - this.priority = currentThread.getPriority(); - - this.contextClassLoader = currentThread.contextClassLoader; - - // Transfer over InheritableThreadLocals. - if (currentThread.inheritableValues != null) { - inheritableValues - = new ThreadLocal.Values(currentThread.inheritableValues); - } - - // store current AccessControlContext as inherited context for this thread - SecurityUtils.putContext(this, AccessController.getContext()); - - // add ourselves to our ThreadGroup of choice - this.group.addThread(this); - } - - /** - * Returns the number of active {@code Thread}s in the running {@code - * Thread}'s group and its subgroups. - * - * @return the number of {@code Thread}s - */ - public static int activeCount() { - return currentThread().getThreadGroup().activeCount(); - } - - /** - * Is used for operations that require approval from a SecurityManager. If - * there's none installed, this method is a no-op. If there's a - * SecurityManager installed, {@link SecurityManager#checkAccess(Thread)} is - * called for that SecurityManager. - * - * @throws SecurityException - * if a SecurityManager is installed and it does not allow - * access to the Thread. - * - * @see java.lang.SecurityException - * @see java.lang.SecurityManager - */ - public final void checkAccess() { - // Forwards the message to the SecurityManager (if there's one) passing - // the receiver as parameter - - SecurityManager currentManager = System.getSecurityManager(); - if (currentManager != null) { - currentManager.checkAccess(this); - } - } - - /** - * Returns the number of stack frames in this thread. - * - * @return Number of stack frames - * @deprecated The results of this call were never well defined. To make - * things worse, it would depend on whether the Thread was - * suspended or not, and suspend was deprecated too. - */ - @Deprecated - public int countStackFrames() { - return getStackTrace().length; - } - - /** - * Returns the Thread of the caller, that is, the current Thread. - * - * @return the current Thread. - */ - public static Thread currentThread() { - return VMThread.currentThread(); - } - - /** - * Destroys the receiver without any monitor cleanup. - * - * @deprecated Not implemented. - */ - @Deprecated - public void destroy() { - throw new NoSuchMethodError("Thread.destroy()"); // TODO Externalize??? - } - - /** - * Prints to the standard error stream a text representation of the current - * stack for this Thread. - * - * @see Throwable#printStackTrace() - */ - public static void dumpStack() { - new Throwable("stack dump").printStackTrace(); - } - - /** - * Copies an array with all Threads which are in the same ThreadGroup as the - * receiver - and subgroups - into the array <code>threads</code> passed as - * parameter. If the array passed as parameter is too small no exception is - * thrown - the extra elements are simply not copied. - * - * @param threads - * array into which the Threads will be copied - * @return How many Threads were copied over - * @throws SecurityException - * if the installed SecurityManager fails - * {@link SecurityManager#checkAccess(Thread)} - * @see java.lang.SecurityException - * @see java.lang.SecurityManager - */ - public static int enumerate(Thread[] threads) { - Thread thread = Thread.currentThread(); - thread.checkAccess(); - return thread.getThreadGroup().enumerate(threads); - } - - /** - * <p> - * Returns the stack traces of all the currently live threads and puts them - * into the given map. - * </p> - * - * @return A Map of current Threads to StackTraceElement arrays. - * @throws SecurityException - * if the current SecurityManager fails the - * {@link SecurityManager#checkPermission(java.security.Permission)} - * call. - */ - public static Map<Thread, StackTraceElement[]> getAllStackTraces() { - SecurityManager securityManager = System.getSecurityManager(); - if (securityManager != null) { - securityManager.checkPermission(new RuntimePermission("getStackTrace")); - securityManager.checkPermission(new RuntimePermission("modifyThreadGroup")); - } - - Map<Thread, StackTraceElement[]> map = new HashMap<Thread, StackTraceElement[]>(); - - // Find out how many live threads we have. Allocate a bit more - // space than needed, in case new ones are just being created. - int count = ThreadGroup.mSystem.activeCount(); - Thread[] threads = new Thread[count + count / 2]; - - // Enumerate the threads and collect the stacktraces. - count = ThreadGroup.mSystem.enumerate(threads); - for (int i = 0; i < count; i++) { - map.put(threads[i], threads[i].getStackTrace()); - } - - return map; - } - - /** - * Returns the context ClassLoader for this Thread. - * <p> - * If the conditions - * <ol> - * <li>there is a security manager - * <li>the caller's class loader is not null - * <li>the caller's class loader is not the same as the requested - * context class loader and not an ancestor thereof - * </ol> - * are satisfied, a security check for - * <code>RuntimePermission("getClassLoader")</code> is performed first. - * - * @return ClassLoader The context ClassLoader - * @see java.lang.ClassLoader - * @see #getContextClassLoader() - * - * @throws SecurityException - * if the aforementioned security check fails. - */ - public ClassLoader getContextClassLoader() { - // First, if the conditions - // 1) there is a security manager - // 2) the caller's class loader is not null - // 3) the caller's class loader is not the same as the context - // class loader and not an ancestor thereof - // are satisfied we should perform a security check. - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - ClassLoader calling = VMStack.getCallingClassLoader(); - - if (calling != null && !calling.isAncestorOf(contextClassLoader)) { - sm.checkPermission(new RuntimePermission("getClassLoader")); - } - } - - return contextClassLoader; - } - - /** - * Returns the default exception handler that's executed when uncaught - * exception terminates a thread. - * - * @return an {@link UncaughtExceptionHandler} or <code>null</code> if - * none exists. - */ - public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() { - return defaultUncaughtHandler; - } - - /** - * Returns the thread's identifier. The ID is a positive <code>long</code> - * generated on thread creation, is unique to the thread, and doesn't change - * during the lifetime of the thread; the ID may be reused after the thread - * has been terminated. - * - * @return the thread's ID. - */ - public long getId() { - return id; - } - - /** - * Returns the name of the Thread. - * - * @return the Thread's name - */ - public final String getName() { - return name; - } - - /** - * Returns the priority of the Thread. - * - * @return the Thread's priority - * @see Thread#setPriority - */ - public final int getPriority() { - return priority; - } - - /** - * Returns the a stack trace representing the current execution state of - * this Thread. - * <p> - * The <code>RuntimePermission("getStackTrace")</code> is checked before - * returning a result. - * </p> - * - * @return an array of StackTraceElements. - * @throws SecurityException - * if the current SecurityManager fails the - * {@link SecurityManager#checkPermission(java.security.Permission)} - * call. - */ - public StackTraceElement[] getStackTrace() { - SecurityManager securityManager = System.getSecurityManager(); - if (securityManager != null) { - securityManager.checkPermission(new RuntimePermission("getStackTrace")); - } - - StackTraceElement ste[] = VMStack.getThreadStackTrace(this); - return ste != null ? ste : new StackTraceElement[0]; - } - - /** - * Returns the current state of the Thread. This method is useful for - * monitoring purposes. - * - * @return a {@link State} value. - */ - public State getState() { - // TODO This is ugly and should be implemented better. - VMThread vmt = this.vmThread; - - // Make sure we have a valid reference to an object. If native code - // deletes the reference we won't run into a null reference later. - VMThread thread = vmThread; - if (thread != null) { - // If the Thread Object became invalid or was not yet started, - // getStatus() will return -1. - int state = thread.getStatus(); - if(state != -1) { - return VMThread.STATE_MAP[state]; - } - } - return hasBeenStarted ? Thread.State.TERMINATED : Thread.State.NEW; - } - - /** - * Returns the ThreadGroup to which this Thread belongs. - * - * @return the Thread's ThreadGroup - */ - public final ThreadGroup getThreadGroup() { - // TODO This should actually be done at native termination. - if (getState() == Thread.State.TERMINATED) { - return null; - } else { - return group; - } - } - - /** - * Returns the thread's uncaught exception handler. If not explicitly set, - * then the ThreadGroup's handler is returned. If the thread is terminated, - * then <code>null</code> is returned. - * - * @return an {@link UncaughtExceptionHandler} instance or {@code null}. - */ - public UncaughtExceptionHandler getUncaughtExceptionHandler() { - if (uncaughtHandler != null) - return uncaughtHandler; - else - return group; // ThreadGroup is instance of UEH - } - - /** - * Posts an interrupt request to this {@code Thread}. Unless the caller is - * the {@link #currentThread()}, the method {@code checkAccess()} is called - * for the installed {@code SecurityManager}, if any. This may result in a - * {@code SecurityException} being thrown. The further behavior depends on - * the state of this {@code Thread}: - * <ul> - * <li> - * {@code Thread}s blocked in one of {@code Object}'s {@code wait()} methods - * or one of {@code Thread}'s {@code join()} or {@code sleep()} methods will - * be woken up, their interrupt status will be cleared, and they receive an - * {@link InterruptedException}. - * <li> - * {@code Thread}s blocked in an I/O operation of an - * {@link java.nio.channels.InterruptibleChannel} will have their interrupt - * status set and receive an - * {@link java.nio.channels.ClosedByInterruptException}. Also, the channel - * will be closed. - * <li> - * {@code Thread}s blocked in a {@link java.nio.channels.Selector} will have - * their interrupt status set and return immediately. They don't receive an - * exception in this case. - * <ul> - * - * @throws SecurityException - * if <code>checkAccess()</code> fails with a SecurityException - * @see java.lang.SecurityException - * @see java.lang.SecurityManager - * @see Thread#interrupted - * @see Thread#isInterrupted - */ - public void interrupt() { - checkAccess(); - - if (interruptAction != null) { - interruptAction.run(); - } - - VMThread vmt = this.vmThread; - if (vmt != null) { - vmt.interrupt(); - } - } - - /** - * Returns a <code>boolean</code> indicating whether the current Thread ( - * <code>currentThread()</code>) has a pending interrupt request (<code> - * true</code>) or not (<code>false</code>). It also has the side-effect of - * clearing the flag. - * - * @return a <code>boolean</code> indicating the interrupt status - * @see Thread#currentThread - * @see Thread#interrupt - * @see Thread#isInterrupted - */ - public static boolean interrupted() { - return VMThread.interrupted(); - } - - /** - * Returns <code>true</code> if the receiver has already been started and - * still runs code (hasn't died yet). Returns <code>false</code> either if - * the receiver hasn't been started yet or if it has already started and run - * to completion and died. - * - * @return a <code>boolean</code> indicating the liveness of the Thread - * @see Thread#start - */ - public final boolean isAlive() { - return (vmThread != null); - } - - /** - * Returns a <code>boolean</code> indicating whether the receiver is a - * daemon Thread (<code>true</code>) or not (<code>false</code>) A - * daemon Thread only runs as long as there are non-daemon Threads running. - * When the last non-daemon Thread ends, the whole program ends no matter if - * it had daemon Threads still running or not. - * - * @return a <code>boolean</code> indicating whether the Thread is a daemon - * @see Thread#setDaemon - */ - public final boolean isDaemon() { - return daemon; - } - - /** - * Returns a <code>boolean</code> indicating whether the receiver has a - * pending interrupt request (<code>true</code>) or not ( - * <code>false</code>) - * - * @return a <code>boolean</code> indicating the interrupt status - * @see Thread#interrupt - * @see Thread#interrupted - */ - public boolean isInterrupted() { - VMThread vmt = this.vmThread; - if (vmt != null) { - return vmt.isInterrupted(); - } - - return false; - } - - /** - * Blocks the current Thread (<code>Thread.currentThread()</code>) until - * the receiver finishes its execution and dies. - * - * @throws InterruptedException if <code>interrupt()</code> was called for - * the receiver while it was in the <code>join()</code> call - * @see Object#notifyAll - * @see java.lang.ThreadDeath - */ - public final void join() throws InterruptedException { - VMThread t = vmThread; - if (t == null) { - return; - } - - synchronized (t) { - while (isAlive()) { - t.wait(); - } - } - } - - /** - * Blocks the current Thread (<code>Thread.currentThread()</code>) until - * the receiver finishes its execution and dies or the specified timeout - * expires, whatever happens first. - * - * @param millis The maximum time to wait (in milliseconds). - * @throws InterruptedException if <code>interrupt()</code> was called for - * the receiver while it was in the <code>join()</code> call - * @see Object#notifyAll - * @see java.lang.ThreadDeath - */ - public final void join(long millis) throws InterruptedException { - join(millis, 0); - } - - /** - * Blocks the current Thread (<code>Thread.currentThread()</code>) until - * the receiver finishes its execution and dies or the specified timeout - * expires, whatever happens first. - * - * @param millis The maximum time to wait (in milliseconds). - * @param nanos Extra nanosecond precision - * @throws InterruptedException if <code>interrupt()</code> was called for - * the receiver while it was in the <code>join()</code> call - * @see Object#notifyAll - * @see java.lang.ThreadDeath - */ - public final void join(long millis, int nanos) throws InterruptedException { - if (millis < 0 || nanos < 0 || nanos >= NANOS_PER_MILLI) { - throw new IllegalArgumentException(); - } - - // avoid overflow: if total > 292,277 years, just wait forever - boolean overflow = millis >= (Long.MAX_VALUE - nanos) / NANOS_PER_MILLI; - boolean forever = (millis | nanos) == 0; - if (forever | overflow) { - join(); - return; - } - - VMThread t = vmThread; - if (t == null) { - return; - } - - synchronized (t) { - if (!isAlive()) { - return; - } - - // guaranteed not to overflow - long nanosToWait = millis * NANOS_PER_MILLI + nanos; - - // wait until this thread completes or the timeout has elapsed - long start = System.nanoTime(); - while (true) { - t.wait(millis, nanos); - if (!isAlive()) { - break; - } - long nanosElapsed = System.nanoTime() - start; - long nanosRemaining = nanosToWait - nanosElapsed; - if (nanosRemaining <= 0) { - break; - } - millis = nanosRemaining / NANOS_PER_MILLI; - nanos = (int) (nanosRemaining - millis * NANOS_PER_MILLI); - } - } - } - - /** - * Resumes a suspended Thread. This is a no-op if the receiver was never - * suspended, or suspended and already resumed. If the receiver is - * suspended, however, makes it resume to the point where it was when it was - * suspended. - * - * @throws SecurityException - * if <code>checkAccess()</code> fails with a SecurityException - * @see Thread#suspend() - * @deprecated Used with deprecated method {@link Thread#suspend} - */ - @Deprecated - public final void resume() { - checkAccess(); - - VMThread vmt = this.vmThread; - if (vmt != null) { - vmt.resume(); - } - } - - /** - * Calls the <code>run()</code> method of the Runnable object the receiver - * holds. If no Runnable is set, does nothing. - * - * @see Thread#start - */ - public void run() { - if (target != null) { - target.run(); - } - } - - /** - * Set the context ClassLoader for the receiver. - * <p> - * The <code>RuntimePermission("setContextClassLoader")</code> - * is checked prior to setting the handler. - * </p> - * - * @param cl The context ClassLoader - * @throws SecurityException if the current SecurityManager fails the - * checkPermission call. - * @see java.lang.ClassLoader - * @see #getContextClassLoader() - */ - public void setContextClassLoader(ClassLoader cl) { - SecurityManager securityManager = System.getSecurityManager(); - if (securityManager != null) { - securityManager.checkPermission(new RuntimePermission("setContextClassLoader")); - } - - contextClassLoader = cl; - } - - /** - * Set if the receiver is a daemon Thread or not. This can only be done - * before the Thread starts running. - * - * @param isDaemon - * indicates whether the Thread should be daemon or not - * @throws SecurityException - * if <code>checkAccess()</code> fails with a SecurityException - * @see Thread#isDaemon - */ - public final void setDaemon(boolean isDaemon) { - checkAccess(); - - if (hasBeenStarted) { - throw new IllegalThreadStateException("Thread already started."); // TODO Externalize? - } - - if (vmThread == null) { - daemon = isDaemon; - } - } - - /** - * <p> - * Sets the default uncaught exception handler. This handler is invoked in - * case any Thread dies due to an unhandled exception. - * </p> - * <p> - * The <code>RuntimePermission("setDefaultUncaughtExceptionHandler")</code> - * is checked prior to setting the handler. - * </p> - * - * @param handler - * The handler to set or <code>null</code>. - * @throws SecurityException - * if the current SecurityManager fails the checkPermission - * call. - */ - public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler handler) { - SecurityManager securityManager = System.getSecurityManager(); - if (securityManager != null) { - securityManager.checkPermission(new RuntimePermission ("setDefaultUncaughtExceptionHandler")); - } - - Thread.defaultUncaughtHandler = handler; - } - - /** - * Set the action to be executed when interruption, which is probably be - * used to implement the interruptible channel. The action is null by - * default. And if this method is invoked by passing in a non-null value, - * this action's run() method will be invoked in <code>interrupt()</code>. - * <p> - * This is required internally by NIO, so even if it looks like it's - * useless, don't delete it! - * - * @param action the action to be executed when interruption - */ - @SuppressWarnings("unused") - private void setInterruptAction(Runnable action) { - this.interruptAction = action; - } - - /** - * Sets the name of the Thread. - * - * @param threadName the new name for the Thread - * @throws SecurityException if <code>checkAccess()</code> fails with a - * SecurityException - * @see Thread#getName - */ - public final void setName(String threadName) { - if (threadName == null) { - throw new NullPointerException(); - } - - checkAccess(); - - name = threadName; - VMThread vmt = this.vmThread; - if (vmt != null) { - /* notify the VM that the thread name has changed */ - vmt.nameChanged(threadName); - } - } - - /** - * Sets the priority of the Thread. Note that the final priority set may not - * be the parameter that was passed - it will depend on the receiver's - * ThreadGroup. The priority cannot be set to be higher than the receiver's - * ThreadGroup's maxPriority(). - * - * @param priority - * new priority for the Thread - * @throws SecurityException - * if <code>checkAccess()</code> fails with a SecurityException - * @throws IllegalArgumentException - * if the new priority is greater than Thread.MAX_PRIORITY or - * less than Thread.MIN_PRIORITY - * @see Thread#getPriority - */ - public final void setPriority(int priority) { - checkAccess(); - - if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) { - throw new IllegalArgumentException("Priority out of range"); // TODO Externalize? - } - - if (priority > group.getMaxPriority()) { - priority = group.getMaxPriority(); - } - - this.priority = priority; - - VMThread vmt = this.vmThread; - if (vmt != null) { - vmt.setPriority(priority); - } - } - - /** - * <p> - * Sets the uncaught exception handler. This handler is invoked in case this - * Thread dies due to an unhandled exception. - * </p> - * - * @param handler - * The handler to set or <code>null</code>. - * @throws SecurityException - * if the current SecurityManager fails the checkAccess call. - */ - public void setUncaughtExceptionHandler(UncaughtExceptionHandler handler) { - checkAccess(); - - uncaughtHandler = handler; - } - - /** - * Causes the thread which sent this message to sleep for the given interval - * of time (given in milliseconds). The precision is not guaranteed - the - * Thread may sleep more or less than requested. - * - * @param time - * The time to sleep in milliseconds. - * @throws InterruptedException - * if <code>interrupt()</code> was called for this Thread while - * it was sleeping - * @see Thread#interrupt() - */ - public static void sleep(long time) throws InterruptedException { - Thread.sleep(time, 0); - } - - /** - * Causes the thread which sent this message to sleep for the given interval - * of time (given in milliseconds and nanoseconds). The precision is not - * guaranteed - the Thread may sleep more or less than requested. - * - * @param millis - * The time to sleep in milliseconds. - * @param nanos - * Extra nanosecond precision - * @throws InterruptedException - * if <code>interrupt()</code> was called for this Thread while - * it was sleeping - * @see Thread#interrupt() - */ - public static void sleep(long millis, int nanos) throws InterruptedException { - VMThread.sleep(millis, nanos); - } - - /** - * Starts the new Thread of execution. The <code>run()</code> method of - * the receiver will be called by the receiver Thread itself (and not the - * Thread calling <code>start()</code>). - * - * @throws IllegalThreadStateException if the Thread has been started before - * - * @see Thread#run - */ - public synchronized void start() { - if (hasBeenStarted) { - throw new IllegalThreadStateException("Thread already started."); // TODO Externalize? - } - - hasBeenStarted = true; - - VMThread.create(this, stackSize); - } - - /** - * Requests the receiver Thread to stop and throw ThreadDeath. The Thread is - * resumed if it was suspended and awakened if it was sleeping, so that it - * can proceed to throw ThreadDeath. - * - * @throws SecurityException if <code>checkAccess()</code> fails with a - * SecurityException - * @deprecated because stopping a thread in this manner is unsafe and can - * leave your application and the VM in an unpredictable state. - */ - @Deprecated - public final void stop() { - stop(new ThreadDeath()); - } - - /** - * Requests the receiver Thread to stop and throw the - * <code>throwable()</code>. The Thread is resumed if it was suspended - * and awakened if it was sleeping, so that it can proceed to throw the - * <code>throwable()</code>. - * - * @param throwable Throwable object to be thrown by the Thread - * @throws SecurityException if <code>checkAccess()</code> fails with a - * SecurityException - * @throws NullPointerException if <code>throwable()</code> is - * <code>null</code> - * @deprecated because stopping a thread in this manner is unsafe and can - * leave your application and the VM in an unpredictable state. - */ - @Deprecated - public final synchronized void stop(Throwable throwable) { - SecurityManager securityManager = System.getSecurityManager(); - if (securityManager != null) { - securityManager.checkAccess(this); - if (Thread.currentThread() != this) { - securityManager.checkPermission(new RuntimePermission("stopThread")); - } - } - - if (throwable == null) { - throw new NullPointerException(); - } - - VMThread vmt = this.vmThread; - if (vmt != null) { - vmt.stop(throwable); - } - } - - /** - * Suspends this Thread. This is a no-op if the receiver is suspended. If - * the receiver <code>isAlive()</code> however, suspended it until <code> - * resume()</code> is sent to it. Suspend requests are not queued, which - * means that N requests are equivalent to just one - only one resume - * request is needed in this case. - * - * @throws SecurityException - * if <code>checkAccess()</code> fails with a SecurityException - * @see Thread#resume() - * @deprecated May cause deadlocks. - */ - @Deprecated - public final void suspend() { - checkAccess(); - - VMThread vmt = this.vmThread; - if (vmt != null) { - vmt.suspend(); - } - } - - /** - * Returns a string containing a concise, human-readable description of the - * Thread. It includes the Thread's name, priority, and group name. - * - * @return a printable representation for the receiver. - */ - @Override - public String toString() { - return "Thread[" + name + "," + priority + "," + group.getName() + "]"; - } - - /** - * Causes the calling Thread to yield execution time to another Thread that - * is ready to run. The actual scheduling is implementation-dependent. - */ - public static void yield() { - VMThread.yield(); - } - - /** - * Indicates whether the current Thread has a monitor lock on the specified - * object. - * - * @param object the object to test for the monitor lock - * @return true if the current thread has a monitor lock on the specified - * object; false otherwise - */ - public static boolean holdsLock(Object object) { - return currentThread().vmThread.holdsLock(object); - } - - /** - * Implemented by objects that want to handle cases where a thread is being - * terminated by an uncaught exception. Upon such termination, the handler - * is notified of the terminating thread and causal exception. If there is - * no explicit handler set then the thread's group is the default handler. - */ - public static interface UncaughtExceptionHandler { - /** - * The thread is being terminated by an uncaught exception. Further - * exceptions thrown in this method are prevent the remainder of the - * method from executing, but are otherwise ignored. - * - * @param thread the thread that has an uncaught exception - * @param ex the exception that was thrown - */ - void uncaughtException(Thread thread, Throwable ex); - } - - /** - * Implementation of <code>unpark()</code>. See {@link LangAccessImpl}. - */ - /*package*/ void unpark() { - VMThread vmt = vmThread; - - if (vmt == null) { - /* - * vmThread is null before the thread is start()ed. In - * this case, we just go ahead and set the state to - * PREEMPTIVELY_UNPARKED. Since this happens before the - * thread is started, we don't have to worry about - * synchronizing with it. - */ - parkState = ParkState.PREEMPTIVELY_UNPARKED; - return; - } - - synchronized (vmt) { - switch (parkState) { - case ParkState.PREEMPTIVELY_UNPARKED: { - /* - * Nothing to do in this case: By definition, a - * preemptively unparked thread is to remain in - * the preemptively unparked state if it is told - * to unpark. - */ - break; - } - case ParkState.UNPARKED: { - parkState = ParkState.PREEMPTIVELY_UNPARKED; - break; - } - default /*parked*/: { - parkState = ParkState.UNPARKED; - vmt.notifyAll(); - break; - } - } - } - } - - /** - * Implementation of <code>parkFor()</code>. See {@link LangAccessImpl}. - * This method must only be called when <code>this</code> is the current - * thread. - * - * @param nanos number of nanoseconds to park for - */ - /*package*/ void parkFor(long nanos) { - VMThread vmt = vmThread; - - if (vmt == null) { - // Running threads should always have an associated vmThread. - throw new AssertionError(); - } - - synchronized (vmt) { - switch (parkState) { - case ParkState.PREEMPTIVELY_UNPARKED: { - parkState = ParkState.UNPARKED; - break; - } - case ParkState.UNPARKED: { - long millis = nanos / NANOS_PER_MILLI; - nanos %= NANOS_PER_MILLI; - - parkState = ParkState.PARKED; - try { - vmt.wait(millis, (int) nanos); - } catch (InterruptedException ex) { - interrupt(); - } finally { - /* - * Note: If parkState manages to become - * PREEMPTIVELY_UNPARKED before hitting this - * code, it should left in that state. - */ - if (parkState == ParkState.PARKED) { - parkState = ParkState.UNPARKED; - } - } - break; - } - default /*parked*/: { - throw new AssertionError( - "shouldn't happen: attempt to repark"); - } - } - } - } - - /** - * Implementation of <code>parkUntil()</code>. See {@link LangAccessImpl}. - * This method must only be called when <code>this</code> is the current - * thread. - * - * @param time absolute milliseconds since the epoch to park until - */ - /*package*/ void parkUntil(long time) { - VMThread vmt = vmThread; - - if (vmt == null) { - // Running threads should always have an associated vmThread. - throw new AssertionError(); - } - - synchronized (vmt) { - /* - * Note: This conflates the two time bases of "wall clock" - * time and "monotonic uptime" time. However, given that - * the underlying system can only wait on monotonic time, - * it is unclear if there is any way to avoid the - * conflation. The downside here is that if, having - * calculated the delay, the wall clock gets moved ahead, - * this method may not return until well after the wall - * clock has reached the originally designated time. The - * reverse problem (the wall clock being turned back) - * isn't a big deal, since this method is allowed to - * spuriously return for any reason, and this situation - * can safely be construed as just such a spurious return. - */ - long delayMillis = time - System.currentTimeMillis(); - - if (delayMillis <= 0) { - parkState = ParkState.UNPARKED; - } else { - parkFor(delayMillis * NANOS_PER_MILLI); - } - } - } -} diff --git a/luni-kernel/src/main/java/java/lang/ThreadGroup.java b/luni-kernel/src/main/java/java/lang/ThreadGroup.java deleted file mode 100644 index 690fb45..0000000 --- a/luni-kernel/src/main/java/java/lang/ThreadGroup.java +++ /dev/null @@ -1,893 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang; - -/** - * {@code ThreadGroup} is a means of organizing threads into a hierarchical structure. - * This class is obsolete. See <i>Effective Java</i> Item 73, "Avoid thread groups" for details. - * @see Thread - * @see SecurityManager - */ -public class ThreadGroup implements Thread.UncaughtExceptionHandler { - - // Name of this ThreadGroup - private String name; - // BEGIN android-note - // VM needs this field name for debugging. - // END android-note - - // Maximum priority for Threads inside this ThreadGroup - private int maxPriority = Thread.MAX_PRIORITY; - - // The ThreadGroup to which this ThreadGroup belongs - ThreadGroup parent; - // BEGIN android-note - // VM needs this field name for debugging. - // END android-note - - int numThreads; - - // The Threads this ThreadGroup contains - private Thread[] childrenThreads = new Thread[5]; - - // The number of children groups - int numGroups; - - // The ThreadGroups this ThreadGroup contains - private ThreadGroup[] childrenGroups = new ThreadGroup[3]; - - // Locked when using the childrenGroups field - private class ChildrenGroupsLock {} - private Object childrenGroupsLock = new ChildrenGroupsLock(); - - // Locked when using the childrenThreads field - private class ChildrenThreadsLock {} - private Object childrenThreadsLock = new ChildrenThreadsLock(); - - // Whether this ThreadGroup is a daemon ThreadGroup or not - private boolean isDaemon; - - // Whether this ThreadGroup has already been destroyed or not - private boolean isDestroyed; - - // BEGIN android-added - /* the VM uses these directly; do not rename */ - static ThreadGroup mSystem = new ThreadGroup(); - static ThreadGroup mMain = new ThreadGroup(mSystem, "main"); - // END android-added - - // BEGIN android-removed - // /** - // * Used by the JVM to create the "system" ThreadGroup. Construct a - // * ThreadGroup instance, and assign the name "system". - // */ - // private ThreadGroup() { - // name = "system"; - // } - // END android-removed - - /** - * Constructs a new {@code ThreadGroup} with the given name. The new {@code ThreadGroup} - * will be child of the {@code ThreadGroup} to which the calling thread belongs. - * - * @param name the name - * @throws SecurityException if {@code checkAccess()} for the parent - * group fails with a SecurityException - * @see java.lang.Thread#currentThread - */ - - public ThreadGroup(String name) { - this(Thread.currentThread().getThreadGroup(), name); - } - - /** - * Constructs a new {@code ThreadGroup} with the given name, as a child of the - * given {@code ThreadGroup}. - * - * @param parent the parent - * @param name the name - * @throws NullPointerException if {@code parent == null} - * @throws SecurityException if {@code checkAccess()} for the parent - * group fails with a SecurityException - * @throws IllegalThreadStateException if {@code parent} has been - * destroyed already - */ - public ThreadGroup(ThreadGroup parent, String name) { - super(); - if (Thread.currentThread() != null) { - // If parent is null we must throw NullPointerException, but that - // will be done "for free" with the message send below - parent.checkAccess(); - } - - this.name = name; - this.setParent(parent); - if (parent != null) { - this.setMaxPriority(parent.getMaxPriority()); - if (parent.isDaemon()) { - this.setDaemon(true); - } - } - } - - /** - * Initialize the special "system" ThreadGroup. Was "main" in Harmony, - * but we have an additional group above that in Android. - */ - ThreadGroup() { - this.name = "system"; - this.setParent(null); - } - - /** - * Returns the number of running {@code Thread}s which are children of this thread group, - * directly or indirectly. - * - * @return the number of children - */ - public int activeCount() { - // BEGIN android-changed - int count = 0; - // Lock the children thread list - synchronized (this.childrenThreadsLock) { - for (int i = 0; i < numThreads; i++) { - if(childrenThreads[i].isAlive()) { - count++; - } - } - } - // END android-changed - // Lock this subpart of the tree as we walk - synchronized (this.childrenGroupsLock) { - for (int i = 0; i < numGroups; i++) { - count += this.childrenGroups[i].activeCount(); - } - } - return count; - } - - /** - * Returns the number of {@code ThreadGroup}s which are children of this group, - * directly or indirectly. - * - * @return the number of children - */ - public int activeGroupCount() { - int count = 0; - // Lock this subpart of the tree as we walk - synchronized (this.childrenGroupsLock) { - for (int i = 0; i < numGroups; i++) { - // One for this group & the subgroups - count += 1 + this.childrenGroups[i].activeGroupCount(); - } - } - return count; - } - - /** - * Adds a {@code Thread} to this thread group. This should only be visible to class - * java.lang.Thread, and should only be called when a new Thread is created - * and initialized by the constructor. - * - * @param thread Thread to add - * @throws IllegalThreadStateException if this group has been destroyed already - * @see #remove(java.lang.Thread) - */ - final void add(Thread thread) throws IllegalThreadStateException { - synchronized (this.childrenThreadsLock) { - if (!isDestroyed) { - if (childrenThreads.length == numThreads) { - Thread[] newThreads = new Thread[childrenThreads.length * 2]; - System.arraycopy(childrenThreads, 0, newThreads, 0, numThreads); - newThreads[numThreads++] = thread; - childrenThreads = newThreads; - } else { - childrenThreads[numThreads++] = thread; - } - } else { - throw new IllegalThreadStateException(); - } - } - } - - /** - * Adds a {@code ThreadGroup} to this thread group. - * - * @param g ThreadGroup to add - * @throws IllegalThreadStateException if this group has been destroyed already - */ - private void add(ThreadGroup g) throws IllegalThreadStateException { - synchronized (this.childrenGroupsLock) { - if (!isDestroyed) { - if (childrenGroups.length == numGroups) { - ThreadGroup[] newGroups = new ThreadGroup[childrenGroups.length * 2]; - System.arraycopy(childrenGroups, 0, newGroups, 0, numGroups); - newGroups[numGroups++] = g; - childrenGroups = newGroups; - } else { - childrenGroups[numGroups++] = g; - } - } else { - throw new IllegalThreadStateException(); - } - } - } - - /** - * Does nothing. The definition of this method depends on the deprecated - * method {@link #suspend()}. The exact behavior of this call was never - * specified. - * - * @param b Used to control low memory implicit suspension - * @return {@code true} (always) - * - * @deprecated Required deprecated method suspend(). - */ - @Deprecated - public boolean allowThreadSuspension(boolean b) { - // Does not apply to this VM, no-op - return true; - } - - /** - * Checks the accessibility of this {@code ThreadGroup} from the perspective of the - * caller. If there is a {@code SecurityManager} installed, calls - * {@code checkAccess} with this thread group as a parameter, otherwise does - * nothing. - */ - public final void checkAccess() { - SecurityManager currentManager = System.getSecurityManager(); - if (currentManager != null) { - currentManager.checkAccess(this); - } - } - - /** - * Destroys this thread group and recursively all its subgroups. It is only legal - * to destroy a {@code ThreadGroup} that has no threads in it. Any daemon - * {@code ThreadGroup} is destroyed automatically when it becomes empty (no threads - * or thread groups in it). - * - * @throws IllegalThreadStateException if this thread group or any of its - * subgroups has been destroyed already or if it still contains - * threads. - * @throws SecurityException if {@code this.checkAccess()} fails with - * a SecurityException - */ - public final void destroy() { - checkAccess(); - - // Lock this subpart of the tree as we walk - synchronized (this.childrenThreadsLock) { - synchronized (this.childrenGroupsLock) { - // BEGIN android-added - if (this.isDestroyed) { - throw new IllegalThreadStateException( - "Thread group was already destroyed: " - + (this.name != null ? this.name : "n/a")); - } - if (this.numThreads > 0) { - throw new IllegalThreadStateException( - "Thread group still contains threads: " - + (this.name != null ? this.name : "n/a")); - } - // END android-added - int toDestroy = numGroups; - // Call recursively for subgroups - for (int i = 0; i < toDestroy; i++) { - // We always get the first element - remember, when the - // child dies it removes itself from our collection. See - // below. - this.childrenGroups[0].destroy(); - } - - if (parent != null) { - parent.remove(this); - } - - // Now that the ThreadGroup is really destroyed it can be tagged - // as so - this.isDestroyed = true; - } - } - } - - /* - * Auxiliary method that destroys this thread group and recursively all its - * subgroups if this is a daemon ThreadGroup. - * - * @see #destroy - * @see #setDaemon - * @see #isDaemon - */ - private void destroyIfEmptyDaemon() { - // Has to be non-destroyed daemon to make sense - synchronized (this.childrenThreadsLock) { - if (isDaemon && !isDestroyed && numThreads == 0) { - synchronized (this.childrenGroupsLock) { - if (numGroups == 0) { - destroy(); - } - } - } - } - } - - /** - * Iterates over all active threads in this group (and its sub-groups) and - * stores the threads in the given array. Returns when the array is full or - * no more threads remain, whichever happens first. - * - * <p>Note that this method will silently ignore any threads that don't fit in the - * supplied array. - * - * @param threads the array into which the {@code Thread}s will be copied - * @return the number of {@code Thread}s that were copied - */ - public int enumerate(Thread[] threads) { - return enumerate(threads, true); - } - - /** - * Iterates over all active threads in this group (and, optionally, its - * sub-groups) and stores the threads in the given array. Returns when the - * array is full or no more threads remain, whichever happens first. - * - * <p>Note that this method will silently ignore any threads that don't fit in the - * supplied array. - * - * @param threads the array into which the {@code Thread}s will be copied - * @param recurse indicates whether {@code Thread}s in subgroups should be - * recursively copied as well - * @return the number of {@code Thread}s that were copied - */ - public int enumerate(Thread[] threads, boolean recurse) { - return enumerateGeneric(threads, recurse, 0, true); - } - - /** - * Iterates over all thread groups in this group (and its sub-groups) and - * and stores the groups in the given array. Returns when the array is full - * or no more groups remain, whichever happens first. - * - * <p>Note that this method will silently ignore any thread groups that don't fit in the - * supplied array. - * - * @param groups the array into which the {@code ThreadGroup}s will be copied - * @return the number of {@code ThreadGroup}s that were copied - */ - public int enumerate(ThreadGroup[] groups) { - return enumerate(groups, true); - } - - /** - * Iterates over all thread groups in this group (and, optionally, its - * sub-groups) and stores the groups in the given array. Returns when - * the array is full or no more groups remain, whichever happens first. - * - * <p>Note that this method will silently ignore any thread groups that don't fit in the - * supplied array. - * - * @param groups the array into which the {@code ThreadGroup}s will be copied - * @param recurse indicates whether {@code ThreadGroup}s in subgroups should be - * recursively copied as well or not - * @return the number of {@code ThreadGroup}s that were copied - */ - public int enumerate(ThreadGroup[] groups, boolean recurse) { - return enumerateGeneric(groups, recurse, 0, false); - } - - /** - * Copies into <param>enumeration</param> starting at - * <param>enumerationIndex</param> all Threads or ThreadGroups in the - * receiver. If <param>recurse</param> is true, recursively enumerate the - * elements in subgroups. - * - * If the array passed as parameter is too small no exception is thrown - - * the extra elements are simply not copied. - * - * @param enumeration array into which the elements will be copied - * @param recurse Indicates whether subgroups should be enumerated or not - * @param enumerationIndex Indicates in which position of the enumeration - * array we are - * @param enumeratingThreads Indicates whether we are enumerating Threads or - * ThreadGroups - * @return How many elements were enumerated/copied over - */ - private int enumerateGeneric(Object[] enumeration, boolean recurse, int enumerationIndex, - boolean enumeratingThreads) { - checkAccess(); - - Object[] immediateCollection = enumeratingThreads ? (Object[]) childrenThreads - : (Object[]) childrenGroups; - Object syncLock = enumeratingThreads ? childrenThreadsLock : childrenGroupsLock; - - synchronized (syncLock) { // Lock this subpart of the tree as we walk - for (int i = enumeratingThreads ? numThreads : numGroups; --i >= 0;) { - if (!enumeratingThreads || ((Thread) immediateCollection[i]).isAlive()) { - if (enumerationIndex >= enumeration.length) { - return enumerationIndex; - } - enumeration[enumerationIndex++] = immediateCollection[i]; - } - } - } - - if (recurse) { // Lock this subpart of the tree as we walk - synchronized (this.childrenGroupsLock) { - for (int i = 0; i < numGroups; i++) { - if (enumerationIndex >= enumeration.length) { - return enumerationIndex; - } - enumerationIndex = childrenGroups[i].enumerateGeneric(enumeration, recurse, - enumerationIndex, enumeratingThreads); - } - } - } - return enumerationIndex; - } - - /** - * Returns the maximum allowed priority for a {@code Thread} in this thread group. - * - * @return the maximum priority - * - * @see #setMaxPriority - */ - public final int getMaxPriority() { - return maxPriority; - } - - /** - * Returns the name of this thread group. - * - * @return the group's name - */ - public final String getName() { - return name; - } - - /** - * Returns this thread group's parent {@code ThreadGroup}. It can be null if this - * is the the root ThreadGroup. - * - * @return the parent - */ - public final ThreadGroup getParent() { - if (parent != null) { - parent.checkAccess(); - } - return parent; - } - - /** - * Interrupts every {@code Thread} in this group and recursively in all its - * subgroups. - * - * @throws SecurityException if {@code this.checkAccess()} fails with - * a SecurityException - * - * @see Thread#interrupt - */ - public final void interrupt() { - checkAccess(); - // Lock this subpart of the tree as we walk - synchronized (this.childrenThreadsLock) { - for (int i = 0; i < numThreads; i++) { - this.childrenThreads[i].interrupt(); - } - } - // Lock this subpart of the tree as we walk - synchronized (this.childrenGroupsLock) { - for (int i = 0; i < numGroups; i++) { - this.childrenGroups[i].interrupt(); - } - } - } - - /** - * Checks whether this thread group is a daemon {@code ThreadGroup}. - * - * @return true if this thread group is a daemon {@code ThreadGroup} - * - * @see #setDaemon - * @see #destroy - */ - public final boolean isDaemon() { - return isDaemon; - } - - /** - * Checks whether this thread group has already been destroyed. - * - * @return true if this thread group has already been destroyed - * @see #destroy - */ - public synchronized boolean isDestroyed() { - return isDestroyed; - } - - /** - * Outputs to {@code System.out} a text representation of the - * hierarchy of {@code Thread}s and {@code ThreadGroup}s in this thread group (and recursively). - * Proper indentation is used to show the nesting of groups inside groups - * and threads inside groups. - */ - public void list() { - // We start in a fresh line - System.out.println(); - list(0); - } - - /* - * Outputs to {@code System.out}a text representation of the - * hierarchy of Threads and ThreadGroups in this thread group (and recursively). - * The indentation will be four spaces per level of nesting. - * - * @param levels How many levels of nesting, so that proper indentation can - * be output. - */ - private void list(int levels) { - for (int i = 0; i < levels; i++) { - System.out.print(" "); // 4 spaces for each level - } - - // Print the receiver - System.out.println(this.toString()); - - // Print the children threads, with 1 extra indentation - synchronized (this.childrenThreadsLock) { - for (int i = 0; i < numThreads; i++) { - // children get an extra indentation, 4 spaces for each level - for (int j = 0; j <= levels; j++) { - System.out.print(" "); - } - System.out.println(this.childrenThreads[i]); - } - } - synchronized (this.childrenGroupsLock) { - for (int i = 0; i < numGroups; i++) { - this.childrenGroups[i].list(levels + 1); - } - } - } - - /** - * Checks whether this thread group is a direct or indirect parent group of a - * given {@code ThreadGroup}. - * - * @param g the potential child {@code ThreadGroup} - * @return true if this thread group is parent of {@code g} - */ - public final boolean parentOf(ThreadGroup g) { - while (g != null) { - if (this == g) { - return true; - } - g = g.parent; - } - return false; - } - - /** - * Removes a {@code Thread} from this group. This should only be visible to class - * java.lang.Thread, and should only be called when a Thread dies. - * - * @param thread Thread to remove - * - * @see #add(Thread) - */ - final void remove(java.lang.Thread thread) { - synchronized (this.childrenThreadsLock) { - for (int i = 0; i < numThreads; i++) { - if (childrenThreads[i].equals(thread)) { - numThreads--; - System - .arraycopy(childrenThreads, i + 1, childrenThreads, i, numThreads - - i); - childrenThreads[numThreads] = null; - break; - } - } - } - destroyIfEmptyDaemon(); - } - - /** - * Removes an immediate subgroup. - * - * @param g ThreadGroup to remove - * - * @see #add(Thread) - * @see #add(ThreadGroup) - */ - private void remove(ThreadGroup g) { - synchronized (this.childrenGroupsLock) { - for (int i = 0; i < numGroups; i++) { - if (childrenGroups[i].equals(g)) { - numGroups--; - System.arraycopy(childrenGroups, i + 1, childrenGroups, i, numGroups - i); - childrenGroups[numGroups] = null; - break; - } - } - } - destroyIfEmptyDaemon(); - } - - /** - * Resumes every thread in this group and recursively in all its - * subgroups. - * - * @throws SecurityException if {@code this.checkAccess()} fails with - * a SecurityException - * - * @see Thread#resume - * @see #suspend - * - * @deprecated Requires deprecated method Thread.resume(). - */ - @SuppressWarnings("deprecation") - @Deprecated - public final void resume() { - checkAccess(); - // Lock this subpart of the tree as we walk - synchronized (this.childrenThreadsLock) { - for (int i = 0; i < numThreads; i++) { - this.childrenThreads[i].resume(); - } - } - // Lock this subpart of the tree as we walk - synchronized (this.childrenGroupsLock) { - for (int i = 0; i < numGroups; i++) { - this.childrenGroups[i].resume(); - } - } - } - - /** - * Sets whether this is a daemon {@code ThreadGroup} or not. Daemon - * thread groups are automatically destroyed when they become empty. - * - * @param isDaemon the new value - * @throws SecurityException if {@code checkAccess()} for the parent - * group fails with a SecurityException - * - * @see #isDaemon - * @see #destroy - */ - public final void setDaemon(boolean isDaemon) { - checkAccess(); - this.isDaemon = isDaemon; - } - - /** - * Configures the maximum allowed priority for a {@code Thread} in this group and - * recursively in all its subgroups. - * - * <p>A caller can never increase the maximum priority of a thread group. - * Such an attempt will not result in an exception, it will - * simply leave the thread group with its current maximum priority. - * - * @param newMax the new maximum priority to be set - * - * @throws SecurityException if {@code checkAccess()} fails with a - * SecurityException - * @throws IllegalArgumentException if the new priority is greater than - * Thread.MAX_PRIORITY or less than Thread.MIN_PRIORITY - * - * @see #getMaxPriority - */ - public final void setMaxPriority(int newMax) { - checkAccess(); - - if (newMax <= this.maxPriority) { - if (newMax < Thread.MIN_PRIORITY) { - newMax = Thread.MIN_PRIORITY; - } - - int parentPriority = parent == null ? newMax : parent.getMaxPriority(); - this.maxPriority = parentPriority <= newMax ? parentPriority : newMax; - // Lock this subpart of the tree as we walk - synchronized (this.childrenGroupsLock) { - // ??? why not maxPriority - for (int i = 0; i < numGroups; i++) { - this.childrenGroups[i].setMaxPriority(newMax); - } - } - } - } - - /** - * Sets the parent {@code ThreadGroup} of this thread group, and adds this - * thread group to the parent's collection of immediate children (if {@code parent} is - * not {@code null}). - * - * @param parent The parent ThreadGroup, or null to make this thread group - * the root ThreadGroup - * - * @see #getParent - * @see #parentOf - */ - private void setParent(ThreadGroup parent) { - if (parent != null) { - parent.add(this); - } - this.parent = parent; - } - - /** - * Stops every thread in this group and recursively in all its subgroups. - * - * @throws SecurityException if {@code this.checkAccess()} fails with - * a SecurityException - * - * @see Thread#stop() - * @see Thread#stop(Throwable) - * @see ThreadDeath - * - * @deprecated Requires deprecated method Thread.stop(). - */ - @SuppressWarnings("deprecation") - @Deprecated - public final void stop() { - if (stopHelper()) { - Thread.currentThread().stop(); - } - } - - /** - * @deprecated Requires deprecated method Thread.suspend(). - */ - @SuppressWarnings("deprecation") - @Deprecated - private final boolean stopHelper() { - checkAccess(); - - boolean stopCurrent = false; - // Lock this subpart of the tree as we walk - synchronized (this.childrenThreadsLock) { - Thread current = Thread.currentThread(); - for (int i = 0; i < numThreads; i++) { - if (this.childrenThreads[i] == current) { - stopCurrent = true; - } else { - this.childrenThreads[i].stop(); - } - } - } - // Lock this subpart of the tree as we walk - synchronized (this.childrenGroupsLock) { - for (int i = 0; i < numGroups; i++) { - stopCurrent |= this.childrenGroups[i].stopHelper(); - } - } - return stopCurrent; - } - - /** - * Suspends every thread in this group and recursively in all its - * subgroups. - * - * @throws SecurityException if {@code this.checkAccess()} fails with - * a SecurityException - * - * @see Thread#suspend - * @see #resume - * - * @deprecated Requires deprecated method Thread.suspend(). - */ - @SuppressWarnings("deprecation") - @Deprecated - public final void suspend() { - if (suspendHelper()) { - Thread.currentThread().suspend(); - } - } - - /** - * @deprecated Requires deprecated method Thread.suspend(). - */ - @SuppressWarnings("deprecation") - @Deprecated - private final boolean suspendHelper() { - checkAccess(); - - boolean suspendCurrent = false; - // Lock this subpart of the tree as we walk - synchronized (this.childrenThreadsLock) { - Thread current = Thread.currentThread(); - for (int i = 0; i < numThreads; i++) { - if (this.childrenThreads[i] == current) { - suspendCurrent = true; - } else { - this.childrenThreads[i].suspend(); - } - } - } - // Lock this subpart of the tree as we walk - synchronized (this.childrenGroupsLock) { - for (int i = 0; i < numGroups; i++) { - suspendCurrent |= this.childrenGroups[i].suspendHelper(); - } - } - return suspendCurrent; - } - - @Override - public String toString() { - return getClass().getName() + "[name=" + this.getName() + ",maxPriority=" - + this.getMaxPriority() + "]"; - } - - /** - * Handles uncaught exceptions. Any uncaught exception in any {@code Thread} - * is forwarded to the thread's {@code ThreadGroup} by invoking this - * method. - * - * <p>New code should use {@link Thread#setUncaughtExceptionHandler} instead of thread groups. - * - * @param t the Thread that terminated with an uncaught exception - * @param e the uncaught exception itself - */ - public void uncaughtException(Thread t, Throwable e) { - // BEGIN android-changed - if (parent != null) { - parent.uncaughtException(t, e); - } else if (Thread.getDefaultUncaughtExceptionHandler() != null) { - // TODO The spec is unclear regarding this. What do we do? - Thread.getDefaultUncaughtExceptionHandler().uncaughtException(t, e); - } else if (!(e instanceof ThreadDeath)) { - // No parent group, has to be 'system' Thread Group - e.printStackTrace(System.err); - } - // END android-changed - } - - // BEGIN android-added - /** - * Non-standard method for adding a thread to a group, required by Dalvik. - * - * @param thread Thread to add - * - * @throws IllegalThreadStateException if the thread has been destroyed - * already - * - * @see #add(java.lang.Thread) - * @see #removeThread(java.lang.Thread) - */ - void addThread(Thread thread) throws IllegalThreadStateException { - add(thread); - } - - /** - * Non-standard method for adding a thread to a group, required by Dalvik. - * - * @param thread Thread to add - * - * @throws IllegalThreadStateException if the thread has been destroyed - * already - * - * @see #remove(java.lang.Thread) - * @see #addThread(java.lang.Thread) - */ - void removeThread(Thread thread) throws IllegalThreadStateException { - remove(thread); - } - // END android-added -} diff --git a/luni-kernel/src/main/java/java/lang/Throwable.java b/luni-kernel/src/main/java/java/lang/Throwable.java deleted file mode 100644 index c94631b..0000000 --- a/luni-kernel/src/main/java/java/lang/Throwable.java +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang; - -import java.io.IOException; -import java.io.ObjectOutputStream; -import java.io.PrintStream; -import java.io.PrintWriter; - -/** - * The superclass of all classes which can be thrown by the virtual machine. The - * two direct subclasses are recoverable exceptions ({@code Exception}) and - * unrecoverable errors ({@code Error}). This class provides common methods for - * accessing a string message which provides extra information about the - * circumstances in which the {@code Throwable} was created (basically an error - * message in most cases), and for saving a stack trace (that is, a record of - * the call stack at a particular point in time) which can be printed later. - * <p> - * A {@code Throwable} can also include a cause, which is a nested {@code - * Throwable} that represents the original problem that led to this {@code - * Throwable}. It is often used for wrapping various types of errors into a - * common {@code Throwable} without losing the detailed original error - * information. When printing the stack trace, the trace of the cause is - * included. - * - * @see Error - * @see Exception - * @see RuntimeException - */ -public class Throwable implements java.io.Serializable { - private static final long serialVersionUID = -3042686055658047285L; - - /** - * The message provided when the exception was created. - */ - private String detailMessage; - - /** - * The cause of this Throwable. Null when there is no cause. - */ - private Throwable cause = this; - - // BEGIN android-added - /** - * An intermediate representation of the stack trace. This field may - * be accessed by the VM; do not rename. - */ - private volatile Object stackState; - // END android-added - - /** - * A fully-expanded representation of the stack trace. - */ - private StackTraceElement[] stackTrace; - - /** - * Constructs a new {@code Throwable} that includes the current stack trace. - */ - public Throwable() { - super(); - fillInStackTrace(); - } - - /** - * Constructs a new {@code Throwable} with the current stack trace and the - * specified detail message. - * - * @param detailMessage - * the detail message for this {@code Throwable}. - */ - public Throwable(String detailMessage) { - this(); - this.detailMessage = detailMessage; - } - - /** - * Constructs a new {@code Throwable} with the current stack trace, the - * specified detail message and the specified cause. - * - * @param detailMessage - * the detail message for this {@code Throwable}. - * @param throwable - * the cause of this {@code Throwable}. - */ - public Throwable(String detailMessage, Throwable throwable) { - this(); - this.detailMessage = detailMessage; - cause = throwable; - } - - /** - * Constructs a new {@code Throwable} with the current stack trace and the - * specified cause. - * - * @param throwable - * the cause of this {@code Throwable}. - */ - public Throwable(Throwable throwable) { - this(); - this.detailMessage = throwable == null ? null : throwable.toString(); - cause = throwable; - } - - // BEGIN android-changed - /** - * Records the stack trace from the point where this method has been called - * to this {@code Throwable}. The method is public so that code which - * catches a {@code Throwable} and then re-throws it can adjust the stack - * trace to represent the location where the exception was re-thrown. - * - * @return this {@code Throwable} instance. - */ - public Throwable fillInStackTrace() { - // Fill in the intermediate representation - stackState = nativeFillInStackTrace(); - // Mark the full representation as empty - stackTrace = null; - return this; - } - // END android-changed - - /** - * Returns the extra information message which was provided when this - * {@code Throwable} was created. Returns {@code null} if no message was - * provided at creation time. - * - * @return this {@code Throwable}'s detail message. - */ - public String getMessage() { - return detailMessage; - } - - /** - * Returns the extra information message which was provided when this - * {@code Throwable} was created. Returns {@code null} if no message was - * provided at creation time. Subclasses may override this method to return - * localized text for the message. Android returns the regular detail message. - * - * @return this {@code Throwable}'s localized detail message. - */ - public String getLocalizedMessage() { - return getMessage(); - } - - /** - * Returns the array of stack trace elements of this {@code Throwable}. Each - * {@code StackTraceElement} represents an entry in the call stack. The - * element at position 0 is the top of the stack, that is, the stack frame - * where this {@code Throwable} is thrown. - * - * @return a copy of the array of {@code StackTraceElement}s representing - * the call stack. Changes in the array obtained from this call will - * not change the call stack stored in this {@code Throwable}. - * @see #printStackTrace() - */ - public StackTraceElement[] getStackTrace() { - return getInternalStackTrace().clone(); - } - - /** - * Sets the array of stack trace elements. Each {@code StackTraceElement} - * represents an entry in the call stack. A copy of the specified array is - * stored in this {@code Throwable}. will be returned by {@code - * getStackTrace()} and printed by {@code printStackTrace()}. - * - * @param trace - * the new array of {@code StackTraceElement}s. A copy of the - * array is stored in this {@code Throwable}, so subsequent - * changes to {@code trace} will not change the call stack stored - * in this {@code Throwable}. - * @throws NullPointerException - * if any element in {@code trace} is {@code null}. - * @see #printStackTrace() - */ - public void setStackTrace(StackTraceElement[] trace) { - StackTraceElement[] newTrace = trace.clone(); - for (java.lang.StackTraceElement element : newTrace) { - if (element == null) { - throw new NullPointerException(); - } - } - stackTrace = newTrace; - } - - /** - * Writes a printable representation of this {@code Throwable}'s stack trace - * to the {@code System.err} stream. - * - */ - public void printStackTrace() { - printStackTrace(System.err); - } - - /** - * Counts the number of duplicate stack frames, starting from the - * end of the stack. - * - * @param currentStack a stack to compare - * @param parentStack a stack to compare - * - * @return the number of duplicate stack frames. - */ - private static int countDuplicates(StackTraceElement[] currentStack, - StackTraceElement[] parentStack) { - int duplicates = 0; - int parentIndex = parentStack.length; - for (int i = currentStack.length; --i >= 0 && --parentIndex >= 0;) { - StackTraceElement parentFrame = parentStack[parentIndex]; - if (parentFrame.equals(currentStack[i])) { - duplicates++; - } else { - break; - } - } - return duplicates; - } - - /** - * Returns an array of StackTraceElement. Each StackTraceElement - * represents a entry on the stack. - * - * @return an array of StackTraceElement representing the stack - */ - private StackTraceElement[] getInternalStackTrace() { - if (stackTrace == null) { - // BEGIN android-changed - stackTrace = nativeGetStackTrace(stackState); - stackState = null; // Clean up intermediate representation - // END android-changed - } - return stackTrace; - } - - /** - * Writes a printable representation of this {@code Throwable}'s stack trace - * to the specified print stream. If the {@code Throwable} contains a - * {@link #getCause() cause}, the method will be invoked recursively for - * the nested {@code Throwable}. - * - * @param err - * the stream to write the stack trace on. - */ - public void printStackTrace(PrintStream err) { - err.println(toString()); - // Don't use getStackTrace() as it calls clone() - // Get stackTrace, in case stackTrace is reassigned - StackTraceElement[] stack = getInternalStackTrace(); - for (java.lang.StackTraceElement element : stack) { - err.println("\tat " + element); - } - - StackTraceElement[] parentStack = stack; - Throwable throwable = getCause(); - while (throwable != null) { - err.print("Caused by: "); - err.println(throwable); - StackTraceElement[] currentStack = throwable.getInternalStackTrace(); - int duplicates = countDuplicates(currentStack, parentStack); - for (int i = 0; i < currentStack.length - duplicates; i++) { - err.println("\tat " + currentStack[i]); - } - if (duplicates > 0) { - err.println("\t... " + duplicates + " more"); - } - parentStack = currentStack; - throwable = throwable.getCause(); - } - } - - /** - * Writes a printable representation of this {@code Throwable}'s stack trace - * to the specified print writer. If the {@code Throwable} contains a - * {@link #getCause() cause}, the method will be invoked recursively for the - * nested {@code Throwable}. - * - * @param err - * the writer to write the stack trace on. - */ - public void printStackTrace(PrintWriter err) { - err.println(toString()); - // Don't use getStackTrace() as it calls clone() - // Get stackTrace, in case stackTrace is reassigned - StackTraceElement[] stack = getInternalStackTrace(); - for (java.lang.StackTraceElement element : stack) { - err.println("\tat " + element); - } - - StackTraceElement[] parentStack = stack; - Throwable throwable = getCause(); - while (throwable != null) { - err.print("Caused by: "); - err.println(throwable); - StackTraceElement[] currentStack = throwable.getInternalStackTrace(); - int duplicates = countDuplicates(currentStack, parentStack); - for (int i = 0; i < currentStack.length - duplicates; i++) { - err.println("\tat " + currentStack[i]); - } - if (duplicates > 0) { - err.println("\t... " + duplicates + " more"); - } - parentStack = currentStack; - throwable = throwable.getCause(); - } - } - - @Override - public String toString() { - String msg = getLocalizedMessage(); - String name = getClass().getName(); - if (msg == null) { - return name; - } - return new StringBuffer(name.length() + 2 + msg.length()).append(name).append(": ") - .append(msg).toString(); - } - - /** - * Initializes the cause of this {@code Throwable}. The cause can only be - * initialized once. - * - * @param throwable - * the cause of this {@code Throwable}. - * @return this {@code Throwable} instance. - * @throws IllegalArgumentException - * if {@code Throwable} is this object. - * @throws IllegalStateException - * if the cause has already been initialized. - */ - public Throwable initCause(Throwable throwable) { - // BEGIN android-note - // removed synchronized modifier - // END android-note - if (cause == this) { - if (throwable != this) { - cause = throwable; - return this; - } - throw new IllegalArgumentException("Cause cannot be the receiver"); - } - throw new IllegalStateException("Cause already initialized"); - } - - /** - * Returns the cause of this {@code Throwable}, or {@code null} if there is - * no cause. - * - * @return Throwable this {@code Throwable}'s cause. - */ - public Throwable getCause() { - if (cause == this) { - return null; - } - return cause; - } - - private void writeObject(ObjectOutputStream s) throws IOException { - // ensure the stackTrace field is initialized - getInternalStackTrace(); - s.defaultWriteObject(); - } - - // BEGIN android-added - /* - * Creates a compact, VM-specific collection of goodies, suitable for - * storing in the "stackState" field, based on the current thread's - * call stack. - */ - native private static Object nativeFillInStackTrace(); - - /* - * Creates an array of StackTraceElement objects from the data held - * in "stackState". - */ - native private static StackTraceElement[] nativeGetStackTrace(Object stackState); - // END android-added -} diff --git a/luni-kernel/src/main/java/java/lang/ref/PhantomReference.java b/luni-kernel/src/main/java/java/lang/ref/PhantomReference.java deleted file mode 100644 index 46ffcad..0000000 --- a/luni-kernel/src/main/java/java/lang/ref/PhantomReference.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang.ref; - -/** - * Implements a phantom reference, which is the weakest of the three types of - * references. Once the garbage collector decides that an object {@code obj} is - * phantom-reachable, it is being enqueued - * on the corresponding queue, but its referent is not cleared. That is, the - * reference queue of the phantom reference must explicitly be processed by some - * application code. As a consequence, a phantom reference that is not - * registered with any reference queue does not make any sense. - * <p> - * Phantom references are useful for implementing cleanup operations that are - * necessary before an object gets garbage-collected. They are sometimes more - * flexible than the {@link Object#finalize()} method. - */ -public class PhantomReference<T> extends Reference<T> { - - /** - * Constructs a new phantom reference and registers it with the given - * reference queue. The reference queue may be {@code null}, but this case - * does not make any sense, since the reference will never be enqueued, and - * the {@link #get()} method always returns {@code null}. - * - * @param r the referent to track - * @param q the queue to register the phantom reference object with - */ - public PhantomReference(T r, ReferenceQueue<? super T> q) { - super(); - referent = r; - queue = q; - } - - /** - * Returns {@code null}. The referent of a phantom reference is not - * accessible. - * - * @return {@code null} (always) - */ - @Override - public T get() { - return null; - } -} diff --git a/luni-kernel/src/main/java/java/lang/ref/Reference.java b/luni-kernel/src/main/java/java/lang/ref/Reference.java deleted file mode 100644 index 9b59b35..0000000 --- a/luni-kernel/src/main/java/java/lang/ref/Reference.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang.ref; - -/** - * Provides an abstract class which describes behavior common to all reference - * objects. It is not possible to create immediate subclasses of - * {@code Reference} in addition to the ones provided by this package. It is - * also not desirable to do so, since references require very close cooperation - * with the system's garbage collector. The existing, specialized reference - * classes should be used instead. - */ -public abstract class Reference<T> { - - /** - * The object to which this reference refers. - * VM requirement: this field <em>must</em> be called "referent" - * and be an object. - */ - volatile T referent; - - /** - * If non-null, the queue on which this reference will be enqueued - * when the referent is appropriately reachable. - * VM requirement: this field <em>must</em> be called "queue" - * and be a java.lang.ref.ReferenceQueue. - */ - @SuppressWarnings("unchecked") - volatile ReferenceQueue queue; - - /** - * Used internally by java.lang.ref.ReferenceQueue. - * VM requirement: this field <em>must</em> be called "queueNext" - * and be a java.lang.ref.Reference. - */ - @SuppressWarnings("unchecked") - volatile Reference queueNext; - - /** - * Used internally by Dalvik. - * VM requirement: this field <em>must</em> be called "vmData" - * and be an int. - */ - @SuppressWarnings("unused") - volatile private int vmData; - - /** - * Constructs a new instance of this class. - */ - Reference() { - super(); - } - - /** - * Makes the referent {@code null}. This does not force the reference - * object to be enqueued. - */ - public void clear() { - referent = null; - } - - /** - * An implementation of .enqueue() that is safe for the VM to call. - * If a Reference object is a subclass of any of the - * java.lang.ref.*Reference classes and that subclass overrides enqueue(), - * the VM may not call the overridden method. - * VM requirement: this method <em>must</em> be called "enqueueInternal", - * have the signature "()Z", and be private. - * - * @return {@code true} if this call has caused the {@code Reference} to - * become enqueued, or {@code false} otherwise - */ - @SuppressWarnings("unchecked") - private synchronized boolean enqueueInternal() { - /* VM requirement: - * The VM assumes that this function only does work - * if "(queue != null && queueNext == null)". - * If that changes, Dalvik needs to change, too. - * (see MarkSweep.c:enqueueReference()) - */ - if (queue != null && queueNext == null) { - queue.enqueue(this); - queue = null; - return true; - } - return false; - } - - /** - * Forces the reference object to be enqueued if it has been associated with - * a queue. - * - * @return {@code true} if this call has caused the {@code Reference} to - * become enqueued, or {@code false} otherwise - */ - public boolean enqueue() { - return enqueueInternal(); - } - - /** - * Returns the referent of the reference object. - * - * @return the referent to which reference refers, or {@code null} if the - * object has been cleared. - */ - public T get() { - return referent; - } - - /** - * Checks whether the reference object has been enqueued. - * - * @return {@code true} if the {@code Reference} has been enqueued, {@code - * false} otherwise - */ - public boolean isEnqueued() { - return queueNext != null; - } - -} diff --git a/luni-kernel/src/main/java/java/lang/ref/SoftReference.java b/luni-kernel/src/main/java/java/lang/ref/SoftReference.java deleted file mode 100644 index 2bf8746..0000000 --- a/luni-kernel/src/main/java/java/lang/ref/SoftReference.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang.ref; - -/** - * Implements a soft reference, which is the least-weak of the three types of - * references. Once the garbage collector has decided that an object {@code obj} - * is softly-reachable, the following - * may happen, either immediately or at a later point: - * - * <ul> - * <li> - * A set {@code ref} of references is determined. {@code ref} contains the - * following elements: - * <ul> - * <li> - * All soft references pointing to {@code obj}. - * </li> - * <li> - * All soft references pointing to objects from which {@code obj} is - * strongly reachable. - * </li> - * </ul> - * </li> - * <li> - * All references in {@code ref} are atomically cleared. - * </li> - * <li> - * At the same time or some time in the future, all references in {@code - * ref} will be enqueued with their corresponding reference queues, if any. - * </li> - * </ul> - * - * The system may decide not to clear and enqueue soft references until a later - * time, yet all {@code SoftReference}s pointing to softly reachable objects are - * guaranteed to be cleared before the VM will throw an {@link - * java.lang.OutOfMemoryError}. - * - * Soft references are useful for caches that should automatically have - * their entries removed once they are not referenced any more (from outside), - * and there is a need for memory. The difference between a {@code - * SoftReference} and a {@code WeakReference} is the point of time at which the - * decision is made to clear and enqueue the reference: - * - * <ul> - * <li> - * A {@code SoftReference} should be cleared and enqueued <em>as late as - * possible</em>, that is, in case the VM is in danger of running out of - * memory. - * </li> - * <li> - * A {@code WeakReference} may be cleared and enqueued as soon as is - * known to be weakly-referenced. - * </li> - * </ul> - */ -public class SoftReference<T> extends Reference<T> { - - /** - * Constructs a new soft reference to the given referent. The newly created - * reference is not registered with any reference queue. - * - * @param r the referent to track - */ - public SoftReference(T r) { - super(); - referent = r; - } - - /** - * Constructs a new soft reference to the given referent. The newly created - * reference is registered with the given reference queue. - * - * @param r the referent to track - * @param q the queue to register to the reference object with. A null value - * results in a weak reference that is not associated with any - * queue. - */ - public SoftReference(T r, ReferenceQueue<? super T> q) { - super(); - referent = r; - queue = q; - } -} diff --git a/luni-kernel/src/main/java/java/lang/ref/WeakReference.java b/luni-kernel/src/main/java/java/lang/ref/WeakReference.java deleted file mode 100644 index e326a24..0000000 --- a/luni-kernel/src/main/java/java/lang/ref/WeakReference.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang.ref; - -/** - * Implements a weak reference, which is the middle of the three types of - * references. Once the garbage collector decides that an object {@code obj} is - * is weakly-reachable, the following - * happens: - * - * <ul> - * <li> - * A set {@code ref} of references is determined. {@code ref} contains the - * following elements: - * <ul> - * <li> - * All weak references pointing to {@code obj}. - * </li> - * <li> - * All weak references pointing to objects from which {@code obj} is - * either strongly or softly reachable. - * </li> - * </ul> - * </li> - * <li> - * All references in {@code ref} are atomically cleared. - * </li> - * <li> - * All objects formerly being referenced by {@code ref} become eligible for - * finalization. - * </li> - * <li> - * At some future point, all references in {@code ref} will be enqueued - * with their corresponding reference queues, if any. - * </li> - * </ul> - * - * Weak references are useful for mappings that should have their entries - * removed automatically once they are not referenced any more (from outside). - * The difference between a {@code SoftReference} and a {@code WeakReference} is - * the point of time at which the decision is made to clear and enqueue the - * reference: - * - * <ul> - * <li> - * A {@code SoftReference} should be cleared and enqueued <em>as late as - * possible</em>, that is, in case the VM is in danger of running out of - * memory. - * </li> - * <li> - * A {@code WeakReference} may be cleared and enqueued as soon as is - * known to be weakly-referenced. - * </li> - * </ul> - */ -public class WeakReference<T> extends Reference<T> { - - /** - * Constructs a new weak reference to the given referent. The newly created - * reference is not registered with any reference queue. - * - * @param r the referent to track - */ - public WeakReference(T r) { - super(); - referent = r; - } - - /** - * Constructs a new weak reference to the given referent. The newly created - * reference is registered with the given reference queue. - * - * @param r the referent to track - * @param q the queue to register to the reference object with. A null value - * results in a weak reference that is not associated with any - * queue. - */ - public WeakReference(T r, ReferenceQueue<? super T> q) { - super(); - referent = r; - queue = q; - } -} diff --git a/luni-kernel/src/main/java/java/lang/reflect/AccessibleObject.java b/luni-kernel/src/main/java/java/lang/reflect/AccessibleObject.java deleted file mode 100644 index 8990156..0000000 --- a/luni-kernel/src/main/java/java/lang/reflect/AccessibleObject.java +++ /dev/null @@ -1,455 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang.reflect; - -import java.lang.annotation.Annotation; -import java.util.Hashtable; - -import org.apache.harmony.kernel.vm.StringUtils; -import org.apache.harmony.kernel.vm.ReflectionAccess; - -/** - * {@code AccessibleObject} is the superclass of all member reflection classes - * (Field, Constructor, Method). AccessibleObject provides the ability to toggle - * a flag controlling access checks for these objects. By default, accessing a - * member (for example, setting a field or invoking a method) checks the - * validity of the access (for example, invoking a private method from outside - * the defining class is prohibited) and throws IllegalAccessException if the - * operation is not permitted. If the accessible flag is set to true, these - * checks are omitted. This allows privileged code, such as Java object - * serialization, object inspectors, and debuggers to have complete access to - * objects. - * - * @see Field - * @see Constructor - * @see Method - * @see ReflectPermission - */ -public class AccessibleObject implements AnnotatedElement { - - // If true, object is accessible, bypassing normal security checks - boolean flag = false; - - /** - * one dimensional array - */ - private static final String DIMENSION_1 = "[]"; - - /** - * two dimensional array - */ - private static final String DIMENSION_2 = "[][]"; - - /** - * three dimensional array - */ - private static final String DIMENSION_3 = "[][][]"; - - // Holds a mapping from Java type names to native type codes. - static Hashtable<String, String> trans; - - static { - trans = new Hashtable<String, String>(9); - trans.put("byte", "B"); - trans.put("char", "C"); - trans.put("short", "S"); - trans.put("int", "I"); - trans.put("long", "J"); - trans.put("float", "F"); - trans.put("double", "D"); - trans.put("void", "V"); - trans.put("boolean", "Z"); - } - - /** - * Attempts to set the value of the accessible flag for all the objects in - * the array provided. Only one security check is performed. Setting this - * flag to {@code false} will enable access checks, setting to {@code true} - * will disable them. If there is a security manager, checkPermission is - * called with a {@code ReflectPermission("suppressAccessChecks")}. - * - * @param objects - * the accessible objects - * @param flag - * the new value for the accessible flag - * - * @throws SecurityException - * if the request is denied - * - * @see #setAccessible(boolean) - * @see ReflectPermission - */ - public static void setAccessible(AccessibleObject[] objects, boolean flag) - throws SecurityException { - SecurityManager smgr = System.getSecurityManager(); - if (smgr != null) { - smgr.checkPermission(new ReflectPermission("suppressAccessChecks")); - } - - synchronized(AccessibleObject.class) { - for (int i = 0; i < objects.length; i++) { - objects[i].flag = flag; - } - } - } - - /** - * Constructs a new {@code AccessibleObject} instance. {@code - * AccessibleObject} instances can only be constructed by the virtual - * machine. - */ - protected AccessibleObject() { - super(); - } - - /** - * Indicates whether this object is accessible without security checks being - * performed. Returns the accessible flag. - * - * @return {@code true} if this object is accessible without security - * checks, {@code false} otherwise - */ - public boolean isAccessible() { - return flag; - } - - /** - * Attempts to set the value of the accessible flag. Setting this flag to - * {@code false} will enable access checks, setting to {@code true} will - * disable them. If there is a security manager, checkPermission is called - * with a {@code ReflectPermission("suppressAccessChecks")}. - * - * @param flag - * the new value for the accessible flag - * - * @throws SecurityException - * if the request is denied - * - * @see ReflectPermission - */ - public void setAccessible(boolean flag) throws SecurityException { - SecurityManager smgr = System.getSecurityManager(); - if (smgr != null) { - smgr.checkPermission(new ReflectPermission("suppressAccessChecks")); - } - - this.flag = flag; - } - - /** - * Sets the accessible flag on this instance without doing any checks. - * - * @param flag - * the new value for the accessible flag - */ - /*package*/ void setAccessibleNoCheck(boolean flag) { - this.flag = flag; - } - - public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) { - return getAnnotation(annotationType) != null; - } - - public Annotation[] getDeclaredAnnotations() { - throw new RuntimeException("subclass must override this method"); - } - - public Annotation[] getAnnotations() { - // for all but Class, getAnnotations == getDeclaredAnnotations - return getDeclaredAnnotations(); - } - - /* slow, but works for all sub-classes */ - public <T extends Annotation> T getAnnotation(Class<T> annotationType) { - if (annotationType == null) { - throw new NullPointerException(); - } - Annotation[] annos = getAnnotations(); - for (int i = annos.length-1; i >= 0; --i) { - if (annos[i].annotationType() == annotationType) { - return (T) annos[i]; - } - } - return null; - } - - /** - * Returns the signature for a class. This is the kind of signature used - * internally by the JVM, with one-character codes representing the basic - * types. It is not suitable for printing. - * - * @param clazz - * the class for which a signature is required - * - * @return The signature as a string - */ - String getSignature(Class<?> clazz) { - String result = ""; - String nextType = clazz.getName(); - - if(trans.containsKey(nextType)) { - result = trans.get(nextType); - } else { - if(clazz.isArray()) { - result = "[" + getSignature(clazz.getComponentType()); - } else { - result = "L" + nextType + ";"; - } - } - return result; - } - - /** - * Returns a printable String consisting of the canonical names of the - * classes contained in an array. The form is that used in parameter and - * exception lists, that is, the class or type names are separated by - * commas. - * - * @param types - * the array of classes - * - * @return The String of names - */ - String toString(Class<?>[] types) { - StringBuilder result = new StringBuilder(); - - if (types.length != 0) { - result.append(types[0].getCanonicalName()); - for (int i = 1; i < types.length; i++) { - result.append(','); - result.append(types[i].getCanonicalName()); - } - } - - return result.toString(); - } - - /** - * Gets the Signature attribute for this instance. Returns {@code null} - * if not found. - */ - /*package*/ String getSignatureAttribute() { - /* - * Note: This method would have been declared abstract, but the - * standard API lists this class as concrete. - */ - throw new UnsupportedOperationException(); - } - - /** - * Retrieve the signature attribute from an arbitrary class. This is - * the same as Class.getSignatureAttribute(), but it can be used from - * the java.lang.reflect package. - */ - /*package*/ static String getClassSignatureAttribute(Class clazz) { - Object[] annotation = getClassSignatureAnnotation(clazz); - - if (annotation == null) { - return null; - } - - return StringUtils.combineStrings(annotation); - } - - /** - * Retrieve the signature annotation from an arbitrary class. This is - * the same as Class.getSignatureAttribute(), but it can be used from - * the java.lang.reflect package. - */ - private static native Object[] getClassSignatureAnnotation(Class clazz); - - /** - * Gets the unique instance of {@link ReflectionAccessImpl}. - * - * @return non-null; the unique instance - */ - static /*package*/ ReflectionAccess getReflectionAccess() { - return ReflectionAccessImpl.THE_ONE; - } - - - /** - * Appends the specified class name to the buffer. The class may represent - * a simple type, a reference type or an array type. - * - * @param sb buffer - * @param obj the class which name should be appended to the buffer - * - * @throws NullPointerException if any of the arguments is null - */ - void appendArrayType(StringBuilder sb, Class<?> obj) { - if (!obj.isArray()) { - sb.append(obj.getName()); - return; - } - int dimensions = 1; - Class simplified = obj.getComponentType(); - obj = simplified; - while (simplified.isArray()) { - obj = simplified; - dimensions++; - } - sb.append(obj.getName()); - switch (dimensions) { - case 1: - sb.append(DIMENSION_1); - break; - case 2: - sb.append(DIMENSION_2); - break; - case 3: - sb.append(DIMENSION_3); - break; - default: - for (; dimensions > 0; dimensions--) { - sb.append(DIMENSION_1); - } - } - } - - /** - * Appends names of the specified array classes to the buffer. The array - * elements may represent a simple type, a reference type or an array type. - * Output format: java.lang.Object[], java.io.File, void - * - * @param sb buffer - * @param objs array of classes to print the names - * - * @throws NullPointerException if any of the arguments is null - */ - void appendArrayType(StringBuilder sb, Class[] objs) { - if (objs.length > 0) { - appendArrayType(sb, objs[0]); - for (int i = 1; i < objs.length; i++) { - sb.append(','); - appendArrayType(sb, objs[i]); - } - } - } - - /** - * Appends names of the specified array classes to the buffer. The array - * elements may represent a simple type, a reference type or an array type. - * Output format: java.lang.Object[], java.io.File, void - * - * @param sb buffer - * @param objs array of classes to print the names - * - * @throws NullPointerException if any of the arguments is null - */ - void appendArrayGenericType(StringBuilder sb, Type[] objs) { - if (objs.length > 0) { - appendGenericType(sb, objs[0]); - for (int i = 1; i < objs.length; i++) { - sb.append(','); - appendGenericType(sb, objs[i]); - } - } - } - - /** - * Appends the generic type representation to the buffer. - * - * @param sb buffer - * @param obj the generic type which representation should be appended to the buffer - * - * @throws NullPointerException if any of the arguments is null - */ - void appendGenericType(StringBuilder sb, Type obj) { - if (obj instanceof TypeVariable) { - sb.append(((TypeVariable)obj).getName()); - } else if (obj instanceof ParameterizedType) { - sb.append(obj.toString()); - } else if (obj instanceof GenericArrayType) { //XXX: is it a working branch? - Type simplified = ((GenericArrayType)obj).getGenericComponentType(); - appendGenericType(sb, simplified); - sb.append("[]"); - } else if (obj instanceof Class) { - Class c = ((Class<?>)obj); - if (c.isArray()){ - String as[] = c.getName().split("\\["); - int len = as.length-1; - if (as[len].length() > 1){ - sb.append(as[len].substring(1, as[len].length()-1)); - } else { - char ch = as[len].charAt(0); - if (ch == 'I') - sb.append("int"); - else if (ch == 'B') - sb.append("byte"); - else if (ch == 'J') - sb.append("long"); - else if (ch == 'F') - sb.append("float"); - else if (ch == 'D') - sb.append("double"); - else if (ch == 'S') - sb.append("short"); - else if (ch == 'C') - sb.append("char"); - else if (ch == 'Z') - sb.append("boolean"); - else if (ch == 'V') //XXX: is it a working branch? - sb.append("void"); - } - for (int i = 0; i < len; i++){ - sb.append("[]"); - } - } else { - sb.append(c.getName()); - } - } - } - - /** - * Appends names of the specified array classes to the buffer. The array - * elements may represent a simple type, a reference type or an array type. - * In case if the specified array element represents an array type its - * internal will be appended to the buffer. - * Output format: [Ljava.lang.Object;, java.io.File, void - * - * @param sb buffer - * @param objs array of classes to print the names - * - * @throws NullPointerException if any of the arguments is null - */ - void appendSimpleType(StringBuilder sb, Class<?>[] objs) { - if (objs.length > 0) { - sb.append(objs[0].getName()); - for (int i = 1; i < objs.length; i++) { - sb.append(','); - sb.append(objs[i].getName()); - } - } - } -} diff --git a/luni-kernel/src/main/java/java/lang/reflect/Array.java b/luni-kernel/src/main/java/java/lang/reflect/Array.java deleted file mode 100644 index 8a12f71..0000000 --- a/luni-kernel/src/main/java/java/lang/reflect/Array.java +++ /dev/null @@ -1,776 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang.reflect; - -/** - * This class provides static methods to create and access arrays dynamically. - */ -public final class Array { - - /** - * Prevent this class from being instantiated. - */ - private Array(){ - //do nothing - } - - /** - * Returns the element of the array at the specified index. This reproduces - * the effect of {@code array[index]}. If the array component is a primitive - * type, the result is automatically wrapped. - * - * @param array - * the array - * @param index - * the index - * - * @return the requested element, possibly wrapped - * - * @throws NullPointerException - * if the array is null - * @throws IllegalArgumentException - * if {@code array} is not an array - * @throws ArrayIndexOutOfBoundsException - * if {@code index < 0 || index >= array.length} - */ - public static Object get(Object array, int index) - throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - if (array instanceof Object[]) - return ((Object[]) array)[index]; - - if (array instanceof boolean[]) - return ((boolean[]) array)[index] ? Boolean.TRUE : Boolean.FALSE; - - if (array instanceof byte[]) - return Byte.valueOf(((byte[]) array)[index]); - - if (array instanceof char[]) - return Character.valueOf(((char[]) array)[index]); - - if (array instanceof short[]) - return Short.valueOf(((short[]) array)[index]); - - if (array instanceof int[]) - return Integer.valueOf(((int[]) array)[index]); - - if (array instanceof long[]) - return Long.valueOf(((long[]) array)[index]); - - if (array instanceof float[]) - return new Float(((float[]) array)[index]); - - if (array instanceof double[]) - return new Double(((double[]) array)[index]); - - if (array == null) - throw new NullPointerException(); - - throw new IllegalArgumentException("Not an array"); - } - - /** - * Returns the element of the array at the specified index, converted to a - * {@code boolean}, if possible. This reproduces the effect of {@code - * array[index]} - * - * @param array - * the array - * @param index - * the index - * - * @return the requested element - * - * @throws NullPointerException - * if the {@code array} is {@code null} - * @throws IllegalArgumentException - * if {@code array} is not an array or the element at the - * index position can not be converted to the return type - * @throws ArrayIndexOutOfBoundsException - * if {@code index < 0 || index >= array.length} - */ - public static boolean getBoolean(Object array, int index) - throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - if (array instanceof boolean[]) { - return ((boolean[]) array)[index]; - } else if (array == null) { - throw new NullPointerException(); - } else if (array.getClass().isArray()) { - throw new IllegalArgumentException("Wrong array type"); - } else { - throw new IllegalArgumentException("Not an array"); - } - } - - /** - * Returns the element of the array at the specified index, converted to a - * {@code byte}, if possible. This reproduces the effect of {@code - * array[index]} - * - * @param array - * the array - * @param index - * the index - * - * @return the requested element - * - * @throws NullPointerException - * if the {@code array} is {@code null} - * @throws IllegalArgumentException - * if {@code array} is not an array or the element at the - * index position can not be converted to the return type - * @throws ArrayIndexOutOfBoundsException - * if {@code index < 0 || index >= array.length} - */ - public static byte getByte(Object array, int index) - throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - if (array instanceof byte[]) { - return ((byte[]) array)[index]; - } else { - return getBoolean(array, index) ? (byte)1 : (byte)0; - } - } - - /** - * Returns the element of the array at the specified index, converted to a - * {@code char}, if possible. This reproduces the effect of {@code - * array[index]} - * - * @param array - * the array - * @param index - * the index - * - * @return the requested element - * - * @throws NullPointerException - * if the {@code array} is {@code null} - * @throws IllegalArgumentException - * if {@code array} is not an array or the element at the - * index position can not be converted to the return type - * @throws ArrayIndexOutOfBoundsException - * if {@code index < 0 || index >= array.length} - */ - public static char getChar(Object array, int index) - throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - if (array instanceof char[]) { - return ((char[]) array)[index]; - } else if (array == null) { - throw new NullPointerException(); - } else if (array.getClass().isArray()) { - throw new IllegalArgumentException("Wrong array type"); - } else { - throw new IllegalArgumentException("Not an array"); - } - } - - /** - * Returns the element of the array at the specified index, converted to a - * {@code double}, if possible. This reproduces the effect of {@code - * array[index]} - * - * @param array - * the array - * @param index - * the index - * - * @return the requested element - * - * @throws NullPointerException - * if the {@code array} is {@code null} - * @throws IllegalArgumentException - * if {@code array} is not an array or the element at the - * index position can not be converted to the return type - * @throws ArrayIndexOutOfBoundsException - * if {@code index < 0 || index >= array.length} - */ - public static double getDouble(Object array, int index) - throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - if (array instanceof double[]) { - return ((double[]) array)[index]; - } else { - return getFloat(array, index); - } - } - - /** - * Returns the element of the array at the specified index, converted to a - * {@code float}, if possible. This reproduces the effect of {@code - * array[index]} - * - * @param array - * the array - * @param index - * the index - * - * @return the requested element - * - * @throws NullPointerException - * if the {@code array} is {@code null} - * @throws IllegalArgumentException - * if {@code array} is not an array or the element at the - * index position can not be converted to the return type - * @throws ArrayIndexOutOfBoundsException - * if {@code index < 0 || index >= array.length} - */ - public static float getFloat(Object array, int index) - throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - if (array instanceof float[]) { - return ((float[]) array)[index]; - } else { - return getLong(array, index); - } - } - - /** - * Returns the element of the array at the specified index, converted to an - * {@code int}, if possible. This reproduces the effect of {@code - * array[index]} - * - * @param array - * the array - * @param index - * the index - * - * @return the requested element - * - * @throws NullPointerException - * if the {@code array} is {@code null} - * @throws IllegalArgumentException - * if {@code array} is not an array or the element at the - * index position can not be converted to the return type - * @throws ArrayIndexOutOfBoundsException - * if {@code index < 0 || index >= array.length} - */ - public static int getInt(Object array, int index) - throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - if (array instanceof int[]) { - return ((int[]) array)[index]; - } else { - return getShort(array, index); - } - } - - /** - * Returns the length of the array. This reproduces the effect of {@code - * array.length} - * - * @param array - * the array - * - * @return the length of the array - * - * @throws NullPointerException - * if the {@code array} is {@code null} - * @throws IllegalArgumentException - * if {@code array} is not an array - */ - public static int getLength(Object array) { - if (array instanceof Object[]) - return ((Object[]) array).length; - - if (array instanceof boolean[]) - return ((boolean[]) array).length; - - if (array instanceof byte[]) - return ((byte[]) array).length; - - if (array instanceof char[]) - return ((char[]) array).length; - - if (array instanceof short[]) - return ((short[]) array).length; - - if (array instanceof int[]) - return ((int[]) array).length; - - if (array instanceof long[]) - return ((long[]) array).length; - - if (array instanceof float[]) - return ((float[]) array).length; - - if (array instanceof double[]) - return ((double[]) array).length; - - if (array == null) - throw new NullPointerException(); - - throw new IllegalArgumentException("Not an array"); - } - - /** - * Returns the element of the array at the specified index, converted to a - * {@code long}, if possible. This reproduces the effect of {@code - * array[index]} - * - * @param array - * the array - * @param index - * the index - * - * @return the requested element - * - * @throws NullPointerException - * if the {@code array} is {@code null} - * @throws IllegalArgumentException - * if {@code array} is not an array or the element at the - * index position can not be converted to the return type - * @throws ArrayIndexOutOfBoundsException - * if {@code index < 0 || index >= array.length} - */ - public static long getLong(Object array, int index) - throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - if (array instanceof long[]) { - return ((long[]) array)[index]; - } else { - return getInt(array, index); - } - } - - /** - * Returns the element of the array at the specified index, converted to a - * {@code short}, if possible. This reproduces the effect of {@code - * array[index]} - * - * @param array - * the array - * @param index - * the index - * - * @return the requested element - * - * @throws NullPointerException - * if the {@code array} is {@code null} - * @throws IllegalArgumentException - * if {@code array} is not an array or the element at the - * index position can not be converted to the return type - * @throws ArrayIndexOutOfBoundsException - * if {@code index < 0 || index >= array.length} - */ - public static short getShort(Object array, int index) - throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - if (array instanceof short[]) - return ((short[]) array)[index]; - - return getByte(array, index); - } - - /** - * Returns a new multidimensional array of the specified component type and - * dimensions. This reproduces the effect of {@code new - * componentType[d0][d1]...[dn]} for a dimensions array of { d0, d1, ... , - * dn }. - * - * @param componentType - * the component type of the new array - * @param dimensions - * the dimensions of the new array - * - * @return the new array - * - * @throws NullPointerException - * if the component type is {@code null} - * @throws NegativeArraySizeException - * if any of the dimensions are negative - * @throws IllegalArgumentException - * if the array of dimensions is of size zero, or exceeds the - * limit of the number of dimension for an array (currently 255) - */ - public static Object newInstance(Class<?> componentType, int[] dimensions) - throws NegativeArraySizeException, IllegalArgumentException { - if (dimensions.length <= 0 || dimensions.length > 255) - throw new IllegalArgumentException("Bad number of dimensions"); - - if (componentType == Void.TYPE) - throw new IllegalArgumentException(); - - if (componentType == null) - throw new NullPointerException(); - - return createMultiArray(componentType, dimensions); - } - - /* - * Create a multi-dimensional array of objects with the specified type. - */ - native private static Object createMultiArray(Class<?> componentType, - int[] dimensions) throws NegativeArraySizeException; - - /** - * Returns a new array of the specified component type and length. This - * reproduces the effect of {@code new componentType[size]}. - * - * @param componentType - * the component type of the new array - * @param size - * the length of the new array - * - * @return the new array - * - * @throws NullPointerException - * if the component type is null - * @throws NegativeArraySizeException - * if {@code size < 0} - */ - public static Object newInstance(Class<?> componentType, int size) - throws NegativeArraySizeException { - if (!componentType.isPrimitive()) - return createObjectArray(componentType, size); - - if (componentType == Boolean.TYPE) - return new boolean[size]; - - if (componentType == Byte.TYPE) - return new byte[size]; - - if (componentType == Character.TYPE) - return new char[size]; - - if (componentType == Short.TYPE) - return new short[size]; - - if (componentType == Integer.TYPE) - return new int[size]; - - if (componentType == Long.TYPE) - return new long[size]; - - if (componentType == Float.TYPE) - return new float[size]; - - if (componentType == Double.TYPE) - return new double[size]; - - if (componentType == Void.TYPE) - throw new IllegalArgumentException(); - - throw new RuntimeException(); // should be impossible - } - - /* - * Create a one-dimensional array of objects with the specified type. - */ - native private static Object createObjectArray(Class<?> componentType, - int length) throws NegativeArraySizeException; - - /** - * Sets the element of the array at the specified index to the value. This - * reproduces the effect of {@code array[index] = value}. If the array - * component is a primitive type, the value is automatically unwrapped. - * - * @param array - * the array - * @param index - * the index - * @param value - * the new value - * - * @throws NullPointerException - * if the {@code array} is {@code null} - * @throws IllegalArgumentException - * if {@code array} is not an array or the value cannot be - * converted to the array type by a widening conversion - * @throws ArrayIndexOutOfBoundsException - * if {@code index < 0 || index >= array.length} - */ - public static void set(Object array, int index, Object value) - throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - if (!array.getClass().isArray()) { - throw new IllegalArgumentException("Not an array type"); - } - - if (array instanceof Object[]) { - if (value != null && - !array.getClass().getComponentType().isInstance(value)) { - // incompatible object type for this array - throw new IllegalArgumentException("Wrong array type"); - } - - ((Object[]) array)[index] = value; - } else { - if (value == null) { - throw new IllegalArgumentException("Primitive array can't take null values."); - } - - if (value instanceof Boolean) - setBoolean(array, index, ((Boolean) value).booleanValue()); - else if (value instanceof Byte) - setByte(array, index, ((Byte) value).byteValue()); - else if (value instanceof Character) - setChar(array, index, ((Character) value).charValue()); - else if (value instanceof Short) - setShort(array, index, ((Short) value).shortValue()); - else if (value instanceof Integer) - setInt(array, index, ((Integer) value).intValue()); - else if (value instanceof Long) - setLong(array, index, ((Long) value).longValue()); - else if (value instanceof Float) - setFloat(array, index, ((Float) value).floatValue()); - else if (value instanceof Double) - setDouble(array, index, ((Double) value).doubleValue()); - } - } - - /** - * Sets the element of the array at the specified index to the {@code - * boolean} value. This reproduces the effect of {@code array[index] = - * value}. - * - * @param array - * the array - * @param index - * the index - * @param value - * the new value - * - * @throws NullPointerException - * if the {@code array} is {@code null} - * @throws IllegalArgumentException - * if the {@code array} is not an array or the value cannot be - * converted to the array type by a widening conversion - * @throws ArrayIndexOutOfBoundsException - * if {@code index < 0 || index >= array.length} - */ - public static void setBoolean(Object array, int index, boolean value) { - if (array instanceof boolean[]) { - ((boolean[]) array)[index] = value; - } else { - setByte(array, index, value ? (byte)1 : (byte)0); - } - } - - /** - * Sets the element of the array at the specified index to the {@code byte} - * value. This reproduces the effect of {@code array[index] = value}. - * - * @param array - * the array - * @param index - * the index - * @param value - * the new value - * - * @throws NullPointerException - * if the {@code array} is {@code null} - * @throws IllegalArgumentException - * if the {@code array} is not an array or the value cannot be - * converted to the array type by a widening conversion - * @throws ArrayIndexOutOfBoundsException - * if {@code index < 0 || index >= array.length} - */ - public static void setByte(Object array, int index, byte value) - throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - if (array instanceof byte[]) { - ((byte[]) array)[index] = value; - } else { - setShort(array, index, value); - } - } - - /** - * Set the element of the array at the specified index to the {@code char} - * value. This reproduces the effect of {@code array[index] = value}. - * - * @param array - * the array - * @param index - * the index - * @param value - * the new value - * - * @throws NullPointerException - * if the {@code array} is {@code null} - * @throws IllegalArgumentException - * if the {@code array} is not an array or the value cannot be - * converted to the array type by a widening conversion - * @throws ArrayIndexOutOfBoundsException - * if {@code index < 0 || index >= array.length} - */ - public static void setChar(Object array, int index, char value) - throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - if (array instanceof char[]) { - ((char[]) array)[index] = value; - } else if (array == null) { - throw new NullPointerException(); - } else if (!array.getClass().isArray()) { - throw new IllegalArgumentException("Not an array"); - } else { - throw new IllegalArgumentException("Wrong array type"); - } - } - - /** - * Set the element of the array at the specified index to the {@code double} - * value. This reproduces the effect of {@code array[index] = value}. - * - * @param array - * the array - * @param index - * the index - * @param value - * the new value - * - * @throws NullPointerException - * if the {@code array} is {@code null} - * @throws IllegalArgumentException - * if the {@code array} is not an array or the value cannot be - * converted to the array type by a widening conversion - * @throws ArrayIndexOutOfBoundsException - * if {@code index < 0 || index >= array.length} - */ - public static void setDouble(Object array, int index, double value) - throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - if (array instanceof double[]) { - ((double[]) array)[index] = value; - } else if (array == null) { - throw new NullPointerException(); - } else if (!array.getClass().isArray()) { - throw new IllegalArgumentException("Not an array"); - } else { - throw new IllegalArgumentException("Wrong array type"); - } - } - - /** - * Set the element of the array at the specified index to the {@code float} - * value. This reproduces the effect of {@code array[index] = value}. - * - * @param array - * the array - * @param index - * the index - * @param value - * the new value - * - * @throws NullPointerException - * if the {@code array} is {@code null} - * @throws IllegalArgumentException - * if the {@code array} is not an array or the value cannot be - * converted to the array type by a widening conversion - * @throws ArrayIndexOutOfBoundsException - * if {@code index < 0 || index >= array.length} - */ - public static void setFloat(Object array, int index, float value) - throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - if (array instanceof float[]) { - ((float[]) array)[index] = value; - } else { - setDouble(array, index, value); - } - } - - /** - * Set the element of the array at the specified index to the {@code int} - * value. This reproduces the effect of {@code array[index] = value}. - * - * @param array - * the array - * @param index - * the index - * @param value - * the new value - * - * @throws NullPointerException - * if the {@code array} is {@code null} - * @throws IllegalArgumentException - * if the {@code array} is not an array or the value cannot be - * converted to the array type by a widening conversion - * @throws ArrayIndexOutOfBoundsException - * if {@code index < 0 || index >= array.length} - */ - public static void setInt(Object array, int index, int value) - throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - if (array instanceof int[]) { - ((int[]) array)[index] = value; - } else { - setLong(array, index, value); - } - } - - /** - * Set the element of the array at the specified index to the {@code long} - * value. This reproduces the effect of {@code array[index] = value}. - * - * @param array - * the array - * @param index - * the index - * @param value - * the new value - * - * @throws NullPointerException - * if the {@code array} is {@code null} - * @throws IllegalArgumentException - * if the {@code array} is not an array or the value cannot be - * converted to the array type by a widening conversion - * @throws ArrayIndexOutOfBoundsException - * if {@code index < 0 || index >= array.length} - */ - public static void setLong(Object array, int index, long value) - throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - if (array instanceof long[]) { - ((long[]) array)[index] = value; - } else { - setFloat(array, index, value); - } - } - - /** - * Set the element of the array at the specified index to the {@code short} - * value. This reproduces the effect of {@code array[index] = value}. - * - * @param array - * the array - * @param index - * the index - * @param value - * the new value - * - * @throws NullPointerException - * if the {@code array} is {@code null} - * @throws IllegalArgumentException - * if the {@code array} is not an array or the value cannot be - * converted to the array type by a widening conversion - * @throws ArrayIndexOutOfBoundsException - * if {@code index < 0 || index >= array.length} - */ - public static void setShort(Object array, int index, short value) - throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - if (array instanceof short[]) { - ((short[]) array)[index] = value; - } else { - setInt(array, index, value); - } - } - -} diff --git a/luni-kernel/src/main/java/java/lang/reflect/Constructor.java b/luni-kernel/src/main/java/java/lang/reflect/Constructor.java deleted file mode 100644 index 784f273..0000000 --- a/luni-kernel/src/main/java/java/lang/reflect/Constructor.java +++ /dev/null @@ -1,460 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang.reflect; - -import dalvik.system.VMStack; - -import java.lang.annotation.Annotation; - -import org.apache.harmony.kernel.vm.StringUtils; -import org.apache.harmony.luni.lang.reflect.GenericSignatureParser; -import org.apache.harmony.luni.lang.reflect.ListOfTypes; -import org.apache.harmony.luni.lang.reflect.Types; - -/** - * This class represents a constructor. Information about the constructor can be - * accessed, and the constructor can be invoked dynamically. - * - * @param <T> the class that declares this constructor - */ -public final class Constructor<T> extends AccessibleObject implements GenericDeclaration, - Member { - - Class<T> declaringClass; - - Class<?>[] parameterTypes; - - Class<?>[] exceptionTypes; - - ListOfTypes genericExceptionTypes; - ListOfTypes genericParameterTypes; - TypeVariable<Constructor<T>>[] formalTypeParameters; - private volatile boolean genericTypesAreInitialized = false; - - private synchronized void initGenericTypes() { - if (!genericTypesAreInitialized) { - String signatureAttribute = getSignatureAttribute(); - GenericSignatureParser parser = new GenericSignatureParser( - VMStack.getCallingClassLoader2()); - parser.parseForConstructor(this, signatureAttribute); - formalTypeParameters = parser.formalTypeParameters; - genericParameterTypes = parser.parameterTypes; - genericExceptionTypes = parser.exceptionTypes; - genericTypesAreInitialized = true; - } - } - - int slot; - - /** - * Prevent this class from being instantiated. - */ - private Constructor(){ - //do nothing - } - - /** - * Creates an instance of the class. Only called from native code, thus - * private. - * - * @param declaringClass - * the class this constructor object belongs to - * @param ptypes - * the parameter types of the constructor - * @param extypes - * the exception types of the constructor - * @param slot - * the slot of the constructor inside the VM class structure - */ - private Constructor (Class<T> declaringClass, Class<?>[] ptypes, Class<?>[] extypes, int slot){ - this.declaringClass = declaringClass; - this.parameterTypes = ptypes; - this.exceptionTypes = extypes; // may be null - this.slot = slot; - } - - @Override /*package*/ String getSignatureAttribute() { - Object[] annotation = getSignatureAnnotation(declaringClass, slot); - - if (annotation == null) { - return null; - } - - return StringUtils.combineStrings(annotation); - } - - /** - * Get the Signature annotation for this constructor. Returns null if not - * found. - */ - native private Object[] getSignatureAnnotation(Class declaringClass, - int slot); - - public TypeVariable<Constructor<T>>[] getTypeParameters() { - initGenericTypes(); - return formalTypeParameters.clone(); - } - - /** - * Returns the string representation of the constructor's declaration, - * including the type parameters. - * - * @return the string representation of the constructor's declaration - */ - public String toGenericString() { - StringBuilder sb = new StringBuilder(80); - initGenericTypes(); - // append modifiers if any - int modifier = getModifiers(); - if (modifier != 0) { - sb.append(Modifier.toString(modifier & ~Modifier.VARARGS)).append(' '); - } - // append type parameters - if (formalTypeParameters != null && formalTypeParameters.length > 0) { - sb.append('<'); - for (int i = 0; i < formalTypeParameters.length; i++) { - appendGenericType(sb, formalTypeParameters[i]); - if (i < formalTypeParameters.length - 1) { - sb.append(", "); - } - } - sb.append("> "); - } - // append constructor name - appendArrayType(sb, getDeclaringClass()); - // append parameters - sb.append('('); - appendArrayGenericType(sb, - Types.getClonedTypeArray(genericParameterTypes)); - sb.append(')'); - // append exceptions if any - Type[] genericExceptionTypeArray = - Types.getClonedTypeArray(genericExceptionTypes); - if (genericExceptionTypeArray.length > 0) { - sb.append(" throws "); - appendArrayGenericType(sb, genericExceptionTypeArray); - } - return sb.toString(); - } - - /** - * Returns the generic parameter types as an array of {@code Type} - * instances, in declaration order. If this constructor has no generic - * parameters, an empty array is returned. - * - * @return the parameter types - * - * @throws GenericSignatureFormatError - * if the generic constructor signature is invalid - * @throws TypeNotPresentException - * if any parameter type points to a missing type - * @throws MalformedParameterizedTypeException - * if any parameter type points to a type that cannot be - * instantiated for some reason - */ - public Type[] getGenericParameterTypes() { - initGenericTypes(); - return Types.getClonedTypeArray(genericParameterTypes); - } - - /** - * Returns the exception types as an array of {@code Type} instances. If - * this constructor has no declared exceptions, an empty array will be - * returned. - * - * @return an array of generic exception types - * - * @throws GenericSignatureFormatError - * if the generic constructor signature is invalid - * @throws TypeNotPresentException - * if any exception type points to a missing type - * @throws MalformedParameterizedTypeException - * if any exception type points to a type that cannot be - * instantiated for some reason - */ - public Type[] getGenericExceptionTypes() { - initGenericTypes(); - return Types.getClonedTypeArray(genericExceptionTypes); - } - - @Override - public Annotation[] getDeclaredAnnotations() { - return getDeclaredAnnotations(declaringClass, slot); - } - native private Annotation[] getDeclaredAnnotations(Class declaringClass, - int slot); - - /** - * Returns an array of arrays that represent the annotations of the formal - * parameters of this constructor. If there are no parameters on this - * constructor, then an empty array is returned. If there are no annotations - * set, then an array of empty arrays is returned. - * - * @return an array of arrays of {@code Annotation} instances - */ - public Annotation[][] getParameterAnnotations() { - Annotation[][] parameterAnnotations - = getParameterAnnotations(declaringClass, slot); - if (parameterAnnotations.length == 0) { - return Method.noAnnotations(parameterTypes.length); - } - return parameterAnnotations; - } - native private Annotation[][] getParameterAnnotations(Class declaringClass, - int slot); - - /** - * Indicates whether or not this constructor takes a variable number of - * arguments. - * - * @return {@code true} if a vararg is declare, otherwise - * {@code false} - */ - public boolean isVarArgs() { - int mods = getConstructorModifiers(declaringClass, slot); - return (mods & Modifier.VARARGS) != 0; - } - - /** - * Indicates whether or not this constructor is synthetic (artificially - * introduced by the compiler). - * - * @return {@code true} if this constructor is synthetic, {@code false} - * otherwise - */ - public boolean isSynthetic() { - int mods = getConstructorModifiers(declaringClass, slot); - return (mods & Modifier.SYNTHETIC) != 0; - } - - /** - * Indicates whether or not the specified {@code object} is equal to this - * constructor. To be equal, the specified object must be an instance - * of {@code Constructor} with the same declaring class and parameter types - * as this constructor. - * - * @param object - * the object to compare - * - * @return {@code true} if the specified object is equal to this - * constructor, {@code false} otherwise - * - * @see #hashCode - */ - @Override - public boolean equals(Object object) { - return object instanceof Constructor && toString().equals(object.toString()); - } - - /** - * Returns the class that declares this constructor. - * - * @return the declaring class - */ - public Class<T> getDeclaringClass() { - return declaringClass; - } - - /** - * Returns the exception types as an array of {@code Class} instances. If - * this constructor has no declared exceptions, an empty array will be - * returned. - * - * @return the declared exception classes - */ - public Class<?>[] getExceptionTypes() { - if (exceptionTypes == null) - return new Class[0]; - return exceptionTypes.clone(); - } - - /** - * Returns the modifiers for this constructor. The {@link Modifier} class - * should be used to decode the result. - * - * @return the modifiers for this constructor - * - * @see Modifier - */ - public int getModifiers() { - return getConstructorModifiers(declaringClass, slot); - } - - private native int getConstructorModifiers(Class<T> declaringClass, int slot); - - /** - * Returns the name of this constructor. - * - * @return the name of this constructor - */ - public String getName() { - return declaringClass.getName(); - } - - /** - * Returns an array of the {@code Class} objects associated with the - * parameter types of this constructor. If the constructor was declared with - * no parameters, an empty array will be returned. - * - * @return the parameter types - */ - public Class<?>[] getParameterTypes() { - return parameterTypes.clone(); - } - - /** - * Returns the constructor's signature in non-printable form. This is called - * (only) from IO native code and needed for deriving the serialVersionUID - * of the class - * - * @return the constructor's signature - */ - @SuppressWarnings("unused") - private String getSignature() { - StringBuilder result = new StringBuilder(); - - result.append('('); - for(int i = 0; i < parameterTypes.length; i++) { - result.append(getSignature(parameterTypes[i])); - } - result.append(")V"); - - return result.toString(); - } - - /** - * Returns an integer hash code for this constructor. Constructors which are - * equal return the same value for this method. The hash code for a - * Constructor is the hash code of the name of the declaring class. - * - * @return the hash code - * - * @see #equals - */ - @Override - public int hashCode() { - return declaringClass.getName().hashCode(); - } - - /** - * Returns a new instance of the declaring class, initialized by dynamically - * invoking the constructor represented by this {@code Constructor} object. - * This reproduces the effect of {@code new declaringClass(arg1, arg2, ... , - * argN)} This method performs the following: - * <ul> - * <li>A new instance of the declaring class is created. If the declaring - * class cannot be instantiated (i.e. abstract class, an interface, an array - * type, or a primitive type) then an InstantiationException is thrown.</li> - * <li>If this Constructor object is enforcing access control (see - * {@link AccessibleObject}) and this constructor is not accessible from the - * current context, an IllegalAccessException is thrown.</li> - * <li>If the number of arguments passed and the number of parameters do not - * match, an IllegalArgumentException is thrown.</li> - * <li>For each argument passed: - * <ul> - * <li>If the corresponding parameter type is a primitive type, the argument - * is unwrapped. If the unwrapping fails, an IllegalArgumentException is - * thrown.</li> - * <li>If the resulting argument cannot be converted to the parameter type - * via a widening conversion, an IllegalArgumentException is thrown.</li> - * </ul> - * <li>The constructor represented by this {@code Constructor} object is - * then invoked. If an exception is thrown during the invocation, it is - * caught and wrapped in an InvocationTargetException. This exception is - * then thrown. If the invocation completes normally, the newly initialized - * object is returned. - * </ul> - * - * @param args - * the arguments to the constructor - * - * @return the new, initialized, object - * - * @exception InstantiationException - * if the class cannot be instantiated - * @exception IllegalAccessException - * if this constructor is not accessible - * @exception IllegalArgumentException - * if an incorrect number of arguments are passed, or an - * argument could not be converted by a widening conversion - * @exception InvocationTargetException - * if an exception was thrown by the invoked constructor - * - * @see AccessibleObject - */ - public T newInstance(Object... args) throws InstantiationException, IllegalAccessException, - IllegalArgumentException, InvocationTargetException { - return constructNative (args, declaringClass, parameterTypes, slot, flag); - } - - private native T constructNative(Object[] args, Class<T> declaringClass, - Class<?>[] parameterTypes, int slot, - boolean noAccessCheck) throws InstantiationException, IllegalAccessException, - InvocationTargetException; - - /** - * Returns a string containing a concise, human-readable description of this - * constructor. The format of the string is: - * - * <ol> - * <li>modifiers (if any) - * <li>declaring class name - * <li>'(' - * <li>parameter types, separated by ',' (if any) - * <li>')' - * <li>'throws' plus exception types, separated by ',' (if any) - * </ol> - * - * For example: - * {@code public String(byte[],String) throws UnsupportedEncodingException} - * - * @return a printable representation for this constructor - */ - @Override - public String toString() { - StringBuilder result = new StringBuilder(Modifier.toString(getModifiers())); - - if (result.length() != 0) - result.append(' '); - result.append(declaringClass.getName()); - result.append("("); - result.append(toString(parameterTypes)); - result.append(")"); - if (exceptionTypes != null && exceptionTypes.length != 0) { - result.append(" throws "); - result.append(toString(exceptionTypes)); - } - - return result.toString(); - } -} diff --git a/luni-kernel/src/main/java/java/lang/reflect/Field.java b/luni-kernel/src/main/java/java/lang/reflect/Field.java deleted file mode 100644 index baaafdd..0000000 --- a/luni-kernel/src/main/java/java/lang/reflect/Field.java +++ /dev/null @@ -1,907 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang.reflect; - -import dalvik.system.VMStack; - -import java.lang.annotation.Annotation; - -import org.apache.harmony.luni.lang.reflect.GenericSignatureParser; -import org.apache.harmony.luni.lang.reflect.Types; -import org.apache.harmony.kernel.vm.StringUtils; - -/** - * This class represents a field. Information about the field can be accessed, - * and the field's value can be accessed dynamically. - */ -public final class Field extends AccessibleObject implements Member { - - private Class<?> declaringClass; - - private Class<?> type; - - private Type genericType; - - private volatile boolean genericTypesAreInitialized = false; - - private String name; - - private int slot; - - private static final int TYPE_BOOLEAN = 1; - - private static final int TYPE_BYTE = 2; - - private static final int TYPE_CHAR = 3; - - private static final int TYPE_SHORT = 4; - - private static final int TYPE_INTEGER = 5; - - private static final int TYPE_FLOAT = 6; - - private static final int TYPE_LONG = 7; - - private static final int TYPE_DOUBLE = 8; - - /** - * Construct a clone of the given instance. - * - * @param orig non-null; the original instance to clone - */ - /*package*/ Field(Field orig) { - this(orig.declaringClass, orig.type, orig.name, orig.slot); - - // Copy the accessible flag. - if (orig.flag) { - this.flag = true; - } - } - - private Field(Class<?> declaringClass, Class<?> type, String name, int slot) { - this.declaringClass = declaringClass; - this.type = type; - this.name = name; - this.slot = slot; - } - - private synchronized void initGenericType() { - if (!genericTypesAreInitialized) { - String signatureAttribute = getSignatureAttribute(); - GenericSignatureParser parser = new GenericSignatureParser( - VMStack.getCallingClassLoader2()); - parser.parseForField(this.declaringClass, signatureAttribute); - genericType = parser.fieldType; - if (genericType == null) { - genericType = getType(); - } - genericTypesAreInitialized = true; - } - } - - /** {@inheritDoc} */ - @Override - /* package */String getSignatureAttribute() { - Object[] annotation = getSignatureAnnotation(declaringClass, slot); - - if (annotation == null) { - return null; - } - - return StringUtils.combineStrings(annotation); - } - - /** - * Get the Signature annotation for this field. Returns null if not found. - */ - native private Object[] getSignatureAnnotation(Class declaringClass, int slot); - - /** - * Indicates whether or not this field is synthetic. - * - * @return {@code true} if this field is synthetic, {@code false} otherwise - */ - public boolean isSynthetic() { - int flags = getFieldModifiers(declaringClass, slot); - return (flags & Modifier.SYNTHETIC) != 0; - } - - /** - * Returns the string representation of this field, including the field's - * generic type. - * - * @return the string representation of this field - */ - public String toGenericString() { - StringBuilder sb = new StringBuilder(80); - // append modifiers if any - int modifier = getModifiers(); - if (modifier != 0) { - sb.append(Modifier.toString(modifier)).append(' '); - } - // append generic type - appendGenericType(sb, getGenericType()); - sb.append(' '); - // append full field name - sb.append(getDeclaringClass().getName()).append('.').append(getName()); - return sb.toString(); - } - - /** - * Indicates whether or not this field is an enumeration constant. - * - * @return {@code true} if this field is an enumeration constant, {@code - * false} otherwise - */ - public boolean isEnumConstant() { - int flags = getFieldModifiers(declaringClass, slot); - return (flags & Modifier.ENUM) != 0; - } - - /** - * Returns the generic type of this field. - * - * @return the generic type - * @throws GenericSignatureFormatError - * if the generic field signature is invalid - * @throws TypeNotPresentException - * if the generic type points to a missing type - * @throws MalformedParameterizedTypeException - * if the generic type points to a type that cannot be - * instantiated for some reason - */ - public Type getGenericType() { - initGenericType(); - return Types.getType(genericType); - } - - @Override - public Annotation[] getDeclaredAnnotations() { - return getDeclaredAnnotations(declaringClass, slot); - } - - native private Annotation[] getDeclaredAnnotations(Class declaringClass, int slot); - - /** - * Indicates whether or not the specified {@code object} is equal to this - * field. To be equal, the specified object must be an instance of - * {@code Field} with the same declaring class, type and name as this field. - * - * @param object - * the object to compare - * @return {@code true} if the specified object is equal to this method, - * {@code false} otherwise - * @see #hashCode - */ - @Override - public boolean equals(Object object) { - return object instanceof Field && toString().equals(object.toString()); - } - - /** - * Returns the value of the field in the specified object. This reproduces - * the effect of {@code object.fieldName} - * <p> - * If the type of this field is a primitive type, the field value is - * automatically wrapped. - * <p> - * If this field is static, the object argument is ignored. - * Otherwise, if the object is null, a NullPointerException is thrown. If - * the object is not an instance of the declaring class of the method, an - * IllegalArgumentException is thrown. - * <p> - * If this Field object is enforcing access control (see AccessibleObject) - * and this field is not accessible from the current context, an - * IllegalAccessException is thrown. - * <p> - * - * @param object - * the object to access - * @return the field value, possibly wrapped - * @throws NullPointerException - * if the object is {@code null} and the field is non-static - * @throws IllegalArgumentException - * if the object is not compatible with the declaring class - * @throws IllegalAccessException - * if this field is not accessible - */ - public Object get(Object object) throws IllegalAccessException, IllegalArgumentException { - return getField(object, declaringClass, type, slot, flag); - } - - /** - * Returns the value of the field in the specified object as a {@code - * boolean}. This reproduces the effect of {@code object.fieldName} - * <p> - * If this field is static, the object argument is ignored. - * Otherwise, if the object is {@code null}, a NullPointerException is - * thrown. If the object is not an instance of the declaring class of the - * method, an IllegalArgumentException is thrown. - * <p> - * If this Field object is enforcing access control (see AccessibleObject) - * and this field is not accessible from the current context, an - * IllegalAccessException is thrown. - * - * @param object - * the object to access - * @return the field value - * @throws NullPointerException - * if the object is {@code null} and the field is non-static - * @throws IllegalArgumentException - * if the object is not compatible with the declaring class - * @throws IllegalAccessException - * if this field is not accessible - */ - public boolean getBoolean(Object object) throws IllegalAccessException, - IllegalArgumentException { - return getZField(object, declaringClass, type, slot, flag, TYPE_BOOLEAN); - } - - /** - * Returns the value of the field in the specified object as a {@code byte}. - * This reproduces the effect of {@code object.fieldName} - * <p> - * If this field is static, the object argument is ignored. - * Otherwise, if the object is {@code null}, a NullPointerException is - * thrown. If the object is not an instance of the declaring class of the - * method, an IllegalArgumentException is thrown. - * <p> - * If this Field object is enforcing access control (see AccessibleObject) - * and this field is not accessible from the current context, an - * IllegalAccessException is thrown. - * - * @param object - * the object to access - * @return the field value - * @throws NullPointerException - * if the object is {@code null} and the field is non-static - * @throws IllegalArgumentException - * if the object is not compatible with the declaring class - * @throws IllegalAccessException - * if this field is not accessible - */ - public byte getByte(Object object) throws IllegalAccessException, IllegalArgumentException { - return getBField(object, declaringClass, type, slot, flag, TYPE_BYTE); - } - - /** - * Returns the value of the field in the specified object as a {@code char}. - * This reproduces the effect of {@code object.fieldName} - * <p> - * If this field is static, the object argument is ignored. - * Otherwise, if the object is {@code null}, a NullPointerException is - * thrown. If the object is not an instance of the declaring class of the - * method, an IllegalArgumentException is thrown. - * <p> - * If this Field object is enforcing access control (see AccessibleObject) - * and this field is not accessible from the current context, an - * IllegalAccessException is thrown. - * - * @param object - * the object to access - * @return the field value - * @throws NullPointerException - * if the object is {@code null} and the field is non-static - * @throws IllegalArgumentException - * if the object is not compatible with the declaring class - * @throws IllegalAccessException - * if this field is not accessible - */ - public char getChar(Object object) throws IllegalAccessException, IllegalArgumentException { - return getCField(object, declaringClass, type, slot, flag, TYPE_CHAR); - } - - /** - * Returns the class that declares this field. - * - * @return the declaring class - */ - public Class<?> getDeclaringClass() { - return declaringClass; - } - - /** - * Returns the value of the field in the specified object as a {@code - * double}. This reproduces the effect of {@code object.fieldName} - * <p> - * If this field is static, the object argument is ignored. - * Otherwise, if the object is {@code null}, a NullPointerException is - * thrown. If the object is not an instance of the declaring class of the - * method, an IllegalArgumentException is thrown. - * <p> - * If this Field object is enforcing access control (see AccessibleObject) - * and this field is not accessible from the current context, an - * IllegalAccessException is thrown. - * - * @param object - * the object to access - * @return the field value - * @throws NullPointerException - * if the object is {@code null} and the field is non-static - * @throws IllegalArgumentException - * if the object is not compatible with the declaring class - * @throws IllegalAccessException - * if this field is not accessible - */ - public double getDouble(Object object) throws IllegalAccessException, IllegalArgumentException { - return getDField(object, declaringClass, type, slot, flag, TYPE_DOUBLE); - } - - /** - * Returns the value of the field in the specified object as a {@code float} - * . This reproduces the effect of {@code object.fieldName} - * <p> - * If this field is static, the object argument is ignored. - * Otherwise, if the object is {@code null}, a NullPointerException is - * thrown. If the object is not an instance of the declaring class of the - * method, an IllegalArgumentException is thrown. - * <p> - * If this Field object is enforcing access control (see AccessibleObject) - * and this field is not accessible from the current context, an - * IllegalAccessException is thrown. - * - * @param object - * the object to access - * @return the field value - * @throws NullPointerException - * if the object is {@code null} and the field is non-static - * @throws IllegalArgumentException - * if the object is not compatible with the declaring class - * @throws IllegalAccessException - * if this field is not accessible - */ - public float getFloat(Object object) throws IllegalAccessException, IllegalArgumentException { - return getFField(object, declaringClass, type, slot, flag, TYPE_FLOAT); - } - - /** - * Returns the value of the field in the specified object as an {@code int}. - * This reproduces the effect of {@code object.fieldName} - * <p> - * If this field is static, the object argument is ignored. - * Otherwise, if the object is {@code null}, a NullPointerException is - * thrown. If the object is not an instance of the declaring class of the - * method, an IllegalArgumentException is thrown. - * <p> - * If this Field object is enforcing access control (see AccessibleObject) - * and this field is not accessible from the current context, an - * IllegalAccessException is thrown. - * - * @param object - * the object to access - * @return the field value - * @throws NullPointerException - * if the object is {@code null} and the field is non-static - * @throws IllegalArgumentException - * if the object is not compatible with the declaring class - * @throws IllegalAccessException - * if this field is not accessible - */ - public int getInt(Object object) throws IllegalAccessException, IllegalArgumentException { - return getIField(object, declaringClass, type, slot, flag, TYPE_INTEGER); - } - - /** - * Returns the value of the field in the specified object as a {@code long}. - * This reproduces the effect of {@code object.fieldName} - * <p> - * If this field is static, the object argument is ignored. - * Otherwise, if the object is {@code null}, a NullPointerException is - * thrown. If the object is not an instance of the declaring class of the - * method, an IllegalArgumentException is thrown. - * <p> - * If this Field object is enforcing access control (see AccessibleObject) - * and this field is not accessible from the current context, an - * IllegalAccessException is thrown. - * - * @param object - * the object to access - * @return the field value - * @throws NullPointerException - * if the object is {@code null} and the field is non-static - * @throws IllegalArgumentException - * if the object is not compatible with the declaring class - * @throws IllegalAccessException - * if this field is not accessible - */ - public long getLong(Object object) throws IllegalAccessException, IllegalArgumentException { - return getJField(object, declaringClass, type, slot, flag, TYPE_LONG); - } - - /** - * Returns the modifiers for this field. The {@link Modifier} class should - * be used to decode the result. - * - * @return the modifiers for this field - * @see Modifier - */ - public int getModifiers() { - return getFieldModifiers(declaringClass, slot); - } - - private native int getFieldModifiers(Class<?> declaringClass, int slot); - - /** - * Returns the name of this field. - * - * @return the name of this field - */ - public String getName() { - return name; - } - - /** - * Returns the value of the field in the specified object as a {@code short} - * . This reproduces the effect of {@code object.fieldName} - * <p> - * If this field is static, the object argument is ignored. - * Otherwise, if the object is {@code null}, a NullPointerException is - * thrown. If the object is not an instance of the declaring class of the - * method, an IllegalArgumentException is thrown. - * <p> - * If this Field object is enforcing access control (see AccessibleObject) - * and this field is not accessible from the current context, an - * IllegalAccessException is thrown. - * - * @param object - * the object to access - * @return the field value - * @throws NullPointerException - * if the object is {@code null} and the field is non-static - * @throws IllegalArgumentException - * if the object is not compatible with the declaring class - * @throws IllegalAccessException - * if this field is not accessible - */ - public short getShort(Object object) throws IllegalAccessException, IllegalArgumentException { - return getSField(object, declaringClass, type, slot, flag, TYPE_SHORT); - } - - /** - * Returns the constructor's signature in non-printable form. This is called - * (only) from IO native code and needed for deriving the serialVersionUID - * of the class - * - * @return the constructor's signature. - */ - @SuppressWarnings("unused") - private String getSignature() { - return getSignature(type); - } - - /** - * Return the {@link Class} associated with the type of this field. - * - * @return the type of this field - */ - public Class<?> getType() { - return type; - } - - /** - * Returns an integer hash code for this field. Objects which are equal - * return the same value for this method. - * <p> - * The hash code for a Field is the exclusive-or combination of the hash - * code of the field's name and the hash code of the name of its declaring - * class. - * - * @return the hash code for this field - * @see #equals - */ - @Override - public int hashCode() { - // BEGIN android-changed - return name.hashCode() ^ getDeclaringClass().getName().hashCode(); - // END android-changed - } - - /** - * Sets the value of the field in the specified object to the value. This - * reproduces the effect of {@code object.fieldName = value} - * <p> - * If this field is static, the object argument is ignored. - * Otherwise, if the object is {@code null}, a NullPointerException is - * thrown. If the object is not an instance of the declaring class of the - * method, an IllegalArgumentException is thrown. - * <p> - * If this Field object is enforcing access control (see AccessibleObject) - * and this field is not accessible from the current context, an - * IllegalAccessException is thrown. - * <p> - * If the field type is a primitive type, the value is automatically - * unwrapped. If the unwrap fails, an IllegalArgumentException is thrown. If - * the value cannot be converted to the field type via a widening - * conversion, an IllegalArgumentException is thrown. - * - * @param object - * the object to access - * @param value - * the new value - * @throws NullPointerException - * if the object is {@code null} and the field is non-static - * @throws IllegalArgumentException - * if the object is not compatible with the declaring class - * @throws IllegalAccessException - * if this field is not accessible - */ - public void set(Object object, Object value) throws IllegalAccessException, - IllegalArgumentException { - setField(object, declaringClass, type, slot, flag, value); - } - - /** - * Sets the value of the field in the specified object to the {@code - * boolean} value. This reproduces the effect of {@code object.fieldName = - * value} - * <p> - * If this field is static, the object argument is ignored. - * Otherwise, if the object is {@code null}, a NullPointerException is - * thrown. If the object is not an instance of the declaring class of the - * method, an IllegalArgumentException is thrown. - * <p> - * If this Field object is enforcing access control (see AccessibleObject) - * and this field is not accessible from the current context, an - * IllegalAccessException is thrown. - * <p> - * If the value cannot be converted to the field type via a widening - * conversion, an IllegalArgumentException is thrown. - * - * @param object - * the object to access - * @param value - * the new value - * @throws NullPointerException - * if the object is {@code null} and the field is non-static - * @throws IllegalArgumentException - * if the object is not compatible with the declaring class - * @throws IllegalAccessException - * if this field is not accessible - */ - public void setBoolean(Object object, boolean value) throws IllegalAccessException, - IllegalArgumentException { - setZField(object, declaringClass, type, slot, flag, TYPE_BOOLEAN, value); - } - - /** - * Sets the value of the field in the specified object to the {@code byte} - * value. This reproduces the effect of {@code object.fieldName = value} - * <p> - * If this field is static, the object argument is ignored. - * Otherwise, if the object is {@code null}, a NullPointerException is - * thrown. If the object is not an instance of the declaring class of the - * method, an IllegalArgumentException is thrown. - * <p> - * If this Field object is enforcing access control (see AccessibleObject) - * and this field is not accessible from the current context, an - * IllegalAccessException is thrown. - * <p> - * If the value cannot be converted to the field type via a widening - * conversion, an IllegalArgumentException is thrown. - * - * @param object - * the object to access - * @param value - * the new value - * @throws NullPointerException - * if the object is {@code null} and the field is non-static - * @throws IllegalArgumentException - * if the object is not compatible with the declaring class - * @throws IllegalAccessException - * if this field is not accessible - */ - public void setByte(Object object, byte value) throws IllegalAccessException, - IllegalArgumentException { - setBField(object, declaringClass, type, slot, flag, TYPE_BYTE, value); - } - - /** - * Sets the value of the field in the specified object to the {@code char} - * value. This reproduces the effect of {@code object.fieldName = value} - * <p> - * If this field is static, the object argument is ignored. - * Otherwise, if the object is {@code null}, a NullPointerException is - * thrown. If the object is not an instance of the declaring class of the - * method, an IllegalArgumentException is thrown. - * <p> - * If this Field object is enforcing access control (see AccessibleObject) - * and this field is not accessible from the current context, an - * IllegalAccessException is thrown. - * <p> - * If the value cannot be converted to the field type via a widening - * conversion, an IllegalArgumentException is thrown. - * - * @param object - * the object to access - * @param value - * the new value - * @throws NullPointerException - * if the object is {@code null} and the field is non-static - * @throws IllegalArgumentException - * if the object is not compatible with the declaring class - * @throws IllegalAccessException - * if this field is not accessible - */ - public void setChar(Object object, char value) throws IllegalAccessException, - IllegalArgumentException { - setCField(object, declaringClass, type, slot, flag, TYPE_CHAR, value); - } - - /** - * Sets the value of the field in the specified object to the {@code double} - * value. This reproduces the effect of {@code object.fieldName = value} - * <p> - * If this field is static, the object argument is ignored. - * Otherwise, if the object is {@code null}, a NullPointerException is - * thrown. If the object is not an instance of the declaring class of the - * method, an IllegalArgumentException is thrown. - * <p> - * If this Field object is enforcing access control (see AccessibleObject) - * and this field is not accessible from the current context, an - * IllegalAccessException is thrown. - * <p> - * If the value cannot be converted to the field type via a widening - * conversion, an IllegalArgumentException is thrown. - * - * @param object - * the object to access - * @param value - * the new value - * @throws NullPointerException - * if the object is {@code null} and the field is non-static - * @throws IllegalArgumentException - * if the object is not compatible with the declaring class - * @throws IllegalAccessException - * if this field is not accessible - */ - public void setDouble(Object object, double value) throws IllegalAccessException, - IllegalArgumentException { - setDField(object, declaringClass, type, slot, flag, TYPE_DOUBLE, value); - } - - /** - * Sets the value of the field in the specified object to the {@code float} - * value. This reproduces the effect of {@code object.fieldName = value} - * <p> - * If this field is static, the object argument is ignored. - * Otherwise, if the object is {@code null}, a NullPointerException is - * thrown. If the object is not an instance of the declaring class of the - * method, an IllegalArgumentException is thrown. - * <p> - * If this Field object is enforcing access control (see AccessibleObject) - * and this field is not accessible from the current context, an - * IllegalAccessException is thrown. - * <p> - * If the value cannot be converted to the field type via a widening - * conversion, an IllegalArgumentException is thrown. - * - * @param object - * the object to access - * @param value - * the new value - * @throws NullPointerException - * if the object is {@code null} and the field is non-static - * @throws IllegalArgumentException - * if the object is not compatible with the declaring class - * @throws IllegalAccessException - * if this field is not accessible - */ - public void setFloat(Object object, float value) throws IllegalAccessException, - IllegalArgumentException { - setFField(object, declaringClass, type, slot, flag, TYPE_FLOAT, value); - } - - /** - * Set the value of the field in the specified object to the {@code int} - * value. This reproduces the effect of {@code object.fieldName = value} - * <p> - * If this field is static, the object argument is ignored. - * Otherwise, if the object is {@code null}, a NullPointerException is - * thrown. If the object is not an instance of the declaring class of the - * method, an IllegalArgumentException is thrown. - * <p> - * If this Field object is enforcing access control (see AccessibleObject) - * and this field is not accessible from the current context, an - * IllegalAccessException is thrown. - * <p> - * If the value cannot be converted to the field type via a widening - * conversion, an IllegalArgumentException is thrown. - * - * @param object - * the object to access - * @param value - * the new value - * @throws NullPointerException - * if the object is {@code null} and the field is non-static - * @throws IllegalArgumentException - * if the object is not compatible with the declaring class - * @throws IllegalAccessException - * if this field is not accessible - */ - public void setInt(Object object, int value) throws IllegalAccessException, - IllegalArgumentException { - setIField(object, declaringClass, type, slot, flag, TYPE_INTEGER, value); - } - - /** - * Sets the value of the field in the specified object to the {@code long} - * value. This reproduces the effect of {@code object.fieldName = value} - * <p> - * If this field is static, the object argument is ignored. - * Otherwise, if the object is {@code null}, a NullPointerException is - * thrown. If the object is not an instance of the declaring class of the - * method, an IllegalArgumentException is thrown. - * <p> - * If this Field object is enforcing access control (see AccessibleObject) - * and this field is not accessible from the current context, an - * IllegalAccessException is thrown. - * <p> - * If the value cannot be converted to the field type via a widening - * conversion, an IllegalArgumentException is thrown. - * - * @param object - * the object to access - * @param value - * the new value - * @throws NullPointerException - * if the object is {@code null} and the field is non-static - * @throws IllegalArgumentException - * if the object is not compatible with the declaring class - * @throws IllegalAccessException - * if this field is not accessible - */ - public void setLong(Object object, long value) throws IllegalAccessException, - IllegalArgumentException { - setJField(object, declaringClass, type, slot, flag, TYPE_LONG, value); - } - - /** - * Sets the value of the field in the specified object to the {@code short} - * value. This reproduces the effect of {@code object.fieldName = value} - * <p> - * If this field is static, the object argument is ignored. - * Otherwise, if the object is {@code null}, a NullPointerException is - * thrown. If the object is not an instance of the declaring class of the - * method, an IllegalArgumentException is thrown. - * <p> - * If this Field object is enforcing access control (see AccessibleObject) - * and this field is not accessible from the current context, an - * IllegalAccessException is thrown. - * <p> - * If the value cannot be converted to the field type via a widening - * conversion, an IllegalArgumentException is thrown. - * - * @param object - * the object to access - * @param value - * the new value - * @throws NullPointerException - * if the object is {@code null} and the field is non-static - * @throws IllegalArgumentException - * if the object is not compatible with the declaring class - * @throws IllegalAccessException - * if this field is not accessible - */ - public void setShort(Object object, short value) throws IllegalAccessException, - IllegalArgumentException { - setSField(object, declaringClass, type, slot, flag, TYPE_SHORT, value); - } - - /** - * Returns a string containing a concise, human-readable description of this - * field. - * <p> - * The format of the string is: - * <ol> - * <li>modifiers (if any) - * <li>type - * <li>declaring class name - * <li>'.' - * <li>field name - * </ol> - * <p> - * For example: {@code public static java.io.InputStream - * java.lang.System.in} - * - * @return a printable representation for this field - */ - @Override - public String toString() { - StringBuffer result = new StringBuffer(Modifier.toString(getModifiers())); - - if (result.length() != 0) - result.append(' '); - result.append(type.getName()); - result.append(' '); - result.append(declaringClass.getName()); - result.append('.'); - result.append(name); - - return result.toString(); - } - - private native Object getField(Object o, Class<?> declaringClass, Class<?> type, int slot, - boolean noAccessCheck) throws IllegalAccessException; - - private native double getDField(Object o, Class<?> declaringClass, Class<?> type, int slot, - boolean noAccessCheck, int type_no) throws IllegalAccessException; - - private native int getIField(Object o, Class<?> declaringClass, Class<?> type, int slot, - boolean noAccessCheck, int type_no) throws IllegalAccessException; - - private native long getJField(Object o, Class<?> declaringClass, Class<?> type, int slot, - boolean noAccessCheck, int type_no) throws IllegalAccessException; - - private native boolean getZField(Object o, Class<?> declaringClass, Class<?> type, int slot, - boolean noAccessCheck, int type_no) throws IllegalAccessException; - - private native float getFField(Object o, Class<?> declaringClass, Class<?> type, int slot, - boolean noAccessCheck, int type_no) throws IllegalAccessException; - - private native char getCField(Object o, Class<?> declaringClass, Class<?> type, int slot, - boolean noAccessCheck, int type_no) throws IllegalAccessException; - - private native short getSField(Object o, Class<?> declaringClass, Class<?> type, int slot, - boolean noAccessCheck, int type_no) throws IllegalAccessException; - - private native byte getBField(Object o, Class<?> declaringClass, Class<?> type, int slot, - boolean noAccessCheck, int type_no) throws IllegalAccessException; - - private native void setField(Object o, Class<?> declaringClass, Class<?> type, int slot, - boolean noAccessCheck, Object value) throws IllegalAccessException; - - private native void setDField(Object o, Class<?> declaringClass, Class<?> type, int slot, - boolean noAccessCheck, int type_no, double v) throws IllegalAccessException; - - private native void setIField(Object o, Class<?> declaringClass, Class<?> type, int slot, - boolean noAccessCheck, int type_no, int i) throws IllegalAccessException; - - private native void setJField(Object o, Class<?> declaringClass, Class<?> type, int slot, - boolean noAccessCheck, int type_no, long j) throws IllegalAccessException; - - private native void setZField(Object o, Class<?> declaringClass, Class<?> type, int slot, - boolean noAccessCheck, int type_no, boolean z) throws IllegalAccessException; - - private native void setFField(Object o, Class<?> declaringClass, Class<?> type, int slot, - boolean noAccessCheck, int type_no, float f) throws IllegalAccessException; - - private native void setCField(Object o, Class<?> declaringClass, Class<?> type, int slot, - boolean noAccessCheck, int type_no, char c) throws IllegalAccessException; - - private native void setSField(Object o, Class<?> declaringClass, Class<?> type, int slot, - boolean noAccessCheck, int type_no, short s) throws IllegalAccessException; - - private native void setBField(Object o, Class<?> declaringClass, Class<?> type, int slot, - boolean noAccessCheck, int type_no, byte b) throws IllegalAccessException; - -} diff --git a/luni-kernel/src/main/java/java/lang/reflect/Method.java b/luni-kernel/src/main/java/java/lang/reflect/Method.java deleted file mode 100644 index 6678f8c..0000000 --- a/luni-kernel/src/main/java/java/lang/reflect/Method.java +++ /dev/null @@ -1,555 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang.reflect; - -import dalvik.system.VMStack; - -import java.lang.annotation.Annotation; - -import org.apache.harmony.kernel.vm.StringUtils; -import org.apache.harmony.luni.lang.reflect.GenericSignatureParser; -import org.apache.harmony.luni.lang.reflect.ListOfTypes; -import org.apache.harmony.luni.lang.reflect.Types; - -/** - * This class represents a method. Information about the method can be accessed, - * and the method can be invoked dynamically. - */ -public final class Method extends AccessibleObject implements GenericDeclaration, Member { - - private int slot; - - private Class<?> declaringClass; - - private String name; - - private Class<?>[] parameterTypes; - - private Class<?>[] exceptionTypes; - - private Class<?> returnType; - - private ListOfTypes genericExceptionTypes; - private ListOfTypes genericParameterTypes; - private Type genericReturnType; - private TypeVariable<Method>[] formalTypeParameters; - private volatile boolean genericTypesAreInitialized = false; - - private synchronized void initGenericTypes() { - if (!genericTypesAreInitialized) { - String signatureAttribute = getSignatureAttribute(); - GenericSignatureParser parser = new GenericSignatureParser( - VMStack.getCallingClassLoader2()); - parser.parseForMethod(this, signatureAttribute); - formalTypeParameters = parser.formalTypeParameters; - genericParameterTypes = parser.parameterTypes; - genericExceptionTypes = parser.exceptionTypes; - genericReturnType = parser.returnType; - genericTypesAreInitialized = true; - } - } - - /** - * Construct a clone of the given instance. - * - * @param orig non-null; the original instance to clone - */ - /*package*/ Method(Method orig) { - this(orig.declaringClass, orig.parameterTypes, orig.exceptionTypes, - orig.returnType, orig.name, orig.slot); - - // Copy the accessible flag. - if (orig.flag) { - this.flag = true; - } - } - - private Method(Class<?> declaring, Class<?>[] paramTypes, Class<?>[] exceptTypes, Class<?> returnType, String name, int slot) - { - this.declaringClass = declaring; - this.name = name; - this.slot = slot; - this.parameterTypes = paramTypes; - this.exceptionTypes = exceptTypes; // may be null - this.returnType = returnType; - } - - public TypeVariable<Method>[] getTypeParameters() { - initGenericTypes(); - return formalTypeParameters.clone(); - } - - /** {@inheritDoc} */ - @Override /*package*/ String getSignatureAttribute() { - Object[] annotation = getSignatureAnnotation(declaringClass, slot); - - if (annotation == null) { - return null; - } - - return StringUtils.combineStrings(annotation); - } - - /** - * Returns the Signature annotation for this method. Returns {@code null} if - * not found. - */ - native private Object[] getSignatureAnnotation(Class declaringClass, - int slot); - - /** - * Returns the string representation of the method's declaration, including - * the type parameters. - * - * @return the string representation of this method - */ - public String toGenericString() { - StringBuilder sb = new StringBuilder(80); - - initGenericTypes(); - - // append modifiers if any - int modifier = getModifiers(); - if (modifier != 0) { - sb.append(Modifier.toString(modifier & ~(Modifier.BRIDGE + - Modifier.VARARGS))).append(' '); - } - // append type parameters - if (formalTypeParameters != null && formalTypeParameters.length > 0) { - sb.append('<'); - for (int i = 0; i < formalTypeParameters.length; i++) { - appendGenericType(sb, formalTypeParameters[i]); - if (i < formalTypeParameters.length - 1) { - sb.append(", "); - } - } - sb.append("> "); - } - // append return type - appendGenericType(sb, Types.getType(genericReturnType)); - sb.append(' '); - // append method name - appendArrayType(sb, getDeclaringClass()); - sb.append("."+getName()); - // append parameters - sb.append('('); - appendArrayGenericType(sb, - Types.getClonedTypeArray(genericParameterTypes)); - sb.append(')'); - // append exceptions if any - Type[] genericExceptionTypeArray = Types.getClonedTypeArray( - genericExceptionTypes); - if (genericExceptionTypeArray.length > 0) { - sb.append(" throws "); - appendArrayGenericType(sb, genericExceptionTypeArray); - } - return sb.toString(); - } - - /** - * Returns the parameter types as an array of {@code Type} instances, in - * declaration order. If this method has no parameters, an empty array is - * returned. - * - * @return the parameter types - * - * @throws GenericSignatureFormatError - * if the generic method signature is invalid - * @throws TypeNotPresentException - * if any parameter type points to a missing type - * @throws MalformedParameterizedTypeException - * if any parameter type points to a type that cannot be - * instantiated for some reason - */ - public Type[] getGenericParameterTypes() { - initGenericTypes(); - return Types.getClonedTypeArray(genericParameterTypes); - } - - /** - * Returns the exception types as an array of {@code Type} instances. If - * this method has no declared exceptions, an empty array will be returned. - * - * @return an array of generic exception types - * - * @throws GenericSignatureFormatError - * if the generic method signature is invalid - * @throws TypeNotPresentException - * if any exception type points to a missing type - * @throws MalformedParameterizedTypeException - * if any exception type points to a type that cannot be - * instantiated for some reason - */ - public Type[] getGenericExceptionTypes() { - initGenericTypes(); - return Types.getClonedTypeArray(genericExceptionTypes); - } - - /** - * Returns the return type of this method as a {@code Type} instance. - * - * @return the return type of this method - * - * @throws GenericSignatureFormatError - * if the generic method signature is invalid - * @throws TypeNotPresentException - * if the return type points to a missing type - * @throws MalformedParameterizedTypeException - * if the return type points to a type that cannot be - * instantiated for some reason - */ - public Type getGenericReturnType() { - initGenericTypes(); - return Types.getType(genericReturnType); - } - - @Override - public Annotation[] getDeclaredAnnotations() { - return getDeclaredAnnotations(declaringClass, slot); - } - native private Annotation[] getDeclaredAnnotations(Class declaringClass, - int slot); - - private static final Annotation[] NO_ANNOTATIONS = new Annotation[0]; - - /** - * Creates an array of empty Annotation arrays. - */ - /*package*/ static Annotation[][] noAnnotations(int size) { - Annotation[][] annotations = new Annotation[size][]; - for (int i = 0; i < size; i++) { - annotations[i] = NO_ANNOTATIONS; - } - return annotations; - } - - /** - * Returns an array of arrays that represent the annotations of the formal - * parameters of this method. If there are no parameters on this method, - * then an empty array is returned. If there are no annotations set, then - * and array of empty arrays is returned. - * - * @return an array of arrays of {@code Annotation} instances - */ - public Annotation[][] getParameterAnnotations() { - Annotation[][] parameterAnnotations - = getParameterAnnotations(declaringClass, slot); - if (parameterAnnotations.length == 0) { - return noAnnotations(parameterTypes.length); - } - return parameterAnnotations; - } - - native private Annotation[][] getParameterAnnotations(Class declaringClass, - int slot); - - /** - * Indicates whether or not this method takes a variable number argument. - * - * @return {@code true} if a vararg is declared, {@code false} otherwise - */ - public boolean isVarArgs() { - int modifiers = getMethodModifiers(declaringClass, slot); - return (modifiers & Modifier.VARARGS) != 0; - } - - /** - * Indicates whether or not this method is a bridge. - * - * @return {@code true} if this method is a bridge, {@code false} otherwise - */ - public boolean isBridge() { - int modifiers = getMethodModifiers(declaringClass, slot); - return (modifiers & Modifier.BRIDGE) != 0; - } - - /** - * Indicates whether or not this method is synthetic. - * - * @return {@code true} if this method is synthetic, {@code false} otherwise - */ - public boolean isSynthetic() { - int modifiers = getMethodModifiers(declaringClass, slot); - return (modifiers & Modifier.SYNTHETIC) != 0; - } - - /** - * Returns the default value for the annotation member represented by this - * method. - * - * @return the default value, or {@code null} if none - * - * @throws TypeNotPresentException - * if this annotation member is of type {@code Class} and no - * definition can be found - */ - public Object getDefaultValue() { - return getDefaultValue(declaringClass, slot); - } - native private Object getDefaultValue(Class declaringClass, int slot); - - /** - * Indicates whether or not the specified {@code object} is equal to this - * method. To be equal, the specified object must be an instance - * of {@code Method} with the same declaring class and parameter types - * as this method. - * - * @param object - * the object to compare - * - * @return {@code true} if the specified object is equal to this - * method, {@code false} otherwise - * - * @see #hashCode - */ - @Override - public boolean equals(Object object) { - return object instanceof Method && toString().equals(object.toString()); - } - - /** - * Returns the class that declares this method. - * - * @return the declaring class - */ - public Class<?> getDeclaringClass() { - return declaringClass; - } - - /** - * Returns the exception types as an array of {@code Class} instances. If - * this method has no declared exceptions, an empty array is returned. - * - * @return the declared exception classes - */ - public Class<?>[] getExceptionTypes() { - if (exceptionTypes == null) { - return new Class[0]; - } - - return exceptionTypes.clone(); - } - - /** - * Returns the modifiers for this method. The {@link Modifier} class should - * be used to decode the result. - * - * @return the modifiers for this method - * - * @see Modifier - */ - public int getModifiers() { - return getMethodModifiers(declaringClass, slot); - } - - private native int getMethodModifiers(Class<?> decl_class, int slot); - - /** - * Returns the name of the method represented by this {@code Method} - * instance. - * - * @return the name of this method - */ - public String getName() { - return name; - } - - /** - * Returns an array of {@code Class} objects associated with the parameter - * types of this method. If the method was declared with no parameters, an - * empty array will be returned. - * - * @return the parameter types - */ - public Class<?>[] getParameterTypes() { - return parameterTypes.clone(); - } - - /** - * Returns the {@code Class} associated with the return type of this - * method. - * - * @return the return type - */ - public Class<?> getReturnType() { - return returnType; - } - - /** - * Returns an integer hash code for this method. Objects which are equal - * return the same value for this method. The hash code for this Method is - * the hash code of the name of this method. - * - * @return hash code for this method - * - * @see #equals - */ - @Override - public int hashCode() { - return name.hashCode(); - } - - /** - * Returns the result of dynamically invoking this method. This reproduces - * the effect of {@code receiver.methodName(arg1, arg2, ... , argN)} This - * method performs the following: - * <ul> - * <li>If this method is static, the receiver argument is ignored.</li> - * <li>Otherwise, if the receiver is null, a NullPointerException is thrown. - * </li> - * <li>If the receiver is not an instance of the declaring class of the - * method, an IllegalArgumentException is thrown.</li> - * <li>If this Method object is enforcing access control (see - * AccessibleObject) and this method is not accessible from the current - * context, an IllegalAccessException is thrown.</li> - * <li>If the number of arguments passed and the number of parameters do not - * match, an IllegalArgumentException is thrown.</li> - * <li>For each argument passed: - * <ul> - * <li>If the corresponding parameter type is a primitive type, the argument - * is unwrapped. If the unwrapping fails, an IllegalArgumentException is - * thrown.</li> - * <li>If the resulting argument cannot be converted to the parameter type - * via a widening conversion, an IllegalArgumentException is thrown.</li> - * </ul> - * <li>If this method is static, it is invoked directly. If it is - * non-static, this method and the receiver are then used to perform a - * standard dynamic method lookup. The resulting method is then invoked.</li> - * <li>If an exception is thrown during the invocation it is caught and - * wrapped in an InvocationTargetException. This exception is then thrown.</li> - * <li>If the invocation completes normally, the return value itself is - * returned. If the method is declared to return a primitive type, the - * return value is first wrapped. If the return type is void, null is - * returned.</li> - * </ul> - * - * @param receiver - * the object on which to call this method - * @param args - * the arguments to the method - * - * @return the new, initialized, object - * - * @throws NullPointerException - * if the receiver is null for a non-static method - * @throws IllegalAccessException - * if this method is not accessible - * @throws IllegalArgumentException - * if an incorrect number of arguments are passed, the receiver - * is incompatible with the declaring class, or an argument - * could not be converted by a widening conversion - * @throws InvocationTargetException - * if an exception was thrown by the invoked method - * - * @see AccessibleObject - */ - public Object invoke(Object receiver, Object... args) - throws IllegalAccessException, IllegalArgumentException, - InvocationTargetException { - if (args == null) { - args = new Object[0]; - } - - return invokeNative (receiver, args, declaringClass, parameterTypes, returnType, slot, flag); - } - - private native Object invokeNative(Object obj, Object[] args, Class<?> declaringClass, Class<?>[] parameterTypes, Class<?> returnType, int slot, boolean noAccessCheck) - throws IllegalAccessException, - IllegalArgumentException, - InvocationTargetException; - - /** - * Returns a string containing a concise, human-readable description of this - * method. The format of the string is: - * - * <ol> - * <li>modifiers (if any) - * <li>return type or 'void' - * <li>declaring class name - * <li>'(' - * <li>parameter types, separated by ',' (if any) - * <li>')' - * <li>'throws' plus exception types, separated by ',' (if any) - * </ol> - * - * For example: {@code public native Object - * java.lang.Method.invoke(Object,Object) throws - * IllegalAccessException,IllegalArgumentException - * ,InvocationTargetException} - * - * @return a printable representation for this method - */ - @Override - public String toString() { - StringBuilder result = new StringBuilder(Modifier.toString(getModifiers())); - - if (result.length() != 0) - result.append(' '); - result.append(returnType.getName()); - result.append(' '); - result.append(declaringClass.getName()); - result.append('.'); - result.append(name); - result.append("("); - result.append(toString(parameterTypes)); - result.append(")"); - if (exceptionTypes != null && exceptionTypes.length != 0) { - result.append(" throws "); - result.append(toString(exceptionTypes)); - } - - return result.toString(); - } - - /** - * Returns the constructor's signature in non-printable form. This is called - * (only) from IO native code and needed for deriving the serialVersionUID - * of the class - * - * @return The constructor's signature. - */ - @SuppressWarnings("unused") - private String getSignature() { - StringBuilder result = new StringBuilder(); - - result.append('('); - for(int i = 0; i < parameterTypes.length; i++) { - result.append(getSignature(parameterTypes[i])); - } - result.append(')'); - result.append(getSignature(returnType)); - - return result.toString(); - } - -} diff --git a/luni-kernel/src/main/java/java/lang/reflect/ReflectionAccessImpl.java b/luni-kernel/src/main/java/java/lang/reflect/ReflectionAccessImpl.java deleted file mode 100644 index 15cd798..0000000 --- a/luni-kernel/src/main/java/java/lang/reflect/ReflectionAccessImpl.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang.reflect; - -import org.apache.harmony.kernel.vm.ReflectionAccess; - -/** - * Implementation of bridge from {@code java.lang} to - * {@code java.lang.reflect}. - */ -/*package*/ final class ReflectionAccessImpl implements ReflectionAccess { - /** non-null; unique instance of this class */ - /*package*/ static final ReflectionAccessImpl THE_ONE = - new ReflectionAccessImpl(); - - /** - * This class is not publicly instantiable. Use {@link #THE_ONE}. - */ - private ReflectionAccessImpl() { - // This space intentionally left blank. - } - - public Method clone(Method method) { - return new Method(method); - } - - public Field clone(Field field) { - return new Field(field); - } - - public Method accessibleClone(Method method) { - Method result = new Method(method); - result.setAccessibleNoCheck(true); - return result; - } - - public void setAccessibleNoCheck(AccessibleObject ao, boolean accessible) { - ao.setAccessibleNoCheck(accessible); - } -} diff --git a/luni-kernel/src/main/java/org/apache/harmony/kernel/vm/LangAccess.java b/luni-kernel/src/main/java/org/apache/harmony/kernel/vm/LangAccess.java deleted file mode 100644 index 8b321e4..0000000 --- a/luni-kernel/src/main/java/org/apache/harmony/kernel/vm/LangAccess.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.harmony.kernel.vm; - -import dalvik.system.VMStack; - -/** - * Bridge into <code>java.lang</code> from other trusted parts of the - * core library. Trusted packages either get seeded with an instance - * of this class directly or may call {@link #getInstance} on this - * class, to allow them to call into what would otherwise be - * package-scope functionality in <code>java.lang</code>. - */ -public abstract class LangAccess { - /** unique instance of this class */ - private static LangAccess theInstance = null; - - /** - * Sets the unique instance of this class. This may only be done once. - * - * @param instance non-null; the instance - */ - public static void setInstance(LangAccess instance) { - if (theInstance != null) { - throw new UnsupportedOperationException("already initialized"); - } - - theInstance = instance; - } - - /** - * Gets the unique instance of this class. This is only allowed in - * very limited situations. - */ - public static LangAccess getInstance() { - /* - * Only code on the bootclasspath is allowed to get at the - * instance. - */ - ClassLoader calling = VMStack.getCallingClassLoader2(); - ClassLoader current = LangAccess.class.getClassLoader(); - - if ((calling != null) && (calling != current)) { - throw new SecurityException("LangAccess access denied"); - } - - if (theInstance == null) { - throw new UnsupportedOperationException("not yet initialized"); - } - - return theInstance; - } - - /** - * Gets a shared array of the enum constants of a given class in - * declaration (ordinal) order. It is not safe to hand out this - * array to any user code. - * - * @param clazz non-null; the class in question - * @return null-ok; the class's list of enumerated constants in - * declaration order or <code>null</code> if the given class is - * not an enumeration - */ - public abstract <T> T[] getEnumValuesInOrder(Class<T> clazz); - - /** - * Unparks the given thread. This unblocks the thread it if it was - * previously parked, or indicates that the thread is "preemptively - * unparked" if it wasn't already parked. The latter means that the - * next time the thread is told to park, it will merely clear its - * latent park bit and carry on without blocking. - * - * <p>See {@link java.util.concurrent.locks.LockSupport} for more - * in-depth information of the behavior of this method.</p> - * - * @param thread non-null; the thread to unpark - */ - public abstract void unpark(Thread thread); - - /** - * Parks the current thread for a particular number of nanoseconds, or - * indefinitely. If not indefinitely, this method unparks the thread - * after the given number of nanoseconds if no other thread unparks it - * first. If the thread has been "preemptively unparked," this method - * cancels that unparking and returns immediately. This method may - * also return spuriously (that is, without the thread being told to - * unpark and without the indicated amount of time elapsing). - * - * <p>See {@link java.util.concurrent.locks.LockSupport} for more - * in-depth information of the behavior of this method.</p> - * - * @param nanos number of nanoseconds to park for or <code>0</code> - * to park indefinitely - * @throws IllegalArgumentException thrown if <code>nanos < 0</code> - */ - public abstract void parkFor(long nanos); - - /** - * Parks the current thread until the specified system time. This - * method attempts to unpark the current thread immediately after - * <code>System.currentTimeMillis()</code> reaches the specified - * value, if no other thread unparks it first. If the thread has - * been "preemptively unparked," this method cancels that - * unparking and returns immediately. This method may also return - * spuriously (that is, without the thread being told to unpark - * and without the indicated amount of time elapsing). - * - * <p>See {@link java.util.concurrent.locks.LockSupport} for more - * in-depth information of the behavior of this method.</p> - * - * @param time the time after which the thread should be unparked, - * in absolute milliseconds-since-the-epoch - */ - public abstract void parkUntil(long time); -} diff --git a/luni-kernel/src/main/java/org/apache/harmony/kernel/vm/ReflectionAccess.java b/luni-kernel/src/main/java/org/apache/harmony/kernel/vm/ReflectionAccess.java deleted file mode 100644 index 1487ba1..0000000 --- a/luni-kernel/src/main/java/org/apache/harmony/kernel/vm/ReflectionAccess.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.harmony.kernel.vm; - -import java.lang.reflect.AccessibleObject; -import java.lang.reflect.Field; -import java.lang.reflect.Method; - -/** - * Bridge from <code>java.lang</code> to <code>java.lang.reflect</code>. - * The package <code>java.lang</code> gets seeded with an instance of - * this interface, to allow it to call into what would otherwise be - * package-scope functionality in <code>java.lang.reflect</code>. - */ -public interface ReflectionAccess { - /** - * Gets a clone of the given method. - * - * @param method non-null; the method to clone - * @return non-null; the clone - */ - public Method clone(Method method); - - /** - * Gets a clone of the given field. - * - * @param field non-null; the field to clone - * @return non-null; the clone - */ - public Field clone(Field field); - - /** - * Gets a clone of the given method, where the clone has - * its "accessible" flag set to <code>true</code> - * - * @param method non-null; the method to clone - * @return non-null; the accessible clone - */ - public Method accessibleClone(Method method); - - /** - * Sets the accessible flag on a given {@link AccessibleObject} - * without doing any checks. - * - * @param ao non-null; the instance in question - * @param flag the new value for the accessible flag - */ - public void setAccessibleNoCheck(AccessibleObject ao, boolean flag); -} diff --git a/luni-kernel/src/main/java/org/apache/harmony/kernel/vm/StringUtils.java b/luni-kernel/src/main/java/org/apache/harmony/kernel/vm/StringUtils.java deleted file mode 100644 index b392388..0000000 --- a/luni-kernel/src/main/java/org/apache/harmony/kernel/vm/StringUtils.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.harmony.kernel.vm; - -/** - * String utility functions. - */ -public final class StringUtils { - /** - * This class is uninstantiable. - */ - private StringUtils() { - // This space intentionally left blank. - } - - /** - * Combine a list of strings in an <code>Object[]</code> into a single - * string. - * - * @param list non-null; the strings to combine - * @return non-null; the combined form - */ - public static String combineStrings(Object[] list) { - int listLength = list.length; - - switch (listLength) { - case 0: { - return ""; - } - case 1: { - return (String) list[0]; - } - } - - int strLength = 0; - - for (int i = 0; i < listLength; i++) { - strLength += ((String) list[i]).length(); - } - - StringBuilder sb = new StringBuilder(strLength); - - for (int i = 0; i < listLength; i++) { - sb.append(list[i]); - } - - return sb.toString(); - } -} diff --git a/luni-kernel/src/main/java/org/apache/harmony/kernel/vm/VM.java b/luni-kernel/src/main/java/org/apache/harmony/kernel/vm/VM.java deleted file mode 100644 index 8aa7c4b..0000000 --- a/luni-kernel/src/main/java/org/apache/harmony/kernel/vm/VM.java +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.harmony.kernel.vm; - -/** - * This class must be implemented by the vm vendor. Represents the running - * virtual machine. All VM specific API are implemented on this class. - * <p> - * Note that all methods in VM are static. There is no singleton instance which - * represents the actively running VM. - */ -public final class VM { - - /* - * kernelVersion has the format: aabbxxyy where: aa - major version of - * kernel. Must equal that stored in jcl. bb - minor version of kernel. Must - * be >= that in jcl. xx - major version of jcl. Must equal that stored in - * kernel. yy - minor version of jcl. Must be >= that in kernel. - */ - private static final int kernelVersion = 0x01000100; - - /** - * This method must be provided by the vm vendor, as it is used by - * org.apache.harmony.kernel.vm.MsgHelp.setLocale() to get the bootstrap - * ClassLoader. MsgHelp uses the bootstrap ClassLoader to find the resource - * bundle of messages packaged with the bootstrap classes. Returns the - * ClassLoader of the method (including natives) at the specified depth on - * the stack of the calling thread. Frames representing the VM - * implementation of java.lang.reflect are not included in the list. This is - * not a public method as it can return the bootstrap class loader, which - * should not be accessed by non-bootstrap classes. Notes: - * <ul> - * <li>This method operates on the defining classes of methods on stack. - * NOT the classes of receivers.</li> - * <li>The item at depth zero is the caller of this method</li> - * </ul> - * - * @param depth the stack depth of the requested ClassLoader - * @return the ClassLoader at the specified depth - * @see java.lang.ClassLoader#getStackClassLoader - */ - static final ClassLoader getStackClassLoader(int depth) { - return null; - }; - - /** - * This method must be provided by the vm vendor, as it is used by other - * provided class implementations. For example, - * java.io.ObjectInputStream.readObject() and - * java.io.ObjectInputStream.resolveProxyClass(). It is also useful for - * other classes, such as java.rmi.server.RMIClassLoader. Walk the stack and - * answer the most recent non-null and non-bootstrap ClassLoader on the - * stack of the calling thread. If no such ClassLoader is found, null is - * returned. Notes: 1) This method operates on the defining classes of - * methods on stack. NOT the classes of receivers. - * - * @return the first non-bootstrap ClassLoader on the stack - */ - static public final ClassLoader getNonBootstrapClassLoader() { - return null; - }; - - /** - * Initialize the classloader. - * - * @param loader ClassLoader the ClassLoader instance - * @param bootLoader boolean true for the bootstrap class loader - */ - public final static void initializeClassLoader(ClassLoader loader, boolean bootLoader) { - return; - }; - - /** - * This method must be provided by the vm vendor. - * - * Searches an internal table of strings for a string equal to the specified - * String. If the string is not in the table, it is added. Returns the - * string contained in the table which is equal to the specified String. The - * same string object is always answered for strings which are equal. - * - * @param string the String to intern - * - * @return the interned string equal to the specified String - */ - public static final String intern(String string) { - return null; - } - - /** - * Native used to find and load a class using the VM - * - * @return java.lang.Class the class or null. - * @param className String the name of the class to search for. - * @param classLoader the classloader to do the work - */ - static Class<?> findClassOrNull(String className, ClassLoader classLoader) { - return null; - } - - /** - * This method must be included, as it is used by - * ResourceBundle.getBundle(), and other places as well. The reference - * implementation of this method uses the getStackClassLoader() method. - * Returns the ClassLoader of the method that called the caller. i.e. A.x() - * calls B.y() calls callerClassLoader(), A's ClassLoader will be returned. - * Returns null for the bootstrap ClassLoader. - * - * @return a ClassLoader or null for the bootstrap ClassLoader - * @throws SecurityException when called from a non-bootstrap Class - */ - public static ClassLoader callerClassLoader() { - return null; - } - - /** - * This method must be provided by the vm vendor, as it is used by - * org.apache.harmony.luni.util.MsgHelp.setLocale() to get the bootstrap - * ClassLoader. MsgHelp uses the bootstrap ClassLoader to find the resource - * bundle of messages packaged with the bootstrap classes. The reference - * implementation of this method uses the getStackClassLoader() method. - * - * Returns the ClassLoader of the method that called the caller. i.e. A.x() - * calls B.y() calls callerClassLoader(), A's ClassLoader will be returned. - * Returns null for the bootstrap ClassLoader. - * - * @return a ClassLoader - * - * @throws SecurityException when called from a non-bootstrap Class - */ - public static ClassLoader bootCallerClassLoader() { - return null; - } - - /** - * Native used to dump a string to the system console for debugging. - * - * @param str String the String to display - */ - public static void dumpString(String str) { - return; - } - - /** - * Get the classpath entry that was used to load the class that is the arg. - * <p> - * This method is for internal use only. - * - * @param targetClass Class the class to set the classpath of. - * @see java.lang.Class - */ - static int getCPIndexImpl(Class<?> targetClass) { - return 0; - } - - /** - * Does internal initialization required by VM. - * - */ - static void initializeVM() { - } - - /** - * Registers a new virtual-machine shutdown hook. This is equivalent to the - * 1.3 API of the same name. - * - * @param hook the hook (a Thread) to register - */ - public static void addShutdownHook(Thread hook) { - return; - } - - /** - * De-registers a previously-registered virtual-machine shutdown hook. This - * is equivalent to the 1.3 API of the same name. - * - * @param hook the hook (a Thread) to de-register - * @return true if the hook could be de-registered - */ - public static boolean removeShutdownHook(Thread hook) { - return false; - } - - /** - * This method must be provided by the vm vendor. Called to signal that the - * org.apache.harmony.luni.internal.net.www.protocol.jar.JarURLConnection - * class has been loaded and JarURLConnection.closeCachedFiles() should be - * called on VM shutdown. - */ - public static void closeJars() { - return; - } - - /** - * This method must be provided by the vm vendor. Called to signal that the - * org.apache.harmony.luni.util.DeleteOnExit class has been loaded and - * DeleteOnExit.deleteOnExit() should be called on VM shutdown. - */ - public static void deleteOnExit() { - return; - } - - // Constants used by getClassPathEntryType to indicate the class path entry - // type - static final int CPE_TYPE_UNKNOWN = 0; - - static final int CPE_TYPE_DIRECTORY = 1; - - static final int CPE_TYPE_JAR = 2; - - static final int CPE_TYPE_TCP = 3; - - static final int CPE_TYPE_UNUSABLE = 5; - - /** - * Return the type of the specified entry on the class path for a - * ClassLoader. Valid types are: CPE_TYPE_UNKNOWN CPE_TYPE_DIRECTORY - * CPE_TYPE_JAR CPE_TYPE_TCP - this is obsolete CPE_TYPE_UNUSABLE - * - * @param classLoader the ClassLoader - * @param cpIndex the index on the class path - * - * @return a int which specifies the class path entry type - */ - static final int getClassPathEntryType(Object classLoader, int cpIndex) { - return 0; - } - - /** - * Returns command line arguments passed to the VM. Internally these are - * broken into optionString and extraInfo. This only returns the - * optionString part. - * <p> - * - * @return a String array containing the optionString part of command line - * arguments - */ - public static String[] getVMArgs() { - return null; - } - - /** - * Return the number of entries on the bootclasspath. - * - * @return an int which is the number of entries on the bootclasspath - */ - static int getClassPathCount() { - return 0; - } - - /** - * Return the specified bootclasspath entry. - * - * @param index the index of the bootclasspath entry - * - * @return a byte array containing the bootclasspath entry - * specified in the vm options - */ - static byte[] getPathFromClassPath(int index) { - return null; - } - - /** - * This method must be provided by the vm vendor. - * - * Returns an int containing the version number of the kernel. Used to check for kernel - * compatibility. - * - * @return an int containing the kernel version number - */ - public static int getKernelVersion() { - return kernelVersion; - } - -} diff --git a/luni-kernel/src/main/java/org/apache/harmony/lang/annotation/AnnotationFactory.java b/luni-kernel/src/main/java/org/apache/harmony/lang/annotation/AnnotationFactory.java deleted file mode 100644 index a898f54..0000000 --- a/luni-kernel/src/main/java/org/apache/harmony/lang/annotation/AnnotationFactory.java +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.harmony.lang.annotation; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.Serializable; -import java.lang.annotation.Annotation; -import java.lang.annotation.IncompleteAnnotationException; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.WeakHashMap; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; - -import static org.apache.harmony.lang.annotation.AnnotationMember.ARRAY; -import static org.apache.harmony.lang.annotation.AnnotationMember.ERROR; - -/** - * The annotation implementation based on dynamically generated proxy instances. - * It conforms to all requirements stated in public APIs, see in particular - * {@link java.lang.reflect.AnnotatedElement java.lang.reflect.AnnotatedElement} - * and {@link java.lang.annotation.Annotation java.lang.annotation.Annotation}. - * Namely, annotation instances are immutable and serializable; they provide - * conforming access to annotation member values and required implementations of - * methods declared in Annotation interface. - * - * @see android.lang.annotation.AnnotationMember - * @see java.lang.annotation.Annotation - * - * @author Alexey V. Varlamov, Serguei S. Zapreyev - * @version $Revision$ - */ -@SuppressWarnings({"serial"}) -public final class AnnotationFactory implements InvocationHandler, Serializable { - - private static final transient - Map<Class<? extends Annotation>, AnnotationMember[]> - cache = new WeakHashMap<Class<? extends Annotation>, AnnotationMember[]>(); - - /** - * Reflects specified annotation type and returns an array - * of member element definitions with default values. - */ - public static AnnotationMember[] getElementsDescription(Class<? extends Annotation> annotationType ) { - AnnotationMember[] desc = cache.get(annotationType); - if (desc == null) { - if (!annotationType.isAnnotation()) { - throw new IllegalArgumentException("Type is not annotation: " - + annotationType.getName()); - } - Method[] m = annotationType.getDeclaredMethods(); - desc = new AnnotationMember[m.length]; - int idx = 0; - for(Method element : m) { - String name = element.getName(); - Class<?> type = element.getReturnType(); - try { - desc[idx] = new AnnotationMember(name, - element.getDefaultValue(), type, element); - } catch (Throwable t) { - desc[idx] = new AnnotationMember(name, t, type, element); - } - idx++; - } - cache.put(annotationType, desc); - } - return desc; - } - - /** - * Provides a new annotation instance. - * @param annotationType the annotation type definition - * @param elements name-value pairs representing elements of the annotation - * @return a new annotation instance - */ - public static Annotation createAnnotation( - Class<? extends Annotation> annotationType, - AnnotationMember[] elements) - { - AnnotationFactory antn = new AnnotationFactory(annotationType, elements); - return (Annotation)Proxy.newProxyInstance( annotationType.getClassLoader(), - new Class[]{annotationType}, antn); - } - - private final Class<? extends Annotation> klazz; - private AnnotationMember[] elements; - - /** - * New instances should not be created directly, use factory method - * {@link #createAnnotation(Class, AnnotationMember[]) createAnnotation()} - * instead. - * - * @param klzz class defining the annotation type - * @param values actual element values - */ - private AnnotationFactory(Class<? extends Annotation> klzz, AnnotationMember[] values) { - klazz = klzz; - AnnotationMember[] defs = getElementsDescription(klazz); - if (values == null) { - elements = defs; - } else { - //merge default and actual values - elements = new AnnotationMember[defs.length]; - next: for (int i = elements.length - 1; i >= 0; i-- ){ - for (AnnotationMember val : values){ - if (val.name.equals(defs[i].name)) { - elements[i] = val.setDefinition(defs[i]); - continue next; - } - } - elements[i] = defs[i]; - } - } - } - - /** - * Reads the object, obtains actual member definitions for the annotation type, - * and merges deserialized values with the new definitions. - */ - private void readObject(ObjectInputStream os) throws IOException, - ClassNotFoundException { - os.defaultReadObject(); - // Annotation type members can be changed arbitrarily - // So there may be zombi elements from the previous life; - // they hardly fit into this new annotation's incarnation, - // as we have no defining methods for them. - // Reasonably just drop such elements, - // but seems better to keep them for compatibility - AnnotationMember[] defs = getElementsDescription(klazz); - AnnotationMember[] old = elements; - List<AnnotationMember> merged = new ArrayList<AnnotationMember>( - defs.length + old.length); - nextOld: for (AnnotationMember el1 : old) { - for (AnnotationMember el2 : defs) { - if (el2.name.equals(el1.name)) { - continue nextOld; - } - } - merged.add(el1); //phantom element - } - nextNew: for (AnnotationMember def : defs){ - for (AnnotationMember val : old){ - if (val.name.equals(def.name)) { - // nothing to do about cached errors (if any) - // anyway they remain relevant to values - merged.add(val.setDefinition(def)); - continue nextNew; - } - } - merged.add(def); // brand new element - } - elements = merged.toArray(new AnnotationMember[merged.size()]); - } - - /** - * Returns true if the specified object represents the same annotation instance. - * That is, if it implements the same annotation type and - * returns the same element values. - * <br>Note, actual underlying implementation mechanism does not matter - it may - * differ completely from this class. - * @return true if the passed object is equivalent annotation instance, - * false otherwise. - * @see android.lang.annotation.AnnotationMember#equals(Object) - */ - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (!klazz.isInstance(obj)) { - return false; - } - Object handler = null; - if (Proxy.isProxyClass(obj.getClass()) - && (handler = Proxy.getInvocationHandler(obj)) instanceof AnnotationFactory ) { - AnnotationFactory other = (AnnotationFactory) handler; - if (elements.length != other.elements.length) { - return false; - } - next: for (AnnotationMember el1 : elements){ - for (AnnotationMember el2 : other.elements) { - if (el1.equals(el2)) { - continue next; - } - } - return false; - } - return true; - } else { - // encountered foreign annotation implementaton - // so have to obtain element values via invocation - // of corresponding methods - for (final AnnotationMember el : elements) { - if (el.tag == ERROR) { - // undefined value is incomparable (transcendent) - return false; - } - try { - if (!el.definingMethod.isAccessible()) { - AccessController.doPrivileged(new PrivilegedAction<Object>(){ - public Object run() { - try { - el.definingMethod.setAccessible(true); - } catch (Exception ignore) {} - return null; - } - }); - } - Object otherValue = el.definingMethod.invoke(obj); - if (otherValue != null ) { - if (el.tag == ARRAY) { - if (!el.equalArrayValue(otherValue)) { - return false; - } - } else { - if (!el.value.equals(otherValue)) { - return false; - } - } - } else if (el.value != AnnotationMember.NO_VALUE) { - return false; - } - } catch (Throwable e) { - return false; - } - } - return true; - } - } - - /** - * Returns a hash code composed as a sum of hash codes of member elements, - * including elements with default values. - * @see android.lang.annotation.AnnotationMember#hashCode() - */ - public int hashCode() { - int hash = 0; - for (AnnotationMember element : elements) { - hash += element.hashCode(); - } - return hash; - } - - /** - * Provides detailed description of this annotation instance, - * including all member name-values pairs. - * @return string representation of this annotation - */ - public String toString() { - String res = "@" + klazz.getName() + "("; - for(int i = 0; i < elements.length; i++) { - if ( i != 0 ) { - res += ", "; - } - res += elements[i].toString();; - } - return res + ")"; - } - - /** - * Processes a method invocation request to this annotation instance. - * Recognizes the methods declared in the - * {@link java.lang.annotation.Annotation java.lang.annotation.Annotation} - * interface, and member-defining methods of the implemented annotation type. - * @throws IllegalArgumentException If the specified method is none of the above - * @return the invocation result - */ - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable - { - String name = method.getName(); - Class[] params = method.getParameterTypes(); - if (params.length == 0) { - if ("annotationType".equals(name)) { - return klazz; - } else if ("toString".equals(name)) { - return toString(); - } else if ("hashCode".equals(name)) { - return hashCode(); - } - - // this must be element value request - AnnotationMember element = null; - for (AnnotationMember el : elements) { - if (name.equals(el.name)) { - element = el; - break; - } - } - if (element == null || !method.equals(element.definingMethod)) { - throw new IllegalArgumentException(method.toString()); - } else { - Object value = element.validateValue(); - if (value == null) { - throw new IncompleteAnnotationException(klazz, name); - } - return value; - } - } else if (params.length == 1 && params[0] == Object.class && "equals".equals(name)){ - return Boolean.valueOf(equals(args[0])); - } - throw new IllegalArgumentException( - "Invalid method for annotation type: " + method); - } -} diff --git a/luni-kernel/src/main/java/org/apache/harmony/lang/annotation/AnnotationMember.java b/luni-kernel/src/main/java/org/apache/harmony/lang/annotation/AnnotationMember.java deleted file mode 100644 index f8dea31..0000000 --- a/luni-kernel/src/main/java/org/apache/harmony/lang/annotation/AnnotationMember.java +++ /dev/null @@ -1,387 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.harmony.lang.annotation; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.lang.annotation.AnnotationTypeMismatchException; -import java.lang.reflect.Array; -import java.lang.reflect.Method; -import java.util.Arrays; - -/** - * This class represents member element of an annotation. - * It consists of name and value, supplemented with element - * definition information (such as declared type of element). - * <br>The value may be one of the following types: - * <ul> - * <li> boxed primitive - * <li> Class - * <li> enum constant - * <li> annotation (nested) - * <li> one-dimensional array of the above - * <li> Throwable - * </ul> - * The last type is specific for this implementation; a Throwable value - * means that the error occured during parsing or resolution of corresponding - * class-data structures and throwing is delayed until the element - * is requested for value. - * - * @see android.lang.annotation.AnnotationFactory - * - * @author Alexey V. Varlamov, Serguei S. Zapreyev - * @version $Revision$ - */ -@SuppressWarnings({"serial"}) -public class AnnotationMember implements Serializable { - - /** - * Tag description of a Throwable value type. - */ - protected static final char ERROR = '!'; - - /** - * Tag description of an array value type. - */ - protected static final char ARRAY = '['; - - /** - * Tag description of all value types except arrays and Throwables. - */ - protected static final char OTHER = '*'; - -// public static final char INT = 'I'; -// public static final char CHAR = 'C'; -// public static final char DOUBLE = 'D'; -// public static final char FLOAT = 'F'; -// public static final char BYTE = 'B'; -// public static final char LONG = 'J'; -// public static final char SHORT = 'S'; -// public static final char BOOL = 'Z'; -// public static final char CLASS = 'c'; -// public static final char ENUM = 'e'; -// public static final char ANTN = '@'; - - private enum DefaultValues {NO_VALUE} - - /** - * Singleton representing missing element value. - */ - protected static final Object NO_VALUE = DefaultValues.NO_VALUE; - - protected final String name; - protected final Object value; // a primitive value is wrapped to the corresponding wrapper class - protected final char tag; - // no sense to serialize definition info as it can be changed arbitrarily - protected transient Class<?> elementType; - protected transient Method definingMethod; - - - /** - * Creates a new element with specified name and value. - * Definition info will be provided later when this - * element becomes actual annotation member. - * @param name element name, must not be null - * @param val element value, should be of addmissible type, - * as specified in the description of this class - * - * @see #setDefinition(AnnotationMember) - */ - public AnnotationMember(String name, Object val) { - this.name = name; - value = val == null ? NO_VALUE : val; - if (value instanceof Throwable) { - tag = ERROR; - } else if (value.getClass().isArray()) { - tag = ARRAY; - } else { - tag = OTHER; - } - } - - /** - * Creates the completely defined element. - * @param name element name, must not be null - * @param value element value, should be of addmissible type, - * as specified in the description of this class - * @param m element-defining method, reflected on the annotation type - * @param type declared type of this element - * (return type of the defining method) - */ - public AnnotationMember(String name, Object val, Class type, Method m) { - this(name, val); - - definingMethod = m; - - if (type == int.class) { - elementType = Integer.class; - } else if (type == boolean.class) { - elementType = Boolean.class; - } else if (type == char.class) { - elementType = Character.class; - } else if (type == float.class) { - elementType = Float.class; - } else if (type == double.class) { - elementType = Double.class; - } else if (type == long.class) { - elementType = Long.class; - } else if (type == short.class) { - elementType = Short.class; - } else if (type == byte.class) { - elementType = Byte.class; - } else { - elementType = type; - } - } - - /** - * Fills in element's definition info and returns this. - */ - protected AnnotationMember setDefinition(AnnotationMember copy) { - definingMethod = copy.definingMethod; - elementType = copy.elementType; - return this; - } - - /** - * Returns readable description of this annotation value. - */ - public String toString() { - if (tag == ARRAY) { - StringBuilder sb = new StringBuilder(80); - sb.append(name).append("=["); - int len = Array.getLength(value); - for (int i = 0; i < len; i++) { - if (i != 0) sb.append(", "); - sb.append(Array.get(value, i)); - } - return sb.append("]").toString(); - } else { - return name+ "=" +value; - } - } - - /** - * Returns true if the specified object represents equal element - * (equivalent name-value pair). - * <br> A special case is the contained Throwable value; it is considered - * transcendent so no other element would be equal. - * @return true if passed object is equivalent element representation, - * false otherwise - * @see #equalArrayValue(Object) - * @see java.lang.annotation.Annotation#equals(Object) - */ - public boolean equals(Object obj) { - if (obj == this) { - // not a mere optimization, - // this is needed for consistency with hashCode() - return true; - } - if (obj instanceof AnnotationMember) { - AnnotationMember that = (AnnotationMember)obj; - if (name.equals(that.name) && tag == that.tag) { - if (tag == ARRAY) { - return equalArrayValue(that.value); - } else if (tag == ERROR) { - // undefined value is incomparable (transcendent) - return false; - } else { - return value.equals(that.value); - } - } - } - return false; - } - - /** - * Returns true if the contained value and a passed object are equal arrays, - * false otherwise. Appropriate overloaded method of Arrays.equals() - * is used for equality testing. - * @see java.util.Arrays#equals(java.lang.Object[], java.lang.Object[]) - * @return true if the value is array and is equal to specified object, - * false otherwise - */ - public boolean equalArrayValue(Object otherValue) { - if (value instanceof Object[] && otherValue instanceof Object[]) { - return Arrays.equals((Object[])value, (Object[])otherValue); - } - Class type = value.getClass(); - if (type != otherValue.getClass()) { - return false; - } - if (type == int[].class) { - return Arrays.equals((int[])value, (int[])otherValue); - } else if (type == byte[].class) { - return Arrays.equals((byte[])value, (byte[])otherValue); - } else if (type == short[].class) { - return Arrays.equals((short[])value, (short[])otherValue); - } else if (type == long[].class) { - return Arrays.equals((long[])value, (long[])otherValue); - } else if (type == char[].class) { - return Arrays.equals((char[])value, (char[])otherValue); - } else if (type == boolean[].class) { - return Arrays.equals((boolean[])value, (boolean[])otherValue); - } else if (type == float[].class) { - return Arrays.equals((float[])value, (float[])otherValue); - } else if (type == double[].class) { - return Arrays.equals((double[])value, (double[])otherValue); - } - return false; - } - - /** - * Computes hash code of this element. The formula is as follows: - * <code> (name.hashCode() * 127) ^ value.hashCode() </code> - * <br>If value is an array, one of overloaded Arrays.hashCode() - * methods is used. - * @return the hash code - * @see java.util.Arrays#hashCode(java.lang.Object[]) - * @see java.lang.annotation.Annotation#hashCode() - */ - public int hashCode() { - int hash = name.hashCode() * 127; - if (tag == ARRAY) { - Class type = value.getClass(); - if (type == int[].class) { - return hash ^ Arrays.hashCode((int[])value); - } else if (type == byte[].class) { - return hash ^ Arrays.hashCode((byte[])value); - } else if (type == short[].class) { - return hash ^ Arrays.hashCode((short[])value); - } else if (type == long[].class) { - return hash ^ Arrays.hashCode((long[])value); - } else if (type == char[].class) { - return hash ^ Arrays.hashCode((char[])value); - } else if (type == boolean[].class) { - return hash ^ Arrays.hashCode((boolean[])value); - } else if (type == float[].class) { - return hash ^ Arrays.hashCode((float[])value); - } else if (type == double[].class) { - return hash ^ Arrays.hashCode((double[])value); - } - return hash ^ Arrays.hashCode((Object[])value); - } else { - return hash ^ value.hashCode(); - } - } - - /** - * Throws contained error (if any) with a renewed stack trace. - */ - public void rethrowError() throws Throwable { - if (tag == ERROR) { - // need to throw cloned exception for thread safety - // besides it is better to provide actual stack trace - // rather than recorded during parsing - - // first check for expected types - if (value instanceof TypeNotPresentException) { - TypeNotPresentException tnpe = (TypeNotPresentException)value; - throw new TypeNotPresentException(tnpe.typeName(), tnpe.getCause()); - } else if (value instanceof EnumConstantNotPresentException) { - EnumConstantNotPresentException ecnpe = (EnumConstantNotPresentException)value; - throw new EnumConstantNotPresentException(ecnpe.enumType(), ecnpe.constantName()); - } else if (value instanceof ArrayStoreException) { - ArrayStoreException ase = (ArrayStoreException)value; - throw new ArrayStoreException(ase.getMessage()); - } - // got some other error, have to go with deep cloning - // via serialization mechanism - Throwable error = (Throwable)value; - StackTraceElement[] ste = error.getStackTrace(); - ByteArrayOutputStream bos = new ByteArrayOutputStream( - ste == null ? 512 : (ste.length + 1) * 80); - ObjectOutputStream oos = new ObjectOutputStream(bos); - oos.writeObject(error); - oos.flush(); - oos.close(); - ByteArrayInputStream bis = new ByteArrayInputStream(bos - .toByteArray()); - ObjectInputStream ois = new ObjectInputStream(bis); - error = (Throwable)ois.readObject(); - ois.close(); - - throw error; - } - } - - /** - * Validates contained value against its member definition - * and if ok returns the value. - * Otherwise, if the value type mismatches definition - * or the value itself describes an error, - * throws appropriate exception. - * <br> Note, this method may return null if this element was constructed - * with such value. - * - * @see #rethrowError() - * @see #copyValue() - * @return actual valid value or null if no value - */ - public Object validateValue() throws Throwable { - if (tag == ERROR) { - rethrowError(); - } - if (value == NO_VALUE) { - return null; - } - if (elementType == value.getClass() - || elementType.isInstance(value)) { // nested annotation value - return copyValue(); - } else { - throw new AnnotationTypeMismatchException(definingMethod, - value.getClass().getName()); - } - - } - - - /** - * Provides mutation-safe access to contained value. That is, caller is free - * to modify the returned value, it will not affect the contained data value. - * @return cloned value if it is mutable or the original immutable value - */ - public Object copyValue() throws Throwable - { - if (tag != ARRAY || Array.getLength(value) == 0) { - return value; - } - Class type = value.getClass(); - if (type == int[].class) { - return ((int[])value).clone(); - } else if (type == byte[].class) { - return ((byte[])value).clone(); - } else if (type == short[].class) { - return ((short[])value).clone(); - } else if (type == long[].class) { - return ((long[])value).clone(); - } else if (type == char[].class) { - return ((char[])value).clone(); - } else if (type == boolean[].class) { - return ((boolean[])value).clone(); - } else if (type == float[].class) { - return ((float[])value).clone(); - } else if (type == double[].class) { - return ((double[])value).clone(); - } - return ((Object[])value).clone(); - } -} diff --git a/luni-kernel/src/main/native/Register.cpp b/luni-kernel/src/main/native/Register.cpp deleted file mode 100644 index 8980cc5..0000000 --- a/luni-kernel/src/main/native/Register.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "ScopedLocalFrame.h" - -namespace android { - extern int register_dalvik_system_TouchDex(JNIEnv* env); -} - -extern int register_com_ibm_icu4jni_converters_NativeConverter(JNIEnv* env); -extern int register_com_ibm_icu4jni_lang_UCharacter(JNIEnv* env); -extern int register_com_ibm_icu4jni_regex_NativeRegEx(JNIEnv* env); -extern int register_com_ibm_icu4jni_text_NativeBreakIterator(JNIEnv* env); -extern int register_com_ibm_icu4jni_text_NativeCollator(JNIEnv* env); -extern int register_com_ibm_icu4jni_text_NativeDecimalFormat(JNIEnv* env); -extern int register_com_ibm_icu4jni_text_NativeIDN(JNIEnv* env); -extern int register_com_ibm_icu4jni_text_NativeNormalizer(JNIEnv* env); -extern int register_com_ibm_icu4jni_util_Resources(JNIEnv* env); -extern int register_java_io_Console(JNIEnv* env); -extern int register_java_io_File(JNIEnv* env); -extern "C" int register_java_io_FileDescriptor(JNIEnv* env); -extern "C" int register_java_io_ObjectInputStream(JNIEnv* env); -extern "C" int register_java_io_ObjectOutputStream(JNIEnv* env); -extern "C" int register_java_io_ObjectStreamClass(JNIEnv* env); -extern "C" int register_java_lang_Double(JNIEnv* env); -extern "C" int register_java_lang_Float(JNIEnv* env); -extern "C" int register_java_lang_Math(JNIEnv* env); -extern int register_java_lang_ProcessManager(JNIEnv* env); -extern "C" int register_java_lang_StrictMath(JNIEnv* env); -extern int register_java_lang_System(JNIEnv* env); -extern int register_java_net_InetAddress(JNIEnv* env); -extern int register_java_net_NetworkInterface(JNIEnv* env); -extern "C" int register_java_util_zip_Adler32(JNIEnv* env); -extern "C" int register_java_util_zip_CRC32(JNIEnv* env); -extern "C" int register_java_util_zip_Deflater(JNIEnv* env); -extern "C" int register_java_util_zip_Inflater(JNIEnv* env); -extern "C" int register_org_apache_harmony_dalvik_NativeTestTarget(JNIEnv* env); -extern int register_org_apache_harmony_luni_platform_OSFileSystem(JNIEnv* env); -extern int register_org_apache_harmony_luni_platform_OSMemory(JNIEnv* env); -extern int register_org_apache_harmony_luni_platform_OSNetworkSystem(JNIEnv* env); -extern "C" int register_org_apache_harmony_luni_util_NumberConvert(JNIEnv* env); -extern "C" int register_org_apache_harmony_luni_util_fltparse(JNIEnv* env); -extern int register_org_apache_harmony_text_BidiWrapper(JNIEnv* env); -extern int register_org_apache_harmony_xml_ExpatParser(JNIEnv* env); -extern int register_org_apache_harmony_xnet_provider_jsse_NativeCrypto(JNIEnv* env); -extern "C" int register_org_openssl_NativeBN(JNIEnv* env); - -// DalvikVM calls this on startup, so we can statically register all our native methods. -extern "C" int registerCoreLibrariesJni(JNIEnv* env) { - ScopedLocalFrame localFrame(env); - - bool result = - register_com_ibm_icu4jni_converters_NativeConverter(env) != -1 && - register_com_ibm_icu4jni_lang_UCharacter(env) != -1 && - register_com_ibm_icu4jni_regex_NativeRegEx(env) != -1 && - register_com_ibm_icu4jni_text_NativeBreakIterator(env) != -1 && - register_com_ibm_icu4jni_text_NativeCollator(env) != -1 && - register_com_ibm_icu4jni_text_NativeDecimalFormat(env) != -1 && - register_com_ibm_icu4jni_text_NativeIDN(env) != -1 && - register_com_ibm_icu4jni_text_NativeNormalizer(env) != -1 && - register_com_ibm_icu4jni_util_Resources(env) != -1 && - register_java_io_Console(env) != -1 && - register_java_io_File(env) != -1 && - register_java_io_FileDescriptor(env) != -1 && - register_java_io_ObjectInputStream(env) != -1 && - register_java_io_ObjectOutputStream(env) != -1 && - register_java_io_ObjectStreamClass(env) != -1 && - register_java_lang_Double(env) != -1 && - register_java_lang_Float(env) != -1 && - register_java_lang_Math(env) != -1 && - register_java_lang_ProcessManager(env) != -1 && - register_java_lang_StrictMath(env) != -1 && - register_java_lang_System(env) != -1 && - register_java_net_InetAddress(env) != -1 && - register_java_net_NetworkInterface(env) != -1 && - register_java_util_zip_Adler32(env) != -1 && - register_java_util_zip_CRC32(env) != -1 && - register_java_util_zip_Deflater(env) != -1 && - register_java_util_zip_Inflater(env) != -1 && - register_org_apache_harmony_luni_platform_OSFileSystem(env) != -1 && - register_org_apache_harmony_luni_platform_OSMemory(env) != -1 && - register_org_apache_harmony_luni_platform_OSNetworkSystem(env) != -1 && - register_org_apache_harmony_luni_util_NumberConvert(env) != -1 && - register_org_apache_harmony_luni_util_fltparse(env) != -1 && - register_org_apache_harmony_text_BidiWrapper(env) != -1 && - register_org_apache_harmony_xnet_provider_jsse_NativeCrypto(env) != -1 && - register_org_openssl_NativeBN(env) != -1 && - // Initialize the Android classes last, as they have dependencies on the "corer" core classes. - android::register_dalvik_system_TouchDex(env) != -1 && - register_org_apache_harmony_dalvik_NativeTestTarget(env) != -1 && - register_org_apache_harmony_xml_ExpatParser(env) != -1; - - return result ? 0 : -1; -} diff --git a/luni-kernel/src/main/native/java_lang_ProcessManager.cpp b/luni-kernel/src/main/native/java_lang_ProcessManager.cpp deleted file mode 100644 index 666a8c7..0000000 --- a/luni-kernel/src/main/native/java_lang_ProcessManager.cpp +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "ProcessManager" - -#include <sys/resource.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> -#include <fcntl.h> -#include <signal.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> - -#include "jni.h" -#include "JNIHelp.h" -#include "utils/Log.h" - -/** Environment variables. */ -extern char **environ; - -static jmethodID onExitMethod = NULL; -static jfieldID descriptorField = NULL; - -#ifdef ANDROID -// Keeps track of the system properties fd so we don't close it. -static int androidSystemPropertiesFd = -1; -#endif - -/* - * These are constants shared with the higher level code in - * ProcessManager.java. - */ -#define WAIT_STATUS_UNKNOWN (-1) // unknown child status -#define WAIT_STATUS_NO_CHILDREN (-2) // no children to wait for -#define WAIT_STATUS_STRANGE_ERRNO (-3) // observed an undocumented errno - -/** Closes a file descriptor. */ -static void java_lang_ProcessManager_close(JNIEnv* env, - jclass, jobject javaDescriptor) { - int fd = env->GetIntField(javaDescriptor, descriptorField); - if (TEMP_FAILURE_RETRY(close(fd)) == -1) { - jniThrowIOException(env, errno); - } -} - -/** - * Kills process with the given ID. - */ -static void java_lang_ProcessManager_kill(JNIEnv* env, jclass clazz, jint pid) { - int result = kill((pid_t) pid, SIGKILL); - if (result == -1) { - jniThrowIOException(env, errno); - } -} - -/** - * Loops indefinitely and calls ProcessManager.onExit() when children exit. - */ -static void java_lang_ProcessManager_watchChildren(JNIEnv* env, jobject o) { - if (onExitMethod == NULL) { - jniThrowException(env, "java/lang/IllegalStateException", - "staticInitialize() must run first."); - } - - while (1) { - int status; - - /* wait for children in our process group */ - pid_t pid = waitpid(0, &status, 0); - - if (pid >= 0) { - // Extract real status. - if (WIFEXITED(status)) { - status = WEXITSTATUS(status); - } else if (WIFSIGNALED(status)) { - status = WTERMSIG(status); - } else if (WIFSTOPPED(status)) { - status = WSTOPSIG(status); - } else { - status = WAIT_STATUS_UNKNOWN; - } - } else { - /* - * The pid should be -1 already, but force it here just in case - * we somehow end up with some other negative value. - */ - pid = -1; - - switch (errno) { - case ECHILD: { - /* - * Expected errno: There are no children to wait() - * for. The callback will sleep until it is - * informed of another child coming to life. - */ - status = WAIT_STATUS_NO_CHILDREN; - break; - } - case EINTR: { - /* - * An unblocked signal came in while waiting; just - * retry the wait(). - */ - continue; - } - default: { - /* - * Unexpected errno, so squawk! Note: Per the - * Linux docs, there are no errnos defined for - * wait() other than the two that are handled - * immediately above. - */ - LOGE("Error %d calling wait(): %s", errno, - strerror(errno)); - status = WAIT_STATUS_STRANGE_ERRNO; - break; - } - } - } - - env->CallVoidMethod(o, onExitMethod, pid, status); - if (env->ExceptionOccurred()) { - /* - * The callback threw, so break out of the loop and return, - * letting the exception percolate up. - */ - break; - } - } -} - -/** Close all open fds > 2 (i.e. everything but stdin/out/err), != skipFd. */ -static void closeNonStandardFds(int skipFd) { - // TODO: rather than close all these non-open files, we could look in /proc/self/fd. - struct rlimit rlimit; - getrlimit(RLIMIT_NOFILE, &rlimit); - const int max_fd = rlimit.rlim_max; - for (int fd = 3; fd < max_fd; ++fd) { - if (fd != skipFd -#ifdef ANDROID - && fd != androidSystemPropertiesFd -#endif - ) { - close(fd); - } - } -} - -#define PIPE_COUNT (4) // number of pipes used to communicate with child proc - -/** Closes all pipes in the given array. */ -static void closePipes(int pipes[], int skipFd) { - int i; - for (i = 0; i < PIPE_COUNT * 2; i++) { - int fd = pipes[i]; - if (fd == -1) { - return; - } - if (fd != skipFd) { - close(pipes[i]); - } - } -} - -/** Executes a command in a child process. */ -static pid_t executeProcess(JNIEnv* env, char** commands, char** environment, - const char* workingDirectory, jobject inDescriptor, - jobject outDescriptor, jobject errDescriptor, - jboolean redirectErrorStream) { - int i, result, error; - - // Create 4 pipes: stdin, stdout, stderr, and an exec() status pipe. - int pipes[PIPE_COUNT * 2] = { -1, -1, -1, -1, -1, -1, -1, -1 }; - for (i = 0; i < PIPE_COUNT; i++) { - if (pipe(pipes + i * 2) == -1) { - jniThrowIOException(env, errno); - closePipes(pipes, -1); - return -1; - } - } - int stdinIn = pipes[0]; - int stdinOut = pipes[1]; - int stdoutIn = pipes[2]; - int stdoutOut = pipes[3]; - int stderrIn = pipes[4]; - int stderrOut = pipes[5]; - int statusIn = pipes[6]; - int statusOut = pipes[7]; - - pid_t childPid = fork(); - - // If fork() failed... - if (childPid == -1) { - jniThrowIOException(env, errno); - closePipes(pipes, -1); - return -1; - } - - // If this is the child process... - if (childPid == 0) { - /* - * Note: We cannot malloc() or free() after this point! - * A no-longer-running thread may be holding on to the heap lock, and - * an attempt to malloc() or free() would result in deadlock. - */ - - // Replace stdin, out, and err with pipes. - dup2(stdinIn, 0); - dup2(stdoutOut, 1); - if (redirectErrorStream) { - dup2(stdoutOut, 2); - } else { - dup2(stderrOut, 2); - } - - // Close all but statusOut. This saves some work in the next step. - closePipes(pipes, statusOut); - - // Make statusOut automatically close if execvp() succeeds. - fcntl(statusOut, F_SETFD, FD_CLOEXEC); - - // Close remaining open fds with the exception of statusOut. - closeNonStandardFds(statusOut); - - // Switch to working directory. - if (workingDirectory != NULL) { - if (chdir(workingDirectory) == -1) { - goto execFailed; - } - } - - // Set up environment. - if (environment != NULL) { - environ = environment; - } - - // Execute process. By convention, the first argument in the arg array - // should be the command itself. In fact, I get segfaults when this - // isn't the case. - execvp(commands[0], commands); - - // If we got here, execvp() failed or the working dir was invalid. - execFailed: - error = errno; - write(statusOut, &error, sizeof(int)); - close(statusOut); - exit(error); - } - - // This is the parent process. - - // Close child's pipe ends. - close(stdinIn); - close(stdoutOut); - close(stderrOut); - close(statusOut); - - // Check status pipe for an error code. If execvp() succeeds, the other - // end of the pipe should automatically close, in which case, we'll read - // nothing. - int count = read(statusIn, &result, sizeof(int)); - close(statusIn); - if (count > 0) { - jniThrowIOException(env, result); - - close(stdoutIn); - close(stdinOut); - close(stderrIn); - - return -1; - } - - // Fill in file descriptor wrappers. - jniSetFileDescriptorOfFD(env, inDescriptor, stdoutIn); - jniSetFileDescriptorOfFD(env, outDescriptor, stdinOut); - jniSetFileDescriptorOfFD(env, errDescriptor, stderrIn); - - return childPid; -} - -/** Converts a Java String[] to a 0-terminated char**. */ -static char** convertStrings(JNIEnv* env, jobjectArray javaArray) { - if (javaArray == NULL) { - return NULL; - } - - char** array = NULL; - jsize length = env->GetArrayLength(javaArray); - array = (char**) malloc(sizeof(char*) * (length + 1)); - array[length] = 0; - jsize index; - for (index = 0; index < length; index++) { - jstring javaEntry = - (jstring) env->GetObjectArrayElement(javaArray, index); - char* entry = (char*) env->GetStringUTFChars(javaEntry, NULL); - array[index] = entry; - } - - return array; -} - -/** Frees a char** which was converted from a Java String[]. */ -static void freeStrings(JNIEnv* env, jobjectArray javaArray, char** array) { - if (javaArray == NULL) { - return; - } - - jsize length = env->GetArrayLength(javaArray); - jsize index; - for (index = 0; index < length; index++) { - jstring javaEntry = - (jstring) env->GetObjectArrayElement(javaArray, index); - env->ReleaseStringUTFChars(javaEntry, array[index]); - } - - free(array); -} - -/** - * Converts Java String[] to char** and delegates to executeProcess(). - */ -static pid_t java_lang_ProcessManager_exec( - JNIEnv* env, jclass clazz, jobjectArray javaCommands, - jobjectArray javaEnvironment, jstring javaWorkingDirectory, - jobject inDescriptor, jobject outDescriptor, jobject errDescriptor, - jboolean redirectErrorStream) { - - // Copy commands into char*[]. - char** commands = convertStrings(env, javaCommands); - - // Extract working directory string. - const char* workingDirectory = NULL; - if (javaWorkingDirectory != NULL) { - workingDirectory = env->GetStringUTFChars(javaWorkingDirectory, NULL); - } - - // Convert environment array. - char** environment = convertStrings(env, javaEnvironment); - - pid_t result = executeProcess( - env, commands, environment, workingDirectory, - inDescriptor, outDescriptor, errDescriptor, redirectErrorStream); - - // Temporarily clear exception so we can clean up. - jthrowable exception = env->ExceptionOccurred(); - env->ExceptionClear(); - - freeStrings(env, javaEnvironment, environment); - - // Clean up working directory string. - if (javaWorkingDirectory != NULL) { - env->ReleaseStringUTFChars(javaWorkingDirectory, workingDirectory); - } - - freeStrings(env, javaCommands, commands); - - // Re-throw exception if present. - if (exception != NULL) { - if (env->Throw(exception) < 0) { - LOGE("Error rethrowing exception!"); - } - } - - return result; -} - -/** - * Looks up Java members. - */ -static void java_lang_ProcessManager_staticInitialize(JNIEnv* env, - jclass clazz) { -#ifdef ANDROID - char* fdString = getenv("ANDROID_PROPERTY_WORKSPACE"); - if (fdString) { - androidSystemPropertiesFd = atoi(fdString); - } -#endif - - onExitMethod = env->GetMethodID(clazz, "onExit", "(II)V"); - if (onExitMethod == NULL) { - return; - } - - jclass fileDescriptorClass = env->FindClass("java/io/FileDescriptor"); - if (fileDescriptorClass == NULL) { - return; - } - descriptorField = env->GetFieldID(fileDescriptorClass, "descriptor", "I"); - if (descriptorField == NULL) { - return; - } -} - -static JNINativeMethod methods[] = { - { "close", "(Ljava/io/FileDescriptor;)V", (void*) java_lang_ProcessManager_close }, - { "kill", "(I)V", (void*) java_lang_ProcessManager_kill }, - { "staticInitialize", "()V", (void*) java_lang_ProcessManager_staticInitialize }, - { "watchChildren", "()V", (void*) java_lang_ProcessManager_watchChildren }, - { "exec", "([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Z)I", - (void*) java_lang_ProcessManager_exec }, -}; -int register_java_lang_ProcessManager(JNIEnv* env) { - return jniRegisterNativeMethods(env, "java/lang/ProcessManager", methods, NELEM(methods)); -} diff --git a/luni-kernel/src/main/native/java_lang_System.cpp b/luni-kernel/src/main/native/java_lang_System.cpp deleted file mode 100644 index b114dab..0000000 --- a/luni-kernel/src/main/native/java_lang_System.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "JNIHelp.h" - -#include <stdlib.h> -#include <string.h> - - -/* - * public static native String getEnvByName(String name) - * - * (Calling it plain "getenv" might confuse GDB if you try to put a breakpoint - * on the libc version.) - */ -static jstring java_getEnvByName(JNIEnv* env, jclass, jstring nameStr) { - jstring valueStr = NULL; - - if (nameStr != NULL) { - const char* name = env->GetStringUTFChars(nameStr, NULL); - const char* val = getenv(name); - if (val != NULL) { - valueStr = env->NewStringUTF(val); - } - env->ReleaseStringUTFChars(nameStr, name); - } else { - jniThrowNullPointerException(env, NULL); - } - - return valueStr; -} - -/* - * Pointer to complete environment, from Posix. - */ -extern char** environ; - -/* - * public static native String getEnvByIndex() - * - * (Calling it plain "getenv" might confuse GDB if you try to put a breakpoint - * on the libc version.) - */ -static jstring java_getEnvByIndex(JNIEnv* env, jclass, jint index) { - jstring valueStr = NULL; - - char* entry = environ[index]; - if (entry != NULL) { - valueStr = env->NewStringUTF(entry); - } - - return valueStr; -} - -/* - * public static native String setFieldImpl() - * - * Sets a field via JNI. Used for the standard streams, which are r/o - * otherwise. - */ -static void java_setFieldImpl(JNIEnv* env, jclass clazz, - jstring name, jstring sig, jobject object) { - const char* fieldName = env->GetStringUTFChars(name, NULL); - const char* fieldSig = env->GetStringUTFChars(sig, NULL); - - jfieldID fieldID = env->GetStaticFieldID(clazz, fieldName, fieldSig); - env->SetStaticObjectField(clazz, fieldID, object); - - env->ReleaseStringUTFChars(name, fieldName); - env->ReleaseStringUTFChars(sig, fieldSig); -} - -static JNINativeMethod gMethods[] = { - { "getEnvByName", "(Ljava/lang/String;)Ljava/lang/String;", (void*) java_getEnvByName }, - { "getEnvByIndex", "(I)Ljava/lang/String;", (void*) java_getEnvByIndex }, - { "setFieldImpl", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V", (void*) java_setFieldImpl }, -}; -int register_java_lang_System(JNIEnv* env) { - return jniRegisterNativeMethods(env, "java/lang/System", gMethods, NELEM(gMethods)); -} diff --git a/luni-kernel/src/main/native/sub.mk b/luni-kernel/src/main/native/sub.mk deleted file mode 100644 index 7f6417b..0000000 --- a/luni-kernel/src/main/native/sub.mk +++ /dev/null @@ -1,18 +0,0 @@ -# This file is included by the top-level libcore Android.mk. -# It's not a normal makefile, so we don't include CLEAR_VARS -# or BUILD_*_LIBRARY. - -LOCAL_SRC_FILES := \ - java_lang_ProcessManager.cpp \ - java_lang_System.cpp \ - Register.cpp - -LOCAL_C_INCLUDES += - -# Any shared/static libs that are listed here must also -# be listed in libs/nativehelper/Android.mk. -# TODO: fix this requirement - -LOCAL_SHARED_LIBRARIES += - -LOCAL_STATIC_LIBRARIES += diff --git a/luni-kernel/src/test/java/java/lang/reflect/AllTests.java b/luni-kernel/src/test/java/java/lang/reflect/AllTests.java deleted file mode 100644 index 8d99672..0000000 --- a/luni-kernel/src/test/java/java/lang/reflect/AllTests.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang.reflect; - -import junit.framework.Test; -import junit.framework.TestSuite; - -public class AllTests { - public static final Test suite() { - TestSuite suite = new TestSuite(); - suite.addTestSuite(java.lang.reflect.ConstructorTest.class); - suite.addTestSuite(java.lang.reflect.MethodTest.class); - return suite; - } -} diff --git a/luni-kernel/src/test/java/java/lang/reflect/ConstructorTest.java b/luni-kernel/src/test/java/java/lang/reflect/ConstructorTest.java deleted file mode 100644 index e2672a8..0000000 --- a/luni-kernel/src/test/java/java/lang/reflect/ConstructorTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang.reflect; - -public class ConstructorTest extends junit.framework.TestCase { - public void test_getExceptionTypes() throws Exception { - Constructor<?> constructor = ConstructorTestHelper.class.getConstructor(new Class[0]); - Class[] exceptions = constructor.getExceptionTypes(); - assertEquals(1, exceptions.length); - assertEquals(IndexOutOfBoundsException.class, exceptions[0]); - // Check that corrupting our array doesn't affect other callers. - exceptions[0] = NullPointerException.class; - exceptions = constructor.getExceptionTypes(); - assertEquals(1, exceptions.length); - assertEquals(IndexOutOfBoundsException.class, exceptions[0]); - } - - public void test_getParameterTypes() throws Exception { - Class[] expectedParameters = new Class[] { Object.class }; - Constructor<?> constructor = ConstructorTestHelper.class.getConstructor(expectedParameters); - Class[] parameters = constructor.getParameterTypes(); - assertEquals(1, parameters.length); - assertEquals(expectedParameters[0], parameters[0]); - // Check that corrupting our array doesn't affect other callers. - parameters[0] = String.class; - parameters = constructor.getParameterTypes(); - assertEquals(1, parameters.length); - assertEquals(expectedParameters[0], parameters[0]); - } - - static class ConstructorTestHelper { - public ConstructorTestHelper() throws IndexOutOfBoundsException { } - public ConstructorTestHelper(Object o) { } - } -} diff --git a/luni-kernel/src/test/java/java/lang/reflect/MethodTest.java b/luni-kernel/src/test/java/java/lang/reflect/MethodTest.java deleted file mode 100644 index ed41de9..0000000 --- a/luni-kernel/src/test/java/java/lang/reflect/MethodTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang.reflect; - -public class MethodTest extends junit.framework.TestCase { - public void test_getExceptionTypes() throws Exception { - Method method = MethodTestHelper.class.getMethod("m1", new Class[0]); - Class[] exceptions = method.getExceptionTypes(); - assertEquals(1, exceptions.length); - assertEquals(IndexOutOfBoundsException.class, exceptions[0]); - // Check that corrupting our array doesn't affect other callers. - exceptions[0] = NullPointerException.class; - exceptions = method.getExceptionTypes(); - assertEquals(1, exceptions.length); - assertEquals(IndexOutOfBoundsException.class, exceptions[0]); - } - - public void test_getParameterTypes() throws Exception { - Class[] expectedParameters = new Class[] { Object.class }; - Method method = MethodTestHelper.class.getMethod("m2", expectedParameters); - Class[] parameters = method.getParameterTypes(); - assertEquals(1, parameters.length); - assertEquals(expectedParameters[0], parameters[0]); - // Check that corrupting our array doesn't affect other callers. - parameters[0] = String.class; - parameters = method.getParameterTypes(); - assertEquals(1, parameters.length); - assertEquals(expectedParameters[0], parameters[0]); - } - - static class MethodTestHelper { - public void m1() throws IndexOutOfBoundsException { } - public void m2(Object o) { } - } -} diff --git a/luni-kernel/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/AllTests.java b/luni-kernel/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/AllTests.java deleted file mode 100644 index e9cf80e..0000000 --- a/luni-kernel/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/AllTests.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package tests.api.org.apache.harmony.kernel.dalvik; - -import junit.framework.Test; -import junit.framework.TestSuite; - -public class AllTests { - public static final Test suite() { - TestSuite suite = new TestSuite(); - suite.addTestSuite(tests.api.org.apache.harmony.kernel.dalvik.ThreadsTest.class); - return suite; - } -} diff --git a/luni-kernel/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/ThreadsTest.java b/luni-kernel/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/ThreadsTest.java deleted file mode 100644 index 8ba2445..0000000 --- a/luni-kernel/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/ThreadsTest.java +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package tests.api.org.apache.harmony.kernel.dalvik; - -import java.lang.reflect.Field; - -import junit.framework.Assert; -import junit.framework.TestCase; -import sun.misc.Unsafe; - -/** - * Tests for the <code>park()</code> functionality of {@link Unsafe}. - */ -public class ThreadsTest extends TestCase { - private static Unsafe UNSAFE = null; - private static RuntimeException INITIALIZEFAILED = null; - - static { - /* - * Set up {@link #UNSAFE}. This subverts the access check to - * get the unique Unsafe instance. We can do this because - * there's no security manager installed when running the - * test. - */ - try { - Field field = Unsafe.class.getDeclaredField("THE_ONE"); - field.setAccessible(true); - - UNSAFE = (Unsafe) field.get(null); - } catch (NoSuchFieldException ex) { - INITIALIZEFAILED = new RuntimeException(ex); - } catch (IllegalAccessException ex) { - INITIALIZEFAILED = new RuntimeException(ex); - } - } - - /** Test the case where the park times out. */ - public void test_parkFor_1() { - Parker parker = new Parker(false, 500); - Thread parkerThread = new Thread(parker); - Thread waiterThread = - new Thread(new WaitAndUnpark(1000, parkerThread)); - - parkerThread.start(); - waiterThread.start(); - parker.assertDurationIsInRange(500); - } - - /** Test the case where the unpark happens before the timeout. */ - public void test_parkFor_2() { - Parker parker = new Parker(false, 1000); - Thread parkerThread = new Thread(parker); - Thread waiterThread = - new Thread(new WaitAndUnpark(300, parkerThread)); - - parkerThread.start(); - waiterThread.start(); - parker.assertDurationIsInRange(300); - } - - /** Test the case where the thread is preemptively unparked. */ - public void test_parkFor_3() { - Parker parker = new Parker(false, 1000); - Thread parkerThread = new Thread(parker); - - UNSAFE.unpark(parkerThread); - parkerThread.start(); - parker.assertDurationIsInRange(0); - } - - /** Test the case where the park times out. */ - public void test_parkUntil_1() { - Parker parker = new Parker(true, 500); - Thread parkerThread = new Thread(parker); - Thread waiterThread = - new Thread(new WaitAndUnpark(1000, parkerThread)); - - parkerThread.start(); - waiterThread.start(); - parker.assertDurationIsInRange(500); - } - - /** Test the case where the unpark happens before the timeout. */ - public void test_parkUntil_2() { - Parker parker = new Parker(true, 1000); - Thread parkerThread = new Thread(parker); - Thread waiterThread = - new Thread(new WaitAndUnpark(300, parkerThread)); - - parkerThread.start(); - waiterThread.start(); - parker.assertDurationIsInRange(300); - } - - /** Test the case where the thread is preemptively unparked. */ - public void test_parkUntil_3() { - Parker parker = new Parker(true, 1000); - Thread parkerThread = new Thread(parker); - - UNSAFE.unpark(parkerThread); - parkerThread.start(); - parker.assertDurationIsInRange(0); - } - - // TODO: Add more tests. - - /** - * Helper <code>Runnable</code> for tests, which parks for or until - * the indicated value, noting the duration of time actually parked. - */ - private static class Parker implements Runnable { - /** whether {@link #amount} is milliseconds to wait in an - * absolute fashion (<code>true</code>) or nanoseconds to wait - * in a relative fashion (<code>false</code>) */ - private final boolean absolute; - - /** amount to wait (see above) */ - private final long amount; - - /** whether the run has completed */ - private boolean completed; - - /** recorded start time */ - private long startMillis; - - /** recorded end time */ - private long endMillis; - - /** - * Construct an instance. - * - * @param absolute whether to use an absolute time or not; in - * either case, this constructor takes a duration to park for - * @param parkMillis the number of milliseconds to be parked - */ - public Parker(boolean absolute, long parkMillis) { - this.absolute = absolute; - - // Multiply by 1000000 because parkFor() takes nanoseconds. - this.amount = absolute ? parkMillis : parkMillis * 1000000; - } - - public void run() { - boolean absolute = this.absolute; - long amount = this.amount; - long start = System.currentTimeMillis(); - - if (absolute) { - UNSAFE.park(true, start + amount); - } else { - UNSAFE.park(false, amount); - } - - long end = System.currentTimeMillis(); - - synchronized (this) { - startMillis = start; - endMillis = end; - completed = true; - notifyAll(); - } - } - - /** - * Wait for the test to complete and return the duration. - * - * @param maxWaitMillis the maximum amount of time to - * wait for the test to complete - * @return the duration in milliseconds - */ - public long getDurationMillis(long maxWaitMillis) { - synchronized (this) { - if (! completed) { - try { - wait(maxWaitMillis); - } catch (InterruptedException ex) { - // Ignore it. - } - if (! completed) { - Assert.fail("parker hanging"); - } - } - - return endMillis - startMillis; - } - } - - /** - * Asserts that the actual duration is within 5% of the - * given expected time. - * - * @param expectedMillis the expected duration, in milliseconds - */ - public void assertDurationIsInRange(long expectedMillis) { - /* - * Allow a bit more slop for the maximum on "expected - * instantaneous" results. - */ - long minimum = (long) ((double) expectedMillis * 0.95); - long maximum = - Math.max((long) ((double) expectedMillis * 1.05), 10); - long waitMillis = Math.max(expectedMillis * 10, 10); - long duration = getDurationMillis(waitMillis); - - if (duration < minimum) { - Assert.fail("expected duration: " + expectedMillis + - "; actual too short: " + duration); - } else if (duration > maximum) { - Assert.fail("expected duration: " + expectedMillis + - "; actual too long: " + duration); - } - } - } - - /** - * Helper <code>Runnable</code> for tests, which waits for the - * specified amount of time and then unparks an indicated thread. - */ - private static class WaitAndUnpark implements Runnable { - private final long waitMillis; - private final Thread thread; - - public WaitAndUnpark(long waitMillis, Thread thread) { - this.waitMillis = waitMillis; - this.thread = thread; - } - - public void run() { - try { - Thread.sleep(waitMillis); - } catch (InterruptedException ex) { - throw new RuntimeException("shouldn't happen", ex); - } - - UNSAFE.unpark(thread); - } - } - - @Override - protected void setUp() throws Exception { - if (INITIALIZEFAILED != null) { - throw INITIALIZEFAILED; - } - } -} |