summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/native/java_lang_Class.cc5
-rw-r--r--runtime/native/java_lang_reflect_Field.cc6
-rw-r--r--runtime/reflection.cc6
-rw-r--r--runtime/reflection.h2
-rw-r--r--test/046-reflect/src/Main.java65
5 files changed, 53 insertions, 31 deletions
diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc
index 3cb6b367f0..0ca9d24824 100644
--- a/runtime/native/java_lang_Class.cc
+++ b/runtime/native/java_lang_Class.cc
@@ -253,7 +253,10 @@ static jobject Class_getDeclaredField(JNIEnv* env, jobject javaThis, jstring nam
mirror::Field* result = GetDeclaredField(soa.Self(), klass, name_string);
if (result == nullptr) {
std::string name_str = name_string->ToModifiedUtf8();
- soa.Self()->ThrowNewException("Ljava/lang/NoSuchFieldException;", name_str.c_str());
+ // We may have a pending exception if we failed to resolve.
+ if (!soa.Self()->IsExceptionPending()) {
+ soa.Self()->ThrowNewException("Ljava/lang/NoSuchFieldException;", name_str.c_str());
+ }
return nullptr;
}
return soa.AddLocalReference<jobject>(result);
diff --git a/runtime/native/java_lang_reflect_Field.cc b/runtime/native/java_lang_reflect_Field.cc
index 0fe78b3281..721b7a3b76 100644
--- a/runtime/native/java_lang_reflect_Field.cc
+++ b/runtime/native/java_lang_reflect_Field.cc
@@ -44,7 +44,7 @@ ALWAYS_INLINE inline static bool VerifyFieldAccess(Thread* self, mirror::Field*
}
mirror::Class* calling_class = nullptr;
if (!VerifyAccess(self, obj, field->GetDeclaringClass(), field->GetAccessFlags(),
- &calling_class)) {
+ &calling_class, 1)) {
ThrowIllegalAccessException(
StringPrintf("Class %s cannot access %s field %s of class %s",
calling_class == nullptr ? "null" : PrettyClass(calling_class).c_str(),
@@ -276,9 +276,9 @@ ALWAYS_INLINE inline static void SetFieldValue(mirror::Object* o, mirror::Field*
break;
case Primitive::kPrimShort:
if (is_volatile) {
- o->SetFieldShortVolatile<false>(offset, new_value.GetZ());
+ o->SetFieldShortVolatile<false>(offset, new_value.GetS());
} else {
- o->SetFieldShort<false>(offset, new_value.GetZ());
+ o->SetFieldShort<false>(offset, new_value.GetS());
}
break;
case Primitive::kPrimNot:
diff --git a/runtime/reflection.cc b/runtime/reflection.cc
index d845e402e7..4e94de4139 100644
--- a/runtime/reflection.cc
+++ b/runtime/reflection.cc
@@ -587,7 +587,7 @@ jobject InvokeMethod(const ScopedObjectAccessAlreadyRunnable& soa, jobject javaM
// If method is not set to be accessible, verify it can be accessed by the caller.
mirror::Class* calling_class = nullptr;
if (!accessible && !VerifyAccess(soa.Self(), receiver, declaring_class, m->GetAccessFlags(),
- &calling_class)) {
+ &calling_class, 2)) {
ThrowIllegalAccessException(
StringPrintf("Class %s cannot access %s method %s of class %s",
calling_class == nullptr ? "null" : PrettyClass(calling_class).c_str(),
@@ -794,11 +794,11 @@ bool UnboxPrimitiveForResult(mirror::Object* o,
}
bool VerifyAccess(Thread* self, mirror::Object* obj, mirror::Class* declaring_class,
- uint32_t access_flags, mirror::Class** calling_class) {
+ uint32_t access_flags, mirror::Class** calling_class, size_t num_frames) {
if ((access_flags & kAccPublic) != 0) {
return true;
}
- NthCallerVisitor visitor(self, 2);
+ NthCallerVisitor visitor(self, num_frames);
visitor.WalkStack();
if (UNLIKELY(visitor.caller == nullptr)) {
// The caller is an attached native thread.
diff --git a/runtime/reflection.h b/runtime/reflection.h
index 6bef664ca4..ff970e5507 100644
--- a/runtime/reflection.h
+++ b/runtime/reflection.h
@@ -73,7 +73,7 @@ ALWAYS_INLINE bool VerifyObjectIsClass(mirror::Object* o, mirror::Class* c)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
bool VerifyAccess(Thread* self, mirror::Object* obj, mirror::Class* declaring_class,
- uint32_t access_flags, mirror::Class** calling_class)
+ uint32_t access_flags, mirror::Class** calling_class, size_t num_frames)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void InvalidReceiverError(mirror::Object* o, mirror::Class* c)
diff --git a/test/046-reflect/src/Main.java b/test/046-reflect/src/Main.java
index 5c6ca135b7..59f7001a58 100644
--- a/test/046-reflect/src/Main.java
+++ b/test/046-reflect/src/Main.java
@@ -720,6 +720,10 @@ public class Main {
}
}
+ static void checkPrivateFieldAccess() {
+ (new OtherClass()).test();
+ }
+
public static void main(String[] args) throws Exception {
Main test = new Main();
test.run();
@@ -733,6 +737,7 @@ public class Main {
checkUnique();
checkParametrizedTypeEqualsAndHashCode();
checkGenericArrayTypeEqualsAndHashCode();
+ checkPrivateFieldAccess();
}
}
@@ -804,41 +809,41 @@ class Target extends SuperTarget {
}
class FieldNoisyInit {
- static {
- System.out.println("FieldNoisyInit is initializing");
- //Throwable th = new Throwable();
- //th.printStackTrace();
- }
+ static {
+ System.out.println("FieldNoisyInit is initializing");
+ //Throwable th = new Throwable();
+ //th.printStackTrace();
+ }
}
class FieldNoisyInitUser {
- static {
- System.out.println("FieldNoisyInitUser is initializing");
- }
- public static int staticField;
- public static FieldNoisyInit noisy;
+ static {
+ System.out.println("FieldNoisyInitUser is initializing");
+ }
+ public static int staticField;
+ public static FieldNoisyInit noisy;
}
class MethodNoisyInit {
- static {
- System.out.println("MethodNoisyInit is initializing");
- //Throwable th = new Throwable();
- //th.printStackTrace();
- }
+ static {
+ System.out.println("MethodNoisyInit is initializing");
+ //Throwable th = new Throwable();
+ //th.printStackTrace();
+ }
}
class MethodNoisyInitUser {
- static {
- System.out.println("MethodNoisyInitUser is initializing");
- }
- public static void staticMethod() {}
- public void createMethodNoisyInit(MethodNoisyInit ni) {}
+ static {
+ System.out.println("MethodNoisyInitUser is initializing");
+ }
+ public static void staticMethod() {}
+ public void createMethodNoisyInit(MethodNoisyInit ni) {}
}
class Thrower {
- public Thrower() throws UnsupportedOperationException {
- throw new UnsupportedOperationException();
- }
+ public Thrower() throws UnsupportedOperationException {
+ throw new UnsupportedOperationException();
+ }
}
class ParametrizedTypeTest {
@@ -850,3 +855,17 @@ class GenericArrayTypeTest<T> {
public void aMethod(T[] names) {}
public void aMethodIdentical(T[] names) {}
}
+
+class OtherClass {
+ private static final long LONG = 1234;
+ public void test() {
+ try {
+ Field field = getClass().getDeclaredField("LONG");
+ if (1234 != field.getLong(null)) {
+ System.out.println("ERROR: values don't match");
+ }
+ } catch (Exception e) {
+ System.out.println(e);
+ }
+ }
+} \ No newline at end of file