diff options
author | 2016-04-04 19:50:14 -0700 | |
---|---|---|
committer | 2016-04-04 19:50:14 -0700 | |
commit | 1133db79350060158f99210c56f111c6dad43563 (patch) | |
tree | c84b4ae2df13a32539645c0904f08c874c20ae31 | |
parent | a07be75830af60ce50aba357e8de066e849aa21c (diff) |
Remove AnnotationAccess and its remaining uses.
Art side of this change. Adds a test to ensure annotations not marked
for runtime retention can't be seen at runtime.
Bug: 27912552
Change-Id: I078069b7b3cb72bfe7d0b9ea61e527fee04d56a3
-rw-r--r-- | runtime/Android.mk | 1 | ||||
-rw-r--r-- | runtime/dex_file.cc | 20 | ||||
-rw-r--r-- | runtime/dex_file.h | 4 | ||||
-rw-r--r-- | runtime/native/java_lang_Class.cc | 12 | ||||
-rw-r--r-- | runtime/native/java_lang_reflect_AbstractMethod.cc | 78 | ||||
-rw-r--r-- | runtime/native/java_lang_reflect_AbstractMethod.h | 28 | ||||
-rw-r--r-- | runtime/native/java_lang_reflect_Method.cc | 28 | ||||
-rw-r--r-- | runtime/runtime.cc | 2 | ||||
-rw-r--r-- | test/005-annotations/expected.txt | 1 | ||||
-rw-r--r-- | test/005-annotations/src/android/test/anno/TestAnnotations.java | 3 | ||||
-rw-r--r-- | test/031-class-attributes/src/ClassAttrs.java | 10 |
11 files changed, 156 insertions, 31 deletions
diff --git a/runtime/Android.mk b/runtime/Android.mk index 542a2c4bdb..c85907987b 100644 --- a/runtime/Android.mk +++ b/runtime/Android.mk @@ -149,6 +149,7 @@ LIBART_COMMON_SRC_FILES := \ native/java_lang_VMClassLoader.cc \ native/java_lang_ref_FinalizerReference.cc \ native/java_lang_ref_Reference.cc \ + native/java_lang_reflect_AbstractMethod.cc \ native/java_lang_reflect_Array.cc \ native/java_lang_reflect_Constructor.cc \ native/java_lang_reflect_Field.cc \ diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc index e63eaa2715..63f3f08bad 100644 --- a/runtime/dex_file.cc +++ b/runtime/dex_file.cc @@ -1351,6 +1351,17 @@ mirror::ObjectArray<mirror::Object>* DexFile::GetParameterAnnotations(ArtMethod* return ProcessAnnotationSetRefList(method_class, set_ref_list, size); } +mirror::ObjectArray<mirror::String>* DexFile::GetSignatureAnnotationForMethod(ArtMethod* method) + const { + const AnnotationSetItem* annotation_set = FindAnnotationSetForMethod(method); + if (annotation_set == nullptr) { + return nullptr; + } + StackHandleScope<1> hs(Thread::Current()); + Handle<mirror::Class> method_class(hs.NewHandle(method->GetDeclaringClass())); + return GetSignatureValue(method_class, annotation_set); +} + bool DexFile::IsMethodAnnotationPresent(ArtMethod* method, Handle<mirror::Class> annotation_class) const { const AnnotationSetItem* annotation_set = FindAnnotationSetForMethod(method); @@ -1548,6 +1559,15 @@ bool DexFile::GetInnerClassFlags(Handle<mirror::Class> klass, uint32_t* flags) c return true; } +mirror::ObjectArray<mirror::String>* DexFile::GetSignatureAnnotationForClass( + Handle<mirror::Class> klass) const { + const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass); + if (annotation_set == nullptr) { + return nullptr; + } + return GetSignatureValue(klass, annotation_set); +} + bool DexFile::IsClassAnnotationPresent(Handle<mirror::Class> klass, Handle<mirror::Class> annotation_class) const { const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass); diff --git a/runtime/dex_file.h b/runtime/dex_file.h index 1456636c3c..3a28422067 100644 --- a/runtime/dex_file.h +++ b/runtime/dex_file.h @@ -991,6 +991,8 @@ class DexFile { SHARED_REQUIRES(Locks::mutator_lock_); mirror::ObjectArray<mirror::Object>* GetParameterAnnotations(ArtMethod* method) const SHARED_REQUIRES(Locks::mutator_lock_); + mirror::ObjectArray<mirror::String>* GetSignatureAnnotationForMethod(ArtMethod* method) const + SHARED_REQUIRES(Locks::mutator_lock_); bool IsMethodAnnotationPresent(ArtMethod* method, Handle<mirror::Class> annotation_class) const SHARED_REQUIRES(Locks::mutator_lock_); @@ -1013,6 +1015,8 @@ class DexFile { SHARED_REQUIRES(Locks::mutator_lock_); bool GetInnerClassFlags(Handle<mirror::Class> klass, uint32_t* flags) const SHARED_REQUIRES(Locks::mutator_lock_); + mirror::ObjectArray<mirror::String>* GetSignatureAnnotationForClass(Handle<mirror::Class> klass) + const SHARED_REQUIRES(Locks::mutator_lock_); bool IsClassAnnotationPresent(Handle<mirror::Class> klass, Handle<mirror::Class> annotation_class) const SHARED_REQUIRES(Locks::mutator_lock_); diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc index bf24de5284..19aa0dd1e5 100644 --- a/runtime/native/java_lang_Class.cc +++ b/runtime/native/java_lang_Class.cc @@ -545,6 +545,17 @@ static jstring Class_getInnerClassName(JNIEnv* env, jobject javaThis) { return soa.AddLocalReference<jstring>(class_name); } +static jobjectArray Class_getSignatureAnnotation(JNIEnv* env, jobject javaThis) { + ScopedFastNativeObjectAccess soa(env); + StackHandleScope<1> hs(soa.Self()); + Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis))); + if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) { + return nullptr; + } + return soa.AddLocalReference<jobjectArray>( + klass->GetDexFile().GetSignatureAnnotationForClass(klass)); +} + static jboolean Class_isAnonymousClass(JNIEnv* env, jobject javaThis) { ScopedFastNativeObjectAccess soa(env); StackHandleScope<1> hs(soa.Self()); @@ -692,6 +703,7 @@ static JNINativeMethod gMethods[] = { NATIVE_METHOD(Class, getNameNative, "!()Ljava/lang/String;"), NATIVE_METHOD(Class, getProxyInterfaces, "!()[Ljava/lang/Class;"), NATIVE_METHOD(Class, getPublicDeclaredFields, "!()[Ljava/lang/reflect/Field;"), + NATIVE_METHOD(Class, getSignatureAnnotation, "!()[Ljava/lang/String;"), NATIVE_METHOD(Class, isAnonymousClass, "!()Z"), NATIVE_METHOD(Class, isDeclaredAnnotationPresent, "!(Ljava/lang/Class;)Z"), NATIVE_METHOD(Class, newInstance, "!()Ljava/lang/Object;"), diff --git a/runtime/native/java_lang_reflect_AbstractMethod.cc b/runtime/native/java_lang_reflect_AbstractMethod.cc new file mode 100644 index 0000000000..7e11c11438 --- /dev/null +++ b/runtime/native/java_lang_reflect_AbstractMethod.cc @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2016 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 "java_lang_reflect_AbstractMethod.h" + +#include "art_method-inl.h" +#include "jni_internal.h" +#include "mirror/class-inl.h" +#include "mirror/object-inl.h" +#include "mirror/object_array-inl.h" +#include "reflection.h" +#include "scoped_fast_native_object_access.h" +#include "well_known_classes.h" + +namespace art { + +static jobjectArray AbstractMethod_getDeclaredAnnotations(JNIEnv* env, jobject javaMethod) { + ScopedFastNativeObjectAccess soa(env); + ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod); + if (method->GetDeclaringClass()->IsProxyClass()) { + // Return an empty array instead of a null pointer. + mirror::Class* annotation_array_class = + soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_annotation_Annotation__array); + mirror::ObjectArray<mirror::Object>* empty_array = + mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), annotation_array_class, 0); + return soa.AddLocalReference<jobjectArray>(empty_array); + } + return soa.AddLocalReference<jobjectArray>(method->GetDexFile()->GetAnnotationsForMethod(method)); +} + +static jobjectArray AbstractMethod_getSignatureAnnotation(JNIEnv* env, jobject javaMethod) { + ScopedFastNativeObjectAccess soa(env); + ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod); + if (method->GetDeclaringClass()->IsProxyClass()) { + return nullptr; + } + StackHandleScope<1> hs(soa.Self()); + return soa.AddLocalReference<jobjectArray>( + method->GetDexFile()->GetSignatureAnnotationForMethod(method)); +} + + +static jboolean AbstractMethod_isAnnotationPresentNative(JNIEnv* env, jobject javaMethod, + jclass annotationType) { + ScopedFastNativeObjectAccess soa(env); + ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod); + if (method->GetDeclaringClass()->IsProxyClass()) { + return false; + } + StackHandleScope<1> hs(soa.Self()); + Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class*>(annotationType))); + return method->GetDexFile()->IsMethodAnnotationPresent(method, klass); +} + +static JNINativeMethod gMethods[] = { + NATIVE_METHOD(AbstractMethod, getDeclaredAnnotations, "!()[Ljava/lang/annotation/Annotation;"), + NATIVE_METHOD(AbstractMethod, getSignatureAnnotation, "!()[Ljava/lang/String;"), + NATIVE_METHOD(AbstractMethod, isAnnotationPresentNative, "!(Ljava/lang/Class;)Z"), +}; + +void register_java_lang_reflect_AbstractMethod(JNIEnv* env) { + REGISTER_NATIVE_METHODS("java/lang/reflect/AbstractMethod"); +} + +} // namespace art diff --git a/runtime/native/java_lang_reflect_AbstractMethod.h b/runtime/native/java_lang_reflect_AbstractMethod.h new file mode 100644 index 0000000000..222e5a05d0 --- /dev/null +++ b/runtime/native/java_lang_reflect_AbstractMethod.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2016 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. + */ + +#ifndef ART_RUNTIME_NATIVE_JAVA_LANG_REFLECT_ABSTRACTMETHOD_H_ +#define ART_RUNTIME_NATIVE_JAVA_LANG_REFLECT_ABSTRACTMETHOD_H_ + +#include <jni.h> + +namespace art { + +void register_java_lang_reflect_AbstractMethod(JNIEnv* env); + +} // namespace art + +#endif // ART_RUNTIME_NATIVE_JAVA_LANG_REFLECT_ABSTRACTMETHOD_H_ diff --git a/runtime/native/java_lang_reflect_Method.cc b/runtime/native/java_lang_reflect_Method.cc index d7cf62e994..78999c2865 100644 --- a/runtime/native/java_lang_reflect_Method.cc +++ b/runtime/native/java_lang_reflect_Method.cc @@ -41,20 +41,6 @@ static jobject Method_getAnnotationNative(JNIEnv* env, jobject javaMethod, jclas method->GetDexFile()->GetAnnotationForMethod(method, klass)); } -static jobjectArray Method_getDeclaredAnnotations(JNIEnv* env, jobject javaMethod) { - ScopedFastNativeObjectAccess soa(env); - ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod); - if (method->GetDeclaringClass()->IsProxyClass()) { - // Return an empty array instead of a null pointer. - mirror::Class* annotation_array_class = - soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_annotation_Annotation__array); - mirror::ObjectArray<mirror::Object>* empty_array = - mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), annotation_array_class, 0); - return soa.AddLocalReference<jobjectArray>(empty_array); - } - return soa.AddLocalReference<jobjectArray>(method->GetDexFile()->GetAnnotationsForMethod(method)); -} - static jobject Method_getDefaultValue(JNIEnv* env, jobject javaMethod) { ScopedFastNativeObjectAccess soa(env); ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod); @@ -116,27 +102,13 @@ static jobject Method_invoke(JNIEnv* env, jobject javaMethod, jobject javaReceiv return InvokeMethod(soa, javaMethod, javaReceiver, javaArgs); } -static jboolean Method_isAnnotationPresentNative(JNIEnv* env, jobject javaMethod, - jclass annotationType) { - ScopedFastNativeObjectAccess soa(env); - ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod); - if (method->GetDeclaringClass()->IsProxyClass()) { - return false; - } - StackHandleScope<1> hs(soa.Self()); - Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class*>(annotationType))); - return method->GetDexFile()->IsMethodAnnotationPresent(method, klass); -} - static JNINativeMethod gMethods[] = { NATIVE_METHOD(Method, getAnnotationNative, "!(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;"), - NATIVE_METHOD(Method, getDeclaredAnnotations, "!()[Ljava/lang/annotation/Annotation;"), NATIVE_METHOD(Method, getDefaultValue, "!()Ljava/lang/Object;"), NATIVE_METHOD(Method, getExceptionTypes, "!()[Ljava/lang/Class;"), NATIVE_METHOD(Method, getParameterAnnotationsNative, "!()[[Ljava/lang/annotation/Annotation;"), NATIVE_METHOD(Method, invoke, "!(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;"), - NATIVE_METHOD(Method, isAnnotationPresentNative, "!(Ljava/lang/Class;)Z"), }; void register_java_lang_reflect_Method(JNIEnv* env) { diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 630d101653..d3454e891f 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -103,6 +103,7 @@ #include "native/java_lang_VMClassLoader.h" #include "native/java_lang_ref_FinalizerReference.h" #include "native/java_lang_ref_Reference.h" +#include "native/java_lang_reflect_AbstractMethod.h" #include "native/java_lang_reflect_Array.h" #include "native/java_lang_reflect_Constructor.h" #include "native/java_lang_reflect_Field.h" @@ -1349,6 +1350,7 @@ void Runtime::RegisterRuntimeNativeMethods(JNIEnv* env) { register_java_lang_DexCache(env); register_java_lang_Object(env); register_java_lang_ref_FinalizerReference(env); + register_java_lang_reflect_AbstractMethod(env); register_java_lang_reflect_Array(env); register_java_lang_reflect_Constructor(env); register_java_lang_reflect_Field(env); diff --git a/test/005-annotations/expected.txt b/test/005-annotations/expected.txt index 3d9fd8bcfc..ee5b0c74c5 100644 --- a/test/005-annotations/expected.txt +++ b/test/005-annotations/expected.txt @@ -93,6 +93,7 @@ annotations on TYPE class android.test.anno.FullyNoted(1): --> nombre is 'fubar' SimplyNoted.get(AnnoSimpleType) = @android.test.anno.AnnoSimpleType() +SimplyNoted.get(AnnoSimpleTypeInvis) = null SubNoted.get(AnnoSimpleType) = @android.test.anno.AnnoSimpleType() Package annotations: diff --git a/test/005-annotations/src/android/test/anno/TestAnnotations.java b/test/005-annotations/src/android/test/anno/TestAnnotations.java index bc89f1682c..d36d43e1ba 100644 --- a/test/005-annotations/src/android/test/anno/TestAnnotations.java +++ b/test/005-annotations/src/android/test/anno/TestAnnotations.java @@ -185,6 +185,9 @@ public class TestAnnotations { // this is expected to be non-null Annotation anno = SimplyNoted.class.getAnnotation(AnnoSimpleType.class); System.out.println("SimplyNoted.get(AnnoSimpleType) = " + anno); + // this is expected to be null + anno = SimplyNoted.class.getAnnotation(AnnoSimpleTypeInvis.class); + System.out.println("SimplyNoted.get(AnnoSimpleTypeInvis) = " + anno); // this is non-null if the @Inherited tag is present anno = SubNoted.class.getAnnotation(AnnoSimpleType.class); System.out.println("SubNoted.get(AnnoSimpleType) = " + anno); diff --git a/test/031-class-attributes/src/ClassAttrs.java b/test/031-class-attributes/src/ClassAttrs.java index c2e41c5b3e..38bd525b86 100644 --- a/test/031-class-attributes/src/ClassAttrs.java +++ b/test/031-class-attributes/src/ClassAttrs.java @@ -1,6 +1,7 @@ import otherpackage.OtherPackageClass; import java.io.Serializable; +import java.lang.reflect.AbstractMethod; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Constructor; import java.lang.reflect.Field; @@ -221,8 +222,11 @@ public class ClassAttrs { public static String getSignatureAttribute(Object obj) { Method method; try { - Class c = Class.forName("libcore.reflect.AnnotationAccess"); - method = c.getDeclaredMethod("getSignature", java.lang.reflect.AnnotatedElement.class); + Class c = obj.getClass(); + if (c == Method.class || c == Constructor.class) { + c = AbstractMethod.class; + } + method = c.getDeclaredMethod("getSignatureAttribute"); method.setAccessible(true); } catch (Exception ex) { ex.printStackTrace(); @@ -230,7 +234,7 @@ public class ClassAttrs { } try { - return (String) method.invoke(null, obj); + return (String) method.invoke(obj); } catch (IllegalAccessException ex) { throw new RuntimeException(ex); } catch (InvocationTargetException ex) { |