jni_internal_test.cc revision d4c3c62cc68296fbaf35e7b37108c2fde2278a3b
1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "jni_internal.h" 18 19#include "common_compiler_test.h" 20#include "mirror/art_method-inl.h" 21#include "mirror/string-inl.h" 22#include "ScopedLocalRef.h" 23 24namespace art { 25 26// TODO: Convert to CommonRuntimeTest. Currently MakeExecutable is used. 27class JniInternalTest : public CommonCompilerTest { 28 protected: 29 virtual void SetUp() { 30 CommonCompilerTest::SetUp(); 31 32 vm_ = Runtime::Current()->GetJavaVM(); 33 34 // Turn on -verbose:jni for the JNI tests. 35 // gLogVerbosity.jni = true; 36 37 vm_->AttachCurrentThread(&env_, nullptr); 38 39 ScopedLocalRef<jclass> aioobe(env_, 40 env_->FindClass("java/lang/ArrayIndexOutOfBoundsException")); 41 CHECK(aioobe.get() != nullptr); 42 aioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(aioobe.get())); 43 44 ScopedLocalRef<jclass> ase(env_, env_->FindClass("java/lang/ArrayStoreException")); 45 CHECK(ase.get() != nullptr); 46 ase_ = reinterpret_cast<jclass>(env_->NewGlobalRef(ase.get())); 47 48 ScopedLocalRef<jclass> sioobe(env_, 49 env_->FindClass("java/lang/StringIndexOutOfBoundsException")); 50 CHECK(sioobe.get() != nullptr); 51 sioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(sioobe.get())); 52 } 53 54 void ExpectException(jclass exception_class) { 55 EXPECT_TRUE(env_->ExceptionCheck()); 56 jthrowable exception = env_->ExceptionOccurred(); 57 EXPECT_NE(nullptr, exception); 58 env_->ExceptionClear(); 59 EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class)); 60 } 61 62 void ExpectClassFound(const char* name) { 63 EXPECT_NE(env_->FindClass(name), nullptr) << name; 64 EXPECT_FALSE(env_->ExceptionCheck()) << name; 65 } 66 67 void ExpectClassNotFound(const char* name) { 68 EXPECT_EQ(env_->FindClass(name), nullptr) << name; 69 EXPECT_TRUE(env_->ExceptionCheck()) << name; 70 env_->ExceptionClear(); 71 } 72 73 void CleanUpJniEnv() { 74 if (aioobe_ != nullptr) { 75 env_->DeleteGlobalRef(aioobe_); 76 aioobe_ = nullptr; 77 } 78 if (ase_ != nullptr) { 79 env_->DeleteGlobalRef(ase_); 80 ase_ = nullptr; 81 } 82 if (sioobe_ != nullptr) { 83 env_->DeleteGlobalRef(sioobe_); 84 sioobe_ = nullptr; 85 } 86 } 87 88 virtual void TearDown() OVERRIDE { 89 CleanUpJniEnv(); 90 CommonCompilerTest::TearDown(); 91 } 92 93 jclass GetPrimitiveClass(char descriptor) { 94 ScopedObjectAccess soa(env_); 95 mirror::Class* c = class_linker_->FindPrimitiveClass(descriptor); 96 CHECK(c != nullptr); 97 return soa.AddLocalReference<jclass>(c); 98 } 99 100 JavaVMExt* vm_; 101 JNIEnv* env_; 102 jclass aioobe_; 103 jclass ase_; 104 jclass sioobe_; 105}; 106 107TEST_F(JniInternalTest, AllocObject) { 108 jclass c = env_->FindClass("java/lang/String"); 109 ASSERT_NE(c, nullptr); 110 jobject o = env_->AllocObject(c); 111 ASSERT_NE(o, nullptr); 112 113 // We have an instance of the class we asked for... 114 ASSERT_TRUE(env_->IsInstanceOf(o, c)); 115 // ...whose fields haven't been initialized because 116 // we didn't call a constructor. 117 ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "count", "I"))); 118 ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "offset", "I"))); 119 ASSERT_TRUE(env_->GetObjectField(o, env_->GetFieldID(c, "value", "[C")) == nullptr); 120} 121 122TEST_F(JniInternalTest, GetVersion) { 123 ASSERT_EQ(JNI_VERSION_1_6, env_->GetVersion()); 124} 125 126TEST_F(JniInternalTest, FindClass) { 127 // Reference types... 128 ExpectClassFound("java/lang/String"); 129 // ...for arrays too, where you must include "L;". 130 ExpectClassFound("[Ljava/lang/String;"); 131 // Primitive arrays are okay too, if the primitive type is valid. 132 ExpectClassFound("[C"); 133 134 { 135 CheckJniAbortCatcher check_jni_abort_catcher; 136 env_->FindClass(nullptr); 137 check_jni_abort_catcher.Check("name == null"); 138 139 // We support . as well as / for compatibility, if -Xcheck:jni is off. 140 ExpectClassFound("java.lang.String"); 141 check_jni_abort_catcher.Check("illegal class name 'java.lang.String'"); 142 ExpectClassNotFound("Ljava.lang.String;"); 143 check_jni_abort_catcher.Check("illegal class name 'Ljava.lang.String;'"); 144 ExpectClassFound("[Ljava.lang.String;"); 145 check_jni_abort_catcher.Check("illegal class name '[Ljava.lang.String;'"); 146 ExpectClassNotFound("[java.lang.String"); 147 check_jni_abort_catcher.Check("illegal class name '[java.lang.String'"); 148 149 // You can't include the "L;" in a JNI class descriptor. 150 ExpectClassNotFound("Ljava/lang/String;"); 151 check_jni_abort_catcher.Check("illegal class name 'Ljava/lang/String;'"); 152 153 // But you must include it for an array of any reference type. 154 ExpectClassNotFound("[java/lang/String"); 155 check_jni_abort_catcher.Check("illegal class name '[java/lang/String'"); 156 157 ExpectClassNotFound("[K"); 158 check_jni_abort_catcher.Check("illegal class name '[K'"); 159 160 // Void arrays aren't allowed. 161 ExpectClassNotFound("[V"); 162 check_jni_abort_catcher.Check("illegal class name '[V'"); 163 } 164 165 // But primitive types aren't allowed... 166 ExpectClassNotFound("C"); 167 ExpectClassNotFound("V"); 168 ExpectClassNotFound("K"); 169} 170 171TEST_F(JniInternalTest, GetFieldID) { 172 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError"); 173 ASSERT_NE(jlnsfe, nullptr); 174 jclass c = env_->FindClass("java/lang/String"); 175 ASSERT_NE(c, nullptr); 176 177 // Wrong type. 178 jfieldID fid = env_->GetFieldID(c, "count", "J"); 179 EXPECT_EQ(nullptr, fid); 180 ExpectException(jlnsfe); 181 182 // Wrong type where type doesn't exist. 183 fid = env_->GetFieldID(c, "count", "Lrod/jane/freddy;"); 184 EXPECT_EQ(nullptr, fid); 185 ExpectException(jlnsfe); 186 187 // Wrong name. 188 fid = env_->GetFieldID(c, "Count", "I"); 189 EXPECT_EQ(nullptr, fid); 190 ExpectException(jlnsfe); 191 192 // Good declared field lookup. 193 fid = env_->GetFieldID(c, "count", "I"); 194 EXPECT_NE(nullptr, fid); 195 EXPECT_FALSE(env_->ExceptionCheck()); 196 197 // Good superclass field lookup. 198 c = env_->FindClass("java/lang/StringBuilder"); 199 fid = env_->GetFieldID(c, "count", "I"); 200 EXPECT_NE(nullptr, fid); 201 EXPECT_NE(fid, nullptr); 202 EXPECT_FALSE(env_->ExceptionCheck()); 203 204 // Not instance. 205 fid = env_->GetFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;"); 206 EXPECT_EQ(nullptr, fid); 207 ExpectException(jlnsfe); 208 209 // Bad arguments. 210 CheckJniAbortCatcher check_jni_abort_catcher; 211 fid = env_->GetFieldID(nullptr, "count", "I"); 212 EXPECT_EQ(nullptr, fid); 213 check_jni_abort_catcher.Check("java_class == null"); 214 fid = env_->GetFieldID(c, nullptr, "I"); 215 EXPECT_EQ(nullptr, fid); 216 check_jni_abort_catcher.Check("name == null"); 217 fid = env_->GetFieldID(c, "count", nullptr); 218 EXPECT_EQ(nullptr, fid); 219 check_jni_abort_catcher.Check("sig == null"); 220} 221 222TEST_F(JniInternalTest, GetStaticFieldID) { 223 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError"); 224 ASSERT_NE(jlnsfe, nullptr); 225 jclass c = env_->FindClass("java/lang/String"); 226 ASSERT_NE(c, nullptr); 227 228 // Wrong type. 229 jfieldID fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "J"); 230 EXPECT_EQ(nullptr, fid); 231 ExpectException(jlnsfe); 232 233 // Wrong type where type doesn't exist. 234 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Lrod/jane/freddy;"); 235 EXPECT_EQ(nullptr, fid); 236 ExpectException(jlnsfe); 237 238 // Wrong name. 239 fid = env_->GetStaticFieldID(c, "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;"); 240 EXPECT_EQ(nullptr, fid); 241 ExpectException(jlnsfe); 242 243 // Good declared field lookup. 244 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;"); 245 EXPECT_NE(nullptr, fid); 246 EXPECT_NE(fid, nullptr); 247 EXPECT_FALSE(env_->ExceptionCheck()); 248 249 // Not static. 250 fid = env_->GetStaticFieldID(c, "count", "I"); 251 EXPECT_EQ(nullptr, fid); 252 ExpectException(jlnsfe); 253 254 // Bad arguments. 255 CheckJniAbortCatcher check_jni_abort_catcher; 256 fid = env_->GetStaticFieldID(nullptr, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;"); 257 EXPECT_EQ(nullptr, fid); 258 check_jni_abort_catcher.Check("java_class == null"); 259 fid = env_->GetStaticFieldID(c, nullptr, "Ljava/util/Comparator;"); 260 EXPECT_EQ(nullptr, fid); 261 check_jni_abort_catcher.Check("name == null"); 262 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", nullptr); 263 EXPECT_EQ(nullptr, fid); 264 check_jni_abort_catcher.Check("sig == null"); 265} 266 267TEST_F(JniInternalTest, GetMethodID) { 268 jclass jlobject = env_->FindClass("java/lang/Object"); 269 jclass jlstring = env_->FindClass("java/lang/String"); 270 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError"); 271 jclass jncrbc = env_->FindClass("java/nio/channels/ReadableByteChannel"); 272 273 // Sanity check that no exceptions are pending. 274 ASSERT_FALSE(env_->ExceptionCheck()); 275 276 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is 277 // a pending exception. 278 jmethodID method = env_->GetMethodID(jlobject, "foo", "()V"); 279 EXPECT_EQ(nullptr, method); 280 ExpectException(jlnsme); 281 282 // Check that java.lang.Object.equals() does exist. 283 method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z"); 284 EXPECT_NE(nullptr, method); 285 EXPECT_FALSE(env_->ExceptionCheck()); 286 287 // Check that GetMethodID for java.lang.String.valueOf(int) fails as the 288 // method is static. 289 method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;"); 290 EXPECT_EQ(nullptr, method); 291 ExpectException(jlnsme); 292 293 // Check that GetMethodID for java.lang.NoSuchMethodError.<init>(String) finds the constructor. 294 method = env_->GetMethodID(jlnsme, "<init>", "(Ljava/lang/String;)V"); 295 EXPECT_NE(nullptr, method); 296 EXPECT_FALSE(env_->ExceptionCheck()); 297 298 // Check that GetMethodID can find a interface method inherited from another interface. 299 method = env_->GetMethodID(jncrbc, "close", "()V"); 300 EXPECT_NE(nullptr, method); 301 EXPECT_FALSE(env_->ExceptionCheck()); 302 303 // Bad arguments. 304 CheckJniAbortCatcher check_jni_abort_catcher; 305 method = env_->GetMethodID(nullptr, "<init>", "(Ljava/lang/String;)V"); 306 EXPECT_EQ(nullptr, method); 307 check_jni_abort_catcher.Check("java_class == null"); 308 method = env_->GetMethodID(jlnsme, nullptr, "(Ljava/lang/String;)V"); 309 EXPECT_EQ(nullptr, method); 310 check_jni_abort_catcher.Check("name == null"); 311 method = env_->GetMethodID(jlnsme, "<init>", nullptr); 312 EXPECT_EQ(nullptr, method); 313 check_jni_abort_catcher.Check("sig == null"); 314} 315 316TEST_F(JniInternalTest, GetStaticMethodID) { 317 jclass jlobject = env_->FindClass("java/lang/Object"); 318 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError"); 319 320 // Sanity check that no exceptions are pending 321 ASSERT_FALSE(env_->ExceptionCheck()); 322 323 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is 324 // a pending exception 325 jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V"); 326 EXPECT_EQ(nullptr, method); 327 ExpectException(jlnsme); 328 329 // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as 330 // the method is not static 331 method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z"); 332 EXPECT_EQ(nullptr, method); 333 ExpectException(jlnsme); 334 335 // Check that java.lang.String.valueOf(int) does exist 336 jclass jlstring = env_->FindClass("java/lang/String"); 337 method = env_->GetStaticMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;"); 338 EXPECT_NE(nullptr, method); 339 EXPECT_FALSE(env_->ExceptionCheck()); 340 341 // Bad arguments. 342 CheckJniAbortCatcher check_jni_abort_catcher; 343 method = env_->GetStaticMethodID(nullptr, "valueOf", "(I)Ljava/lang/String;"); 344 EXPECT_EQ(nullptr, method); 345 check_jni_abort_catcher.Check("java_class == null"); 346 method = env_->GetStaticMethodID(jlstring, nullptr, "(I)Ljava/lang/String;"); 347 EXPECT_EQ(nullptr, method); 348 check_jni_abort_catcher.Check("name == null"); 349 method = env_->GetStaticMethodID(jlstring, "valueOf", nullptr); 350 EXPECT_EQ(nullptr, method); 351 check_jni_abort_catcher.Check("sig == null"); 352} 353 354TEST_F(JniInternalTest, FromReflectedField_ToReflectedField) { 355 jclass jlrField = env_->FindClass("java/lang/reflect/Field"); 356 jclass c = env_->FindClass("java/lang/String"); 357 ASSERT_NE(c, nullptr); 358 jfieldID fid = env_->GetFieldID(c, "count", "I"); 359 ASSERT_NE(fid, nullptr); 360 // Turn the fid into a java.lang.reflect.Field... 361 jobject field = env_->ToReflectedField(c, fid, JNI_FALSE); 362 ASSERT_NE(c, nullptr); 363 ASSERT_TRUE(env_->IsInstanceOf(field, jlrField)); 364 // ...and back again. 365 jfieldID fid2 = env_->FromReflectedField(field); 366 ASSERT_NE(fid2, nullptr); 367 // Make sure we can actually use it. 368 jstring s = env_->NewStringUTF("poop"); 369 ASSERT_EQ(4, env_->GetIntField(s, fid2)); 370 371 // Bad arguments. 372 CheckJniAbortCatcher check_jni_abort_catcher; 373 field = env_->ToReflectedField(c, nullptr, JNI_FALSE); 374 EXPECT_EQ(field, nullptr); 375 check_jni_abort_catcher.Check("fid == null"); 376 fid2 = env_->FromReflectedField(nullptr); 377 ASSERT_EQ(fid2, nullptr); 378 check_jni_abort_catcher.Check("jlr_field == null"); 379} 380 381TEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) { 382 jclass jlrMethod = env_->FindClass("java/lang/reflect/Method"); 383 ASSERT_NE(jlrMethod, nullptr); 384 jclass jlrConstructor = env_->FindClass("java/lang/reflect/Constructor"); 385 ASSERT_NE(jlrConstructor, nullptr); 386 jclass c = env_->FindClass("java/lang/String"); 387 ASSERT_NE(c, nullptr); 388 389 jmethodID mid = env_->GetMethodID(c, "<init>", "()V"); 390 ASSERT_NE(mid, nullptr); 391 // Turn the mid into a java.lang.reflect.Constructor... 392 jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE); 393 ASSERT_NE(method, nullptr); 394 ASSERT_TRUE(env_->IsInstanceOf(method, jlrConstructor)); 395 // ...and back again. 396 jmethodID mid2 = env_->FromReflectedMethod(method); 397 ASSERT_NE(mid2, nullptr); 398 // Make sure we can actually use it. 399 jstring s = reinterpret_cast<jstring>(env_->AllocObject(c)); 400 ASSERT_NE(s, nullptr); 401 env_->CallVoidMethod(s, mid2); 402 ASSERT_EQ(JNI_FALSE, env_->ExceptionCheck()); 403 404 mid = env_->GetMethodID(c, "length", "()I"); 405 ASSERT_NE(mid, nullptr); 406 // Turn the mid into a java.lang.reflect.Method... 407 method = env_->ToReflectedMethod(c, mid, JNI_FALSE); 408 ASSERT_NE(method, nullptr); 409 ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod)); 410 // ...and back again. 411 mid2 = env_->FromReflectedMethod(method); 412 ASSERT_NE(mid2, nullptr); 413 // Make sure we can actually use it. 414 s = env_->NewStringUTF("poop"); 415 ASSERT_NE(s, nullptr); 416 ASSERT_EQ(4, env_->CallIntMethod(s, mid2)); 417 418 // Bad arguments. 419 CheckJniAbortCatcher check_jni_abort_catcher; 420 method = env_->ToReflectedMethod(c, nullptr, JNI_FALSE); 421 EXPECT_EQ(method, nullptr); 422 check_jni_abort_catcher.Check("mid == null"); 423 mid2 = env_->FromReflectedMethod(method); 424 ASSERT_EQ(mid2, nullptr); 425 check_jni_abort_catcher.Check("jlr_method == null"); 426} 427 428static void BogusMethod() { 429 // You can't pass nullptr function pointers to RegisterNatives. 430} 431 432TEST_F(JniInternalTest, RegisterAndUnregisterNatives) { 433 jclass jlobject = env_->FindClass("java/lang/Object"); 434 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError"); 435 void* native_function = reinterpret_cast<void*>(BogusMethod); 436 437 // Sanity check that no exceptions are pending. 438 ASSERT_FALSE(env_->ExceptionCheck()); 439 440 // Check that registering method without name causes a NoSuchMethodError. 441 { 442 JNINativeMethod methods[] = { { nullptr, "()V", native_function } }; 443 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR); 444 } 445 ExpectException(jlnsme); 446 447 // Check that registering method without signature causes a NoSuchMethodError. 448 { 449 JNINativeMethod methods[] = { { "notify", nullptr, native_function } }; 450 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR); 451 } 452 ExpectException(jlnsme); 453 454 // Check that registering method without function causes a NoSuchMethodError. 455 { 456 JNINativeMethod methods[] = { { "notify", "()V", nullptr } }; 457 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR); 458 } 459 ExpectException(jlnsme); 460 461 // Check that registering to a non-existent java.lang.Object.foo() causes a NoSuchMethodError. 462 { 463 JNINativeMethod methods[] = { { "foo", "()V", native_function } }; 464 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR); 465 } 466 ExpectException(jlnsme); 467 468 // Check that registering non-native methods causes a NoSuchMethodError. 469 { 470 JNINativeMethod methods[] = { { "equals", "(Ljava/lang/Object;)Z", native_function } }; 471 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR); 472 } 473 ExpectException(jlnsme); 474 475 // Check that registering native methods is successful. 476 { 477 JNINativeMethod methods[] = { { "notify", "()V", native_function } }; 478 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_OK); 479 } 480 EXPECT_FALSE(env_->ExceptionCheck()); 481 EXPECT_EQ(env_->UnregisterNatives(jlobject), JNI_OK); 482 483 // Check that registering no methods isn't a failure. 484 { 485 JNINativeMethod methods[] = { }; 486 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 0), JNI_OK); 487 } 488 EXPECT_FALSE(env_->ExceptionCheck()); 489 EXPECT_EQ(env_->UnregisterNatives(jlobject), JNI_OK); 490 491 // Check that registering a -ve number of methods is a failure. 492 CheckJniAbortCatcher check_jni_abort_catcher; 493 for (int i = -10; i < 0; ++i) { 494 JNINativeMethod methods[] = { }; 495 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, i), JNI_ERR); 496 check_jni_abort_catcher.Check("negative method count: "); 497 } 498 EXPECT_FALSE(env_->ExceptionCheck()); 499 500 // Passing a class of null is a failure. 501 { 502 JNINativeMethod methods[] = { }; 503 EXPECT_EQ(env_->RegisterNatives(nullptr, methods, 0), JNI_ERR); 504 check_jni_abort_catcher.Check("java_class == null"); 505 } 506 507 // Passing methods as null is a failure. 508 EXPECT_EQ(env_->RegisterNatives(jlobject, nullptr, 1), JNI_ERR); 509 check_jni_abort_catcher.Check("methods == null"); 510 511 // Unregisters null is a failure. 512 EXPECT_EQ(env_->UnregisterNatives(nullptr), JNI_ERR); 513 check_jni_abort_catcher.Check("java_class == null"); 514 515 // Unregistering a class with no natives is a warning. 516 EXPECT_EQ(env_->UnregisterNatives(jlnsme), JNI_OK); 517} 518 519#define EXPECT_PRIMITIVE_ARRAY(new_fn, \ 520 get_region_fn, \ 521 set_region_fn, \ 522 get_elements_fn, \ 523 release_elements_fn, \ 524 scalar_type, \ 525 expected_class_descriptor) \ 526 jsize size = 4; \ 527 \ 528 { \ 529 CheckJniAbortCatcher jni_abort_catcher; \ 530 /* Allocate an negative sized array and check it has the right failure type. */ \ 531 EXPECT_EQ(env_->new_fn(-1), nullptr); \ 532 jni_abort_catcher.Check("negative array length: -1"); \ 533 EXPECT_EQ(env_->new_fn(std::numeric_limits<jint>::min()), nullptr); \ 534 jni_abort_catcher.Check("negative array length: -2147483648"); \ 535 /* Pass the array as null. */ \ 536 EXPECT_EQ(0, env_->GetArrayLength(nullptr)); \ 537 jni_abort_catcher.Check("java_array == null"); \ 538 env_->get_region_fn(nullptr, 0, 0, nullptr); \ 539 jni_abort_catcher.Check("java_array == null"); \ 540 env_->set_region_fn(nullptr, 0, 0, nullptr); \ 541 jni_abort_catcher.Check("java_array == null"); \ 542 env_->get_elements_fn(nullptr, nullptr); \ 543 jni_abort_catcher.Check("java_array == null"); \ 544 env_->release_elements_fn(nullptr, nullptr, 0); \ 545 jni_abort_catcher.Check("java_array == null"); \ 546 /* Pass the elements for region as null. */ \ 547 scalar_type ## Array a = env_->new_fn(size); \ 548 env_->get_region_fn(a, 0, size, nullptr); \ 549 jni_abort_catcher.Check("buf == null"); \ 550 env_->set_region_fn(a, 0, size, nullptr); \ 551 jni_abort_catcher.Check("buf == null"); \ 552 } \ 553 /* Allocate an array and check it has the right type and length. */ \ 554 scalar_type ## Array a = env_->new_fn(size); \ 555 EXPECT_NE(a, nullptr); \ 556 EXPECT_TRUE(env_->IsInstanceOf(a, env_->FindClass(expected_class_descriptor))); \ 557 EXPECT_EQ(size, env_->GetArrayLength(a)); \ 558 \ 559 /* GetPrimitiveArrayRegion/SetPrimitiveArrayRegion */ \ 560 /* AIOOBE for negative start offset. */ \ 561 env_->get_region_fn(a, -1, 1, nullptr); \ 562 ExpectException(aioobe_); \ 563 env_->set_region_fn(a, -1, 1, nullptr); \ 564 ExpectException(aioobe_); \ 565 \ 566 /* AIOOBE for negative length. */ \ 567 env_->get_region_fn(a, 0, -1, nullptr); \ 568 ExpectException(aioobe_); \ 569 env_->set_region_fn(a, 0, -1, nullptr); \ 570 ExpectException(aioobe_); \ 571 \ 572 /* AIOOBE for buffer overrun. */ \ 573 env_->get_region_fn(a, size - 1, size, nullptr); \ 574 ExpectException(aioobe_); \ 575 env_->set_region_fn(a, size - 1, size, nullptr); \ 576 ExpectException(aioobe_); \ 577 \ 578 /* It's okay for the buffer to be nullptr as long as the length is 0. */ \ 579 env_->get_region_fn(a, 2, 0, nullptr); \ 580 /* Even if the offset is invalid... */ \ 581 env_->get_region_fn(a, 123, 0, nullptr); \ 582 ExpectException(aioobe_); \ 583 \ 584 /* It's okay for the buffer to be nullptr as long as the length is 0. */ \ 585 env_->set_region_fn(a, 2, 0, nullptr); \ 586 /* Even if the offset is invalid... */ \ 587 env_->set_region_fn(a, 123, 0, nullptr); \ 588 ExpectException(aioobe_); \ 589 \ 590 /* Prepare a couple of buffers. */ \ 591 std::unique_ptr<scalar_type[]> src_buf(new scalar_type[size]); \ 592 std::unique_ptr<scalar_type[]> dst_buf(new scalar_type[size]); \ 593 for (jsize i = 0; i < size; ++i) { src_buf[i] = scalar_type(i); } \ 594 for (jsize i = 0; i < size; ++i) { dst_buf[i] = scalar_type(-1); } \ 595 \ 596 /* Copy all of src_buf onto the heap. */ \ 597 env_->set_region_fn(a, 0, size, &src_buf[0]); \ 598 /* Copy back only part. */ \ 599 env_->get_region_fn(a, 1, size - 2, &dst_buf[1]); \ 600 EXPECT_NE(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \ 601 << "short copy equal"; \ 602 /* Copy the missing pieces. */ \ 603 env_->get_region_fn(a, 0, 1, &dst_buf[0]); \ 604 env_->get_region_fn(a, size - 1, 1, &dst_buf[size - 1]); \ 605 EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \ 606 << "fixed copy not equal"; \ 607 /* Copy back the whole array. */ \ 608 env_->get_region_fn(a, 0, size, &dst_buf[0]); \ 609 EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \ 610 << "full copy not equal"; \ 611 /* GetPrimitiveArrayCritical */ \ 612 void* v = env_->GetPrimitiveArrayCritical(a, nullptr); \ 613 EXPECT_EQ(memcmp(&src_buf[0], v, size * sizeof(scalar_type)), 0) \ 614 << "GetPrimitiveArrayCritical not equal"; \ 615 env_->ReleasePrimitiveArrayCritical(a, v, 0); \ 616 /* GetXArrayElements */ \ 617 scalar_type* xs = env_->get_elements_fn(a, nullptr); \ 618 EXPECT_EQ(memcmp(&src_buf[0], xs, size * sizeof(scalar_type)), 0) \ 619 << # get_elements_fn " not equal"; \ 620 env_->release_elements_fn(a, xs, 0); \ 621 622TEST_F(JniInternalTest, BooleanArrays) { 623 EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion, 624 GetBooleanArrayElements, ReleaseBooleanArrayElements, jboolean, "[Z"); 625} 626TEST_F(JniInternalTest, ByteArrays) { 627 EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion, 628 GetByteArrayElements, ReleaseByteArrayElements, jbyte, "[B"); 629} 630TEST_F(JniInternalTest, CharArrays) { 631 EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion, 632 GetCharArrayElements, ReleaseCharArrayElements, jchar, "[C"); 633} 634TEST_F(JniInternalTest, DoubleArrays) { 635 EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion, 636 GetDoubleArrayElements, ReleaseDoubleArrayElements, jdouble, "[D"); 637} 638TEST_F(JniInternalTest, FloatArrays) { 639 EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion, 640 GetFloatArrayElements, ReleaseFloatArrayElements, jfloat, "[F"); 641} 642TEST_F(JniInternalTest, IntArrays) { 643 EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion, 644 GetIntArrayElements, ReleaseIntArrayElements, jint, "[I"); 645} 646TEST_F(JniInternalTest, LongArrays) { 647 EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion, 648 GetLongArrayElements, ReleaseLongArrayElements, jlong, "[J"); 649} 650TEST_F(JniInternalTest, ShortArrays) { 651 EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion, 652 GetShortArrayElements, ReleaseShortArrayElements, jshort, "[S"); 653} 654 655TEST_F(JniInternalTest, GetPrimitiveArrayElementsOfWrongType) { 656 CheckJniAbortCatcher jni_abort_catcher; 657 jbooleanArray array = env_->NewBooleanArray(10); 658 jboolean is_copy; 659 EXPECT_EQ(env_->GetByteArrayElements(reinterpret_cast<jbyteArray>(array), &is_copy), nullptr); 660 jni_abort_catcher.Check( 661 "attempt to get byte primitive array elements with an object of type boolean[]"); 662 EXPECT_EQ(env_->GetShortArrayElements(reinterpret_cast<jshortArray>(array), &is_copy), nullptr); 663 jni_abort_catcher.Check( 664 "attempt to get short primitive array elements with an object of type boolean[]"); 665 EXPECT_EQ(env_->GetCharArrayElements(reinterpret_cast<jcharArray>(array), &is_copy), nullptr); 666 jni_abort_catcher.Check( 667 "attempt to get char primitive array elements with an object of type boolean[]"); 668 EXPECT_EQ(env_->GetIntArrayElements(reinterpret_cast<jintArray>(array), &is_copy), nullptr); 669 jni_abort_catcher.Check( 670 "attempt to get int primitive array elements with an object of type boolean[]"); 671 EXPECT_EQ(env_->GetLongArrayElements(reinterpret_cast<jlongArray>(array), &is_copy), nullptr); 672 jni_abort_catcher.Check( 673 "attempt to get long primitive array elements with an object of type boolean[]"); 674 EXPECT_EQ(env_->GetFloatArrayElements(reinterpret_cast<jfloatArray>(array), &is_copy), nullptr); 675 jni_abort_catcher.Check( 676 "attempt to get float primitive array elements with an object of type boolean[]"); 677 EXPECT_EQ(env_->GetDoubleArrayElements(reinterpret_cast<jdoubleArray>(array), &is_copy), nullptr); 678 jni_abort_catcher.Check( 679 "attempt to get double primitive array elements with an object of type boolean[]"); 680 jbyteArray array2 = env_->NewByteArray(10); 681 EXPECT_EQ(env_->GetBooleanArrayElements(reinterpret_cast<jbooleanArray>(array2), &is_copy), 682 nullptr); 683 jni_abort_catcher.Check( 684 "attempt to get boolean primitive array elements with an object of type byte[]"); 685 jobject object = env_->NewStringUTF("Test String"); 686 EXPECT_EQ(env_->GetBooleanArrayElements(reinterpret_cast<jbooleanArray>(object), &is_copy), 687 nullptr); 688 jni_abort_catcher.Check( 689 "attempt to get boolean primitive array elements with an object of type java.lang.String"); 690} 691 692TEST_F(JniInternalTest, ReleasePrimitiveArrayElementsOfWrongType) { 693 CheckJniAbortCatcher jni_abort_catcher; 694 jbooleanArray array = env_->NewBooleanArray(10); 695 ASSERT_TRUE(array != nullptr); 696 jboolean is_copy; 697 jboolean* elements = env_->GetBooleanArrayElements(array, &is_copy); 698 ASSERT_TRUE(elements != nullptr); 699 env_->ReleaseByteArrayElements(reinterpret_cast<jbyteArray>(array), 700 reinterpret_cast<jbyte*>(elements), 0); 701 jni_abort_catcher.Check( 702 "attempt to release byte primitive array elements with an object of type boolean[]"); 703 env_->ReleaseShortArrayElements(reinterpret_cast<jshortArray>(array), 704 reinterpret_cast<jshort*>(elements), 0); 705 jni_abort_catcher.Check( 706 "attempt to release short primitive array elements with an object of type boolean[]"); 707 env_->ReleaseCharArrayElements(reinterpret_cast<jcharArray>(array), 708 reinterpret_cast<jchar*>(elements), 0); 709 jni_abort_catcher.Check( 710 "attempt to release char primitive array elements with an object of type boolean[]"); 711 env_->ReleaseIntArrayElements(reinterpret_cast<jintArray>(array), 712 reinterpret_cast<jint*>(elements), 0); 713 jni_abort_catcher.Check( 714 "attempt to release int primitive array elements with an object of type boolean[]"); 715 env_->ReleaseLongArrayElements(reinterpret_cast<jlongArray>(array), 716 reinterpret_cast<jlong*>(elements), 0); 717 jni_abort_catcher.Check( 718 "attempt to release long primitive array elements with an object of type boolean[]"); 719 env_->ReleaseFloatArrayElements(reinterpret_cast<jfloatArray>(array), 720 reinterpret_cast<jfloat*>(elements), 0); 721 jni_abort_catcher.Check( 722 "attempt to release float primitive array elements with an object of type boolean[]"); 723 env_->ReleaseDoubleArrayElements(reinterpret_cast<jdoubleArray>(array), 724 reinterpret_cast<jdouble*>(elements), 0); 725 jni_abort_catcher.Check( 726 "attempt to release double primitive array elements with an object of type boolean[]"); 727 jbyteArray array2 = env_->NewByteArray(10); 728 env_->ReleaseBooleanArrayElements(reinterpret_cast<jbooleanArray>(array2), elements, 0); 729 jni_abort_catcher.Check( 730 "attempt to release boolean primitive array elements with an object of type byte[]"); 731 jobject object = env_->NewStringUTF("Test String"); 732 env_->ReleaseBooleanArrayElements(reinterpret_cast<jbooleanArray>(object), elements, 0); 733 jni_abort_catcher.Check( 734 "attempt to release boolean primitive array elements with an object of type " 735 "java.lang.String"); 736} 737TEST_F(JniInternalTest, GetReleasePrimitiveArrayCriticalOfWrongType) { 738 CheckJniAbortCatcher jni_abort_catcher; 739 jobject object = env_->NewStringUTF("Test String"); 740 jboolean is_copy; 741 void* elements = env_->GetPrimitiveArrayCritical(reinterpret_cast<jarray>(object), &is_copy); 742 jni_abort_catcher.Check("expected primitive array, given java.lang.String"); 743 env_->ReleasePrimitiveArrayCritical(reinterpret_cast<jarray>(object), elements, 0); 744 jni_abort_catcher.Check("expected primitive array, given java.lang.String"); 745} 746 747TEST_F(JniInternalTest, GetPrimitiveArrayRegionElementsOfWrongType) { 748 CheckJniAbortCatcher jni_abort_catcher; 749 constexpr size_t kLength = 10; 750 jbooleanArray array = env_->NewBooleanArray(kLength); 751 ASSERT_TRUE(array != nullptr); 752 jboolean elements[kLength]; 753 env_->GetByteArrayRegion(reinterpret_cast<jbyteArray>(array), 0, kLength, 754 reinterpret_cast<jbyte*>(elements)); 755 jni_abort_catcher.Check( 756 "attempt to get region of byte primitive array elements with an object of type boolean[]"); 757 env_->GetShortArrayRegion(reinterpret_cast<jshortArray>(array), 0, kLength, 758 reinterpret_cast<jshort*>(elements)); 759 jni_abort_catcher.Check( 760 "attempt to get region of short primitive array elements with an object of type boolean[]"); 761 env_->GetCharArrayRegion(reinterpret_cast<jcharArray>(array), 0, kLength, 762 reinterpret_cast<jchar*>(elements)); 763 jni_abort_catcher.Check( 764 "attempt to get region of char primitive array elements with an object of type boolean[]"); 765 env_->GetIntArrayRegion(reinterpret_cast<jintArray>(array), 0, kLength, 766 reinterpret_cast<jint*>(elements)); 767 jni_abort_catcher.Check( 768 "attempt to get region of int primitive array elements with an object of type boolean[]"); 769 env_->GetLongArrayRegion(reinterpret_cast<jlongArray>(array), 0, kLength, 770 reinterpret_cast<jlong*>(elements)); 771 jni_abort_catcher.Check( 772 "attempt to get region of long primitive array elements with an object of type boolean[]"); 773 env_->GetFloatArrayRegion(reinterpret_cast<jfloatArray>(array), 0, kLength, 774 reinterpret_cast<jfloat*>(elements)); 775 jni_abort_catcher.Check( 776 "attempt to get region of float primitive array elements with an object of type boolean[]"); 777 env_->GetDoubleArrayRegion(reinterpret_cast<jdoubleArray>(array), 0, kLength, 778 reinterpret_cast<jdouble*>(elements)); 779 jni_abort_catcher.Check( 780 "attempt to get region of double primitive array elements with an object of type boolean[]"); 781 jbyteArray array2 = env_->NewByteArray(10); 782 env_->GetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(array2), 0, kLength, 783 reinterpret_cast<jboolean*>(elements)); 784 jni_abort_catcher.Check( 785 "attempt to get region of boolean primitive array elements with an object of type byte[]"); 786 jobject object = env_->NewStringUTF("Test String"); 787 env_->GetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(object), 0, kLength, 788 reinterpret_cast<jboolean*>(elements)); 789 jni_abort_catcher.Check( 790 "attempt to get region of boolean primitive array elements with an object of type " 791 "java.lang.String"); 792} 793 794TEST_F(JniInternalTest, SetPrimitiveArrayRegionElementsOfWrongType) { 795 CheckJniAbortCatcher jni_abort_catcher; 796 constexpr size_t kLength = 10; 797 jbooleanArray array = env_->NewBooleanArray(kLength); 798 ASSERT_TRUE(array != nullptr); 799 jboolean elements[kLength]; 800 env_->SetByteArrayRegion(reinterpret_cast<jbyteArray>(array), 0, kLength, 801 reinterpret_cast<jbyte*>(elements)); 802 jni_abort_catcher.Check( 803 "attempt to set region of byte primitive array elements with an object of type boolean[]"); 804 env_->SetShortArrayRegion(reinterpret_cast<jshortArray>(array), 0, kLength, 805 reinterpret_cast<jshort*>(elements)); 806 jni_abort_catcher.Check( 807 "attempt to set region of short primitive array elements with an object of type boolean[]"); 808 env_->SetCharArrayRegion(reinterpret_cast<jcharArray>(array), 0, kLength, 809 reinterpret_cast<jchar*>(elements)); 810 jni_abort_catcher.Check( 811 "attempt to set region of char primitive array elements with an object of type boolean[]"); 812 env_->SetIntArrayRegion(reinterpret_cast<jintArray>(array), 0, kLength, 813 reinterpret_cast<jint*>(elements)); 814 jni_abort_catcher.Check( 815 "attempt to set region of int primitive array elements with an object of type boolean[]"); 816 env_->SetLongArrayRegion(reinterpret_cast<jlongArray>(array), 0, kLength, 817 reinterpret_cast<jlong*>(elements)); 818 jni_abort_catcher.Check( 819 "attempt to set region of long primitive array elements with an object of type boolean[]"); 820 env_->SetFloatArrayRegion(reinterpret_cast<jfloatArray>(array), 0, kLength, 821 reinterpret_cast<jfloat*>(elements)); 822 jni_abort_catcher.Check( 823 "attempt to set region of float primitive array elements with an object of type boolean[]"); 824 env_->SetDoubleArrayRegion(reinterpret_cast<jdoubleArray>(array), 0, kLength, 825 reinterpret_cast<jdouble*>(elements)); 826 jni_abort_catcher.Check( 827 "attempt to set region of double primitive array elements with an object of type boolean[]"); 828 jbyteArray array2 = env_->NewByteArray(10); 829 env_->SetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(array2), 0, kLength, 830 reinterpret_cast<jboolean*>(elements)); 831 jni_abort_catcher.Check( 832 "attempt to set region of boolean primitive array elements with an object of type byte[]"); 833 jobject object = env_->NewStringUTF("Test String"); 834 env_->SetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(object), 0, kLength, 835 reinterpret_cast<jboolean*>(elements)); 836 jni_abort_catcher.Check( 837 "attempt to set region of boolean primitive array elements with an object of type " 838 "java.lang.String"); 839} 840 841TEST_F(JniInternalTest, NewObjectArray) { 842 jclass element_class = env_->FindClass("java/lang/String"); 843 ASSERT_NE(element_class, nullptr); 844 jclass array_class = env_->FindClass("[Ljava/lang/String;"); 845 ASSERT_NE(array_class, nullptr); 846 847 jobjectArray a = env_->NewObjectArray(0, element_class, nullptr); 848 EXPECT_NE(a, nullptr); 849 EXPECT_TRUE(env_->IsInstanceOf(a, array_class)); 850 EXPECT_EQ(0, env_->GetArrayLength(a)); 851 852 a = env_->NewObjectArray(1, element_class, nullptr); 853 EXPECT_NE(a, nullptr); 854 EXPECT_TRUE(env_->IsInstanceOf(a, array_class)); 855 EXPECT_EQ(1, env_->GetArrayLength(a)); 856 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), nullptr)); 857 858 // Negative array length checks. 859 CheckJniAbortCatcher jni_abort_catcher; 860 env_->NewObjectArray(-1, element_class, nullptr); 861 jni_abort_catcher.Check("negative array length: -1"); 862 863 env_->NewObjectArray(std::numeric_limits<jint>::min(), element_class, nullptr); 864 jni_abort_catcher.Check("negative array length: -2147483648"); 865} 866 867TEST_F(JniInternalTest, NewObjectArrayWithPrimitiveClasses) { 868 const char* primitive_descriptors = "VZBSCIJFD"; 869 const char* primitive_names[] = { 870 "void", "boolean", "byte", "short", "char", "int", "long", "float", "double" 871 }; 872 ASSERT_EQ(strlen(primitive_descriptors), arraysize(primitive_names)); 873 874 CheckJniAbortCatcher jni_abort_catcher; 875 for (size_t i = 0; i < strlen(primitive_descriptors); ++i) { 876 env_->NewObjectArray(0, nullptr, nullptr); 877 jni_abort_catcher.Check("element_jclass == null"); 878 jclass primitive_class = GetPrimitiveClass(primitive_descriptors[i]); 879 env_->NewObjectArray(1, primitive_class, nullptr); 880 std::string error_msg(StringPrintf("not an object type: %s", primitive_names[i])); 881 jni_abort_catcher.Check(error_msg.c_str()); 882 } 883} 884 885TEST_F(JniInternalTest, NewObjectArrayWithInitialValue) { 886 jclass element_class = env_->FindClass("java/lang/String"); 887 ASSERT_NE(element_class, nullptr); 888 jclass array_class = env_->FindClass("[Ljava/lang/String;"); 889 ASSERT_NE(array_class, nullptr); 890 891 jstring s = env_->NewStringUTF("poop"); 892 jobjectArray a = env_->NewObjectArray(2, element_class, s); 893 EXPECT_NE(a, nullptr); 894 EXPECT_TRUE(env_->IsInstanceOf(a, array_class)); 895 EXPECT_EQ(2, env_->GetArrayLength(a)); 896 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), s)); 897 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 1), s)); 898 899 // Attempt to incorrect create an array of strings with initial value of string arrays. 900 CheckJniAbortCatcher jni_abort_catcher; 901 env_->NewObjectArray(2, element_class, a); 902 jni_abort_catcher.Check("cannot assign object of type 'java.lang.String[]' to array with element " 903 "type of 'java.lang.String'"); 904} 905 906TEST_F(JniInternalTest, GetArrayLength) { 907 // Already tested in NewObjectArray/NewPrimitiveArray. 908} 909 910TEST_F(JniInternalTest, GetObjectClass) { 911 jclass string_class = env_->FindClass("java/lang/String"); 912 ASSERT_NE(string_class, nullptr); 913 jclass class_class = env_->FindClass("java/lang/Class"); 914 ASSERT_NE(class_class, nullptr); 915 916 jstring s = env_->NewStringUTF("poop"); 917 jclass c = env_->GetObjectClass(s); 918 ASSERT_TRUE(env_->IsSameObject(string_class, c)); 919 920 jclass c2 = env_->GetObjectClass(c); 921 ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2))); 922 923 // Null as object should fail. 924 CheckJniAbortCatcher jni_abort_catcher; 925 EXPECT_EQ(env_->GetObjectClass(nullptr), nullptr); 926 jni_abort_catcher.Check("java_object == null"); 927} 928 929TEST_F(JniInternalTest, GetSuperclass) { 930 jclass object_class = env_->FindClass("java/lang/Object"); 931 ASSERT_NE(object_class, nullptr); 932 jclass string_class = env_->FindClass("java/lang/String"); 933 ASSERT_NE(string_class, nullptr); 934 jclass runnable_interface = env_->FindClass("java/lang/Runnable"); 935 ASSERT_NE(runnable_interface, nullptr); 936 ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class))); 937 ASSERT_EQ(env_->GetSuperclass(object_class), nullptr); 938 ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(runnable_interface))); 939 940 // Null as class should fail. 941 CheckJniAbortCatcher jni_abort_catcher; 942 EXPECT_EQ(env_->GetSuperclass(nullptr), nullptr); 943 jni_abort_catcher.Check("java_class == null"); 944} 945 946TEST_F(JniInternalTest, IsAssignableFrom) { 947 jclass object_class = env_->FindClass("java/lang/Object"); 948 ASSERT_NE(object_class, nullptr); 949 jclass string_class = env_->FindClass("java/lang/String"); 950 ASSERT_NE(string_class, nullptr); 951 952 // A superclass is assignable from an instance of its 953 // subclass but not vice versa. 954 ASSERT_TRUE(env_->IsAssignableFrom(string_class, object_class)); 955 ASSERT_FALSE(env_->IsAssignableFrom(object_class, string_class)); 956 957 jclass charsequence_interface = env_->FindClass("java/lang/CharSequence"); 958 ASSERT_NE(charsequence_interface, nullptr); 959 960 // An interface is assignable from an instance of an implementing 961 // class but not vice versa. 962 ASSERT_TRUE(env_->IsAssignableFrom(string_class, charsequence_interface)); 963 ASSERT_FALSE(env_->IsAssignableFrom(charsequence_interface, string_class)); 964 965 // Check that arrays are covariant. 966 jclass string_array_class = env_->FindClass("[Ljava/lang/String;"); 967 ASSERT_NE(string_array_class, nullptr); 968 jclass object_array_class = env_->FindClass("[Ljava/lang/Object;"); 969 ASSERT_NE(object_array_class, nullptr); 970 ASSERT_TRUE(env_->IsAssignableFrom(string_array_class, object_array_class)); 971 ASSERT_FALSE(env_->IsAssignableFrom(object_array_class, string_array_class)); 972 973 // Primitive types are tested in 004-JniTest. 974 975 // Null as either class should fail. 976 CheckJniAbortCatcher jni_abort_catcher; 977 EXPECT_EQ(env_->IsAssignableFrom(nullptr, string_class), JNI_FALSE); 978 jni_abort_catcher.Check("java_class1 == null"); 979 EXPECT_EQ(env_->IsAssignableFrom(object_class, nullptr), JNI_FALSE); 980 jni_abort_catcher.Check("java_class2 == null"); 981} 982 983TEST_F(JniInternalTest, GetObjectRefType) { 984 jclass local = env_->FindClass("java/lang/Object"); 985 ASSERT_TRUE(local != nullptr); 986 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(local)); 987 988 jobject global = env_->NewGlobalRef(local); 989 EXPECT_EQ(JNIGlobalRefType, env_->GetObjectRefType(global)); 990 991 jweak weak_global = env_->NewWeakGlobalRef(local); 992 EXPECT_EQ(JNIWeakGlobalRefType, env_->GetObjectRefType(weak_global)); 993 994 jobject invalid = reinterpret_cast<jobject>(this); 995 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(invalid)); 996 997 // TODO: invoke a native method and test that its arguments are considered local references. 998 999 // Null as object should fail. 1000 CheckJniAbortCatcher jni_abort_catcher; 1001 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(nullptr)); 1002 jni_abort_catcher.Check("java_object == null"); 1003} 1004 1005TEST_F(JniInternalTest, StaleWeakGlobal) { 1006 jclass java_lang_Class = env_->FindClass("java/lang/Class"); 1007 ASSERT_NE(java_lang_Class, nullptr); 1008 jobjectArray local_ref = env_->NewObjectArray(1, java_lang_Class, nullptr); 1009 ASSERT_NE(local_ref, nullptr); 1010 jweak weak_global = env_->NewWeakGlobalRef(local_ref); 1011 ASSERT_NE(weak_global, nullptr); 1012 env_->DeleteLocalRef(local_ref); 1013 Runtime::Current()->GetHeap()->CollectGarbage(false); // GC should clear the weak global. 1014 jobject new_global_ref = env_->NewGlobalRef(weak_global); 1015 EXPECT_EQ(new_global_ref, nullptr); 1016 jobject new_local_ref = env_->NewLocalRef(weak_global); 1017 EXPECT_EQ(new_local_ref, nullptr); 1018} 1019 1020TEST_F(JniInternalTest, NewStringUTF) { 1021 EXPECT_EQ(env_->NewStringUTF(nullptr), nullptr); 1022 jstring s; 1023 1024 s = env_->NewStringUTF(""); 1025 EXPECT_NE(s, nullptr); 1026 EXPECT_EQ(0, env_->GetStringLength(s)); 1027 EXPECT_EQ(0, env_->GetStringUTFLength(s)); 1028 s = env_->NewStringUTF("hello"); 1029 EXPECT_NE(s, nullptr); 1030 EXPECT_EQ(5, env_->GetStringLength(s)); 1031 EXPECT_EQ(5, env_->GetStringUTFLength(s)); 1032 1033 // TODO: check some non-ASCII strings. 1034} 1035 1036TEST_F(JniInternalTest, NewString) { 1037 jchar chars[] = { 'h', 'i' }; 1038 jstring s; 1039 s = env_->NewString(chars, 0); 1040 EXPECT_NE(s, nullptr); 1041 EXPECT_EQ(0, env_->GetStringLength(s)); 1042 EXPECT_EQ(0, env_->GetStringUTFLength(s)); 1043 s = env_->NewString(chars, 2); 1044 EXPECT_NE(s, nullptr); 1045 EXPECT_EQ(2, env_->GetStringLength(s)); 1046 EXPECT_EQ(2, env_->GetStringUTFLength(s)); 1047 1048 // TODO: check some non-ASCII strings. 1049} 1050 1051TEST_F(JniInternalTest, NewStringNullCharsZeroLength) { 1052 jstring s = env_->NewString(nullptr, 0); 1053 EXPECT_NE(s, nullptr); 1054 EXPECT_EQ(0, env_->GetStringLength(s)); 1055} 1056 1057TEST_F(JniInternalTest, NewStringNullCharsNonzeroLength) { 1058 CheckJniAbortCatcher jni_abort_catcher; 1059 env_->NewString(nullptr, 1); 1060 jni_abort_catcher.Check("chars == null && char_count > 0"); 1061} 1062 1063TEST_F(JniInternalTest, NewStringNegativeLength) { 1064 CheckJniAbortCatcher jni_abort_catcher; 1065 env_->NewString(nullptr, -1); 1066 jni_abort_catcher.Check("char_count < 0: -1"); 1067 env_->NewString(nullptr, std::numeric_limits<jint>::min()); 1068 jni_abort_catcher.Check("char_count < 0: -2147483648"); 1069} 1070 1071TEST_F(JniInternalTest, GetStringLength_GetStringUTFLength) { 1072 // Already tested in the NewString/NewStringUTF tests. 1073} 1074 1075TEST_F(JniInternalTest, GetStringRegion_GetStringUTFRegion) { 1076 jstring s = env_->NewStringUTF("hello"); 1077 ASSERT_TRUE(s != nullptr); 1078 1079 env_->GetStringRegion(s, -1, 0, nullptr); 1080 ExpectException(sioobe_); 1081 env_->GetStringRegion(s, 0, -1, nullptr); 1082 ExpectException(sioobe_); 1083 env_->GetStringRegion(s, 0, 10, nullptr); 1084 ExpectException(sioobe_); 1085 env_->GetStringRegion(s, 10, 1, nullptr); 1086 ExpectException(sioobe_); 1087 1088 jchar chars[4] = { 'x', 'x', 'x', 'x' }; 1089 env_->GetStringRegion(s, 1, 2, &chars[1]); 1090 EXPECT_EQ('x', chars[0]); 1091 EXPECT_EQ('e', chars[1]); 1092 EXPECT_EQ('l', chars[2]); 1093 EXPECT_EQ('x', chars[3]); 1094 1095 // It's okay for the buffer to be nullptr as long as the length is 0. 1096 env_->GetStringRegion(s, 2, 0, nullptr); 1097 // Even if the offset is invalid... 1098 env_->GetStringRegion(s, 123, 0, nullptr); 1099 ExpectException(sioobe_); 1100 1101 env_->GetStringUTFRegion(s, -1, 0, nullptr); 1102 ExpectException(sioobe_); 1103 env_->GetStringUTFRegion(s, 0, -1, nullptr); 1104 ExpectException(sioobe_); 1105 env_->GetStringUTFRegion(s, 0, 10, nullptr); 1106 ExpectException(sioobe_); 1107 env_->GetStringUTFRegion(s, 10, 1, nullptr); 1108 ExpectException(sioobe_); 1109 1110 char bytes[4] = { 'x', 'x', 'x', 'x' }; 1111 env_->GetStringUTFRegion(s, 1, 2, &bytes[1]); 1112 EXPECT_EQ('x', bytes[0]); 1113 EXPECT_EQ('e', bytes[1]); 1114 EXPECT_EQ('l', bytes[2]); 1115 EXPECT_EQ('x', bytes[3]); 1116 1117 // It's okay for the buffer to be nullptr as long as the length is 0. 1118 env_->GetStringUTFRegion(s, 2, 0, nullptr); 1119 // Even if the offset is invalid... 1120 env_->GetStringUTFRegion(s, 123, 0, nullptr); 1121 ExpectException(sioobe_); 1122} 1123 1124TEST_F(JniInternalTest, GetStringUTFChars_ReleaseStringUTFChars) { 1125 // Passing in a nullptr jstring is ignored normally, but caught by -Xcheck:jni. 1126 { 1127 CheckJniAbortCatcher check_jni_abort_catcher; 1128 EXPECT_EQ(env_->GetStringUTFChars(nullptr, nullptr), nullptr); 1129 check_jni_abort_catcher.Check("GetStringUTFChars received null jstring"); 1130 } 1131 1132 jstring s = env_->NewStringUTF("hello"); 1133 ASSERT_TRUE(s != nullptr); 1134 1135 const char* utf = env_->GetStringUTFChars(s, nullptr); 1136 EXPECT_STREQ("hello", utf); 1137 env_->ReleaseStringUTFChars(s, utf); 1138 1139 jboolean is_copy = JNI_FALSE; 1140 utf = env_->GetStringUTFChars(s, &is_copy); 1141 EXPECT_EQ(JNI_TRUE, is_copy); 1142 EXPECT_STREQ("hello", utf); 1143 env_->ReleaseStringUTFChars(s, utf); 1144} 1145 1146TEST_F(JniInternalTest, GetStringChars_ReleaseStringChars) { 1147 jstring s = env_->NewStringUTF("hello"); 1148 ScopedObjectAccess soa(env_); 1149 mirror::String* s_m = soa.Decode<mirror::String*>(s); 1150 ASSERT_TRUE(s != nullptr); 1151 1152 jchar expected[] = { 'h', 'e', 'l', 'l', 'o' }; 1153 const jchar* chars = env_->GetStringChars(s, nullptr); 1154 EXPECT_EQ(expected[0], chars[0]); 1155 EXPECT_EQ(expected[1], chars[1]); 1156 EXPECT_EQ(expected[2], chars[2]); 1157 EXPECT_EQ(expected[3], chars[3]); 1158 EXPECT_EQ(expected[4], chars[4]); 1159 env_->ReleaseStringChars(s, chars); 1160 1161 jboolean is_copy = JNI_FALSE; 1162 chars = env_->GetStringChars(s, &is_copy); 1163 if (Runtime::Current()->GetHeap()->IsMovableObject(s_m->GetCharArray())) { 1164 EXPECT_EQ(JNI_TRUE, is_copy); 1165 } else { 1166 EXPECT_EQ(JNI_FALSE, is_copy); 1167 } 1168 EXPECT_EQ(expected[0], chars[0]); 1169 EXPECT_EQ(expected[1], chars[1]); 1170 EXPECT_EQ(expected[2], chars[2]); 1171 EXPECT_EQ(expected[3], chars[3]); 1172 EXPECT_EQ(expected[4], chars[4]); 1173 env_->ReleaseStringChars(s, chars); 1174} 1175 1176TEST_F(JniInternalTest, GetStringCritical_ReleaseStringCritical) { 1177 jstring s = env_->NewStringUTF("hello"); 1178 ASSERT_TRUE(s != nullptr); 1179 1180 jchar expected[] = { 'h', 'e', 'l', 'l', 'o' }; 1181 const jchar* chars = env_->GetStringCritical(s, nullptr); 1182 EXPECT_EQ(expected[0], chars[0]); 1183 EXPECT_EQ(expected[1], chars[1]); 1184 EXPECT_EQ(expected[2], chars[2]); 1185 EXPECT_EQ(expected[3], chars[3]); 1186 EXPECT_EQ(expected[4], chars[4]); 1187 env_->ReleaseStringCritical(s, chars); 1188 1189 jboolean is_copy = JNI_TRUE; 1190 chars = env_->GetStringCritical(s, &is_copy); 1191 EXPECT_EQ(JNI_FALSE, is_copy); 1192 EXPECT_EQ(expected[0], chars[0]); 1193 EXPECT_EQ(expected[1], chars[1]); 1194 EXPECT_EQ(expected[2], chars[2]); 1195 EXPECT_EQ(expected[3], chars[3]); 1196 EXPECT_EQ(expected[4], chars[4]); 1197 env_->ReleaseStringCritical(s, chars); 1198} 1199 1200TEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) { 1201 jclass java_lang_Class = env_->FindClass("java/lang/Class"); 1202 ASSERT_TRUE(java_lang_Class != nullptr); 1203 1204 jobjectArray array = env_->NewObjectArray(1, java_lang_Class, nullptr); 1205 EXPECT_NE(array, nullptr); 1206 EXPECT_EQ(env_->GetObjectArrayElement(array, 0), nullptr); 1207 env_->SetObjectArrayElement(array, 0, java_lang_Class); 1208 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(array, 0), java_lang_Class)); 1209 1210 // ArrayIndexOutOfBounds for negative index. 1211 env_->SetObjectArrayElement(array, -1, java_lang_Class); 1212 ExpectException(aioobe_); 1213 1214 // ArrayIndexOutOfBounds for too-large index. 1215 env_->SetObjectArrayElement(array, 1, java_lang_Class); 1216 ExpectException(aioobe_); 1217 1218 // ArrayStoreException thrown for bad types. 1219 env_->SetObjectArrayElement(array, 0, env_->NewStringUTF("not a jclass!")); 1220 ExpectException(ase_); 1221 1222 // Null as array should fail. 1223 CheckJniAbortCatcher jni_abort_catcher; 1224 EXPECT_EQ(nullptr, env_->GetObjectArrayElement(nullptr, 0)); 1225 jni_abort_catcher.Check("java_array == null"); 1226 env_->SetObjectArrayElement(nullptr, 0, nullptr); 1227 jni_abort_catcher.Check("java_array == null"); 1228} 1229 1230#define EXPECT_STATIC_PRIMITIVE_FIELD(type, field_name, sig, value1, value2) \ 1231 do { \ 1232 jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \ 1233 EXPECT_NE(fid, nullptr); \ 1234 env_->SetStatic ## type ## Field(c, fid, value1); \ 1235 EXPECT_EQ(value1, env_->GetStatic ## type ## Field(c, fid)); \ 1236 env_->SetStatic ## type ## Field(c, fid, value2); \ 1237 EXPECT_EQ(value2, env_->GetStatic ## type ## Field(c, fid)); \ 1238 \ 1239 CheckJniAbortCatcher jni_abort_catcher; \ 1240 env_->GetStatic ## type ## Field(nullptr, fid); \ 1241 jni_abort_catcher.Check("received null jclass"); \ 1242 env_->SetStatic ## type ## Field(nullptr, fid, value1); \ 1243 jni_abort_catcher.Check("received null jclass"); \ 1244 env_->GetStatic ## type ## Field(c, nullptr); \ 1245 jni_abort_catcher.Check("fid == null"); \ 1246 env_->SetStatic ## type ## Field(c, nullptr, value1); \ 1247 jni_abort_catcher.Check("fid == null"); \ 1248 } while (false) 1249 1250#define EXPECT_PRIMITIVE_FIELD(instance, type, field_name, sig, value1, value2) \ 1251 do { \ 1252 jfieldID fid = env_->GetFieldID(c, field_name, sig); \ 1253 EXPECT_NE(fid, nullptr); \ 1254 env_->Set ## type ## Field(instance, fid, value1); \ 1255 EXPECT_EQ(value1, env_->Get ## type ## Field(instance, fid)); \ 1256 env_->Set ## type ## Field(instance, fid, value2); \ 1257 EXPECT_EQ(value2, env_->Get ## type ## Field(instance, fid)); \ 1258 \ 1259 CheckJniAbortCatcher jni_abort_catcher; \ 1260 env_->Get ## type ## Field(nullptr, fid); \ 1261 jni_abort_catcher.Check("obj == null"); \ 1262 env_->Set ## type ## Field(nullptr, fid, value1); \ 1263 jni_abort_catcher.Check("obj == null"); \ 1264 env_->Get ## type ## Field(instance, nullptr); \ 1265 jni_abort_catcher.Check("fid == null"); \ 1266 env_->Set ## type ## Field(instance, nullptr, value1); \ 1267 jni_abort_catcher.Check("fid == null"); \ 1268 } while (false) 1269 1270 1271TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) { 1272 TEST_DISABLED_FOR_PORTABLE(); 1273 Thread::Current()->TransitionFromSuspendedToRunnable(); 1274 LoadDex("AllFields"); 1275 bool started = runtime_->Start(); 1276 ASSERT_TRUE(started); 1277 1278 jclass c = env_->FindClass("AllFields"); 1279 ASSERT_NE(c, nullptr); 1280 jobject o = env_->AllocObject(c); 1281 ASSERT_NE(o, nullptr); 1282 1283 EXPECT_STATIC_PRIMITIVE_FIELD(Boolean, "sZ", "Z", JNI_TRUE, JNI_FALSE); 1284 EXPECT_STATIC_PRIMITIVE_FIELD(Byte, "sB", "B", 1, 2); 1285 EXPECT_STATIC_PRIMITIVE_FIELD(Char, "sC", "C", 'a', 'b'); 1286 EXPECT_STATIC_PRIMITIVE_FIELD(Double, "sD", "D", 1.0, 2.0); 1287 EXPECT_STATIC_PRIMITIVE_FIELD(Float, "sF", "F", 1.0, 2.0); 1288 EXPECT_STATIC_PRIMITIVE_FIELD(Int, "sI", "I", 1, 2); 1289 EXPECT_STATIC_PRIMITIVE_FIELD(Long, "sJ", "J", 1, 2); 1290 EXPECT_STATIC_PRIMITIVE_FIELD(Short, "sS", "S", 1, 2); 1291 1292 EXPECT_PRIMITIVE_FIELD(o, Boolean, "iZ", "Z", JNI_TRUE, JNI_FALSE); 1293 EXPECT_PRIMITIVE_FIELD(o, Byte, "iB", "B", 1, 2); 1294 EXPECT_PRIMITIVE_FIELD(o, Char, "iC", "C", 'a', 'b'); 1295 EXPECT_PRIMITIVE_FIELD(o, Double, "iD", "D", 1.0, 2.0); 1296 EXPECT_PRIMITIVE_FIELD(o, Float, "iF", "F", 1.0, 2.0); 1297 EXPECT_PRIMITIVE_FIELD(o, Int, "iI", "I", 1, 2); 1298 EXPECT_PRIMITIVE_FIELD(o, Long, "iJ", "J", 1, 2); 1299 EXPECT_PRIMITIVE_FIELD(o, Short, "iS", "S", 1, 2); 1300} 1301 1302TEST_F(JniInternalTest, GetObjectField_SetObjectField) { 1303 TEST_DISABLED_FOR_PORTABLE(); 1304 Thread::Current()->TransitionFromSuspendedToRunnable(); 1305 LoadDex("AllFields"); 1306 runtime_->Start(); 1307 1308 jclass c = env_->FindClass("AllFields"); 1309 ASSERT_NE(c, nullptr); 1310 jobject o = env_->AllocObject(c); 1311 ASSERT_NE(o, nullptr); 1312 1313 jstring s1 = env_->NewStringUTF("hello"); 1314 ASSERT_NE(s1, nullptr); 1315 jstring s2 = env_->NewStringUTF("world"); 1316 ASSERT_NE(s2, nullptr); 1317 1318 jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;"); 1319 ASSERT_NE(s_fid, nullptr); 1320 jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;"); 1321 ASSERT_NE(i_fid, nullptr); 1322 1323 env_->SetStaticObjectField(c, s_fid, s1); 1324 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid))); 1325 env_->SetStaticObjectField(c, s_fid, s2); 1326 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid))); 1327 1328 env_->SetObjectField(o, i_fid, s1); 1329 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid))); 1330 env_->SetObjectField(o, i_fid, s2); 1331 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid))); 1332} 1333 1334TEST_F(JniInternalTest, NewLocalRef_nullptr) { 1335 EXPECT_EQ(env_->NewLocalRef(nullptr), nullptr); 1336} 1337 1338TEST_F(JniInternalTest, NewLocalRef) { 1339 jstring s = env_->NewStringUTF(""); 1340 ASSERT_NE(s, nullptr); 1341 jobject o = env_->NewLocalRef(s); 1342 EXPECT_NE(o, nullptr); 1343 EXPECT_NE(o, s); 1344 1345 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(o)); 1346} 1347 1348TEST_F(JniInternalTest, DeleteLocalRef_nullptr) { 1349 env_->DeleteLocalRef(nullptr); 1350} 1351 1352TEST_F(JniInternalTest, DeleteLocalRef) { 1353 jstring s = env_->NewStringUTF(""); 1354 ASSERT_NE(s, nullptr); 1355 env_->DeleteLocalRef(s); 1356 1357 // Currently, deleting an already-deleted reference is just a CheckJNI warning. 1358 { 1359 CheckJniAbortCatcher check_jni_abort_catcher; 1360 env_->DeleteLocalRef(s); 1361 1362 std::string expected(StringPrintf("native code passing in reference to " 1363 "invalid local reference: %p", s)); 1364 check_jni_abort_catcher.Check(expected.c_str()); 1365 } 1366 1367 s = env_->NewStringUTF(""); 1368 ASSERT_NE(s, nullptr); 1369 jobject o = env_->NewLocalRef(s); 1370 ASSERT_NE(o, nullptr); 1371 1372 env_->DeleteLocalRef(s); 1373 env_->DeleteLocalRef(o); 1374} 1375 1376TEST_F(JniInternalTest, PushLocalFrame_10395422) { 1377 // The JNI specification is ambiguous about whether the given capacity is to be interpreted as a 1378 // maximum or as a minimum, but it seems like it's supposed to be a minimum, and that's how 1379 // Android historically treated it, and it's how the RI treats it. It's also the more useful 1380 // interpretation! 1381 ASSERT_EQ(JNI_OK, env_->PushLocalFrame(0)); 1382 env_->PopLocalFrame(nullptr); 1383 1384 // Negative capacities are not allowed. 1385 ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(-1)); 1386 1387 // And it's okay to have an upper limit. Ours is currently 512. 1388 ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(8192)); 1389} 1390 1391TEST_F(JniInternalTest, PushLocalFrame_PopLocalFrame) { 1392 jobject original = env_->NewStringUTF(""); 1393 ASSERT_NE(original, nullptr); 1394 1395 jobject outer; 1396 jobject inner1, inner2; 1397 ScopedObjectAccess soa(env_); 1398 mirror::Object* inner2_direct_pointer; 1399 { 1400 ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4)); 1401 outer = env_->NewLocalRef(original); 1402 1403 { 1404 ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4)); 1405 inner1 = env_->NewLocalRef(outer); 1406 inner2 = env_->NewStringUTF("survivor"); 1407 inner2_direct_pointer = soa.Decode<mirror::Object*>(inner2); 1408 env_->PopLocalFrame(inner2); 1409 } 1410 1411 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original)); 1412 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(outer)); 1413 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1)); 1414 1415 // Our local reference for the survivor is invalid because the survivor 1416 // gets a new local reference... 1417 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2)); 1418 1419 env_->PopLocalFrame(nullptr); 1420 } 1421 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original)); 1422 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(outer)); 1423 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1)); 1424 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2)); 1425} 1426 1427TEST_F(JniInternalTest, NewGlobalRef_nullptr) { 1428 EXPECT_EQ(env_->NewGlobalRef(nullptr), nullptr); 1429} 1430 1431TEST_F(JniInternalTest, NewGlobalRef) { 1432 jstring s = env_->NewStringUTF(""); 1433 ASSERT_NE(s, nullptr); 1434 jobject o = env_->NewGlobalRef(s); 1435 EXPECT_NE(o, nullptr); 1436 EXPECT_NE(o, s); 1437 1438 EXPECT_EQ(env_->GetObjectRefType(o), JNIGlobalRefType); 1439} 1440 1441TEST_F(JniInternalTest, DeleteGlobalRef_nullptr) { 1442 env_->DeleteGlobalRef(nullptr); 1443} 1444 1445TEST_F(JniInternalTest, DeleteGlobalRef) { 1446 jstring s = env_->NewStringUTF(""); 1447 ASSERT_NE(s, nullptr); 1448 1449 jobject o = env_->NewGlobalRef(s); 1450 ASSERT_NE(o, nullptr); 1451 env_->DeleteGlobalRef(o); 1452 1453 // Currently, deleting an already-deleted reference is just a CheckJNI warning. 1454 { 1455 CheckJniAbortCatcher check_jni_abort_catcher; 1456 env_->DeleteGlobalRef(o); 1457 1458 std::string expected(StringPrintf("native code passing in reference to " 1459 "invalid global reference: %p", o)); 1460 check_jni_abort_catcher.Check(expected.c_str()); 1461 } 1462 1463 jobject o1 = env_->NewGlobalRef(s); 1464 ASSERT_NE(o1, nullptr); 1465 jobject o2 = env_->NewGlobalRef(s); 1466 ASSERT_NE(o2, nullptr); 1467 1468 env_->DeleteGlobalRef(o1); 1469 env_->DeleteGlobalRef(o2); 1470} 1471 1472TEST_F(JniInternalTest, NewWeakGlobalRef_nullptr) { 1473 EXPECT_EQ(env_->NewWeakGlobalRef(nullptr), nullptr); 1474} 1475 1476TEST_F(JniInternalTest, NewWeakGlobalRef) { 1477 jstring s = env_->NewStringUTF(""); 1478 ASSERT_NE(s, nullptr); 1479 jobject o = env_->NewWeakGlobalRef(s); 1480 EXPECT_NE(o, nullptr); 1481 EXPECT_NE(o, s); 1482 1483 EXPECT_EQ(env_->GetObjectRefType(o), JNIWeakGlobalRefType); 1484} 1485 1486TEST_F(JniInternalTest, DeleteWeakGlobalRef_nullptr) { 1487 env_->DeleteWeakGlobalRef(nullptr); 1488} 1489 1490TEST_F(JniInternalTest, DeleteWeakGlobalRef) { 1491 jstring s = env_->NewStringUTF(""); 1492 ASSERT_NE(s, nullptr); 1493 1494 jobject o = env_->NewWeakGlobalRef(s); 1495 ASSERT_NE(o, nullptr); 1496 env_->DeleteWeakGlobalRef(o); 1497 1498 // Currently, deleting an already-deleted reference is just a CheckJNI warning. 1499 { 1500 CheckJniAbortCatcher check_jni_abort_catcher; 1501 env_->DeleteWeakGlobalRef(o); 1502 1503 std::string expected(StringPrintf("native code passing in reference to " 1504 "invalid weak global reference: %p", o)); 1505 check_jni_abort_catcher.Check(expected.c_str()); 1506 } 1507 1508 jobject o1 = env_->NewWeakGlobalRef(s); 1509 ASSERT_NE(o1, nullptr); 1510 jobject o2 = env_->NewWeakGlobalRef(s); 1511 ASSERT_NE(o2, nullptr); 1512 1513 env_->DeleteWeakGlobalRef(o1); 1514 env_->DeleteWeakGlobalRef(o2); 1515} 1516 1517TEST_F(JniInternalTest, ExceptionDescribe) { 1518 // This checks how ExceptionDescribe handles call without exception. 1519 env_->ExceptionClear(); 1520 env_->ExceptionDescribe(); 1521} 1522 1523TEST_F(JniInternalTest, Throw) { 1524 EXPECT_EQ(JNI_ERR, env_->Throw(nullptr)); 1525 1526 jclass exception_class = env_->FindClass("java/lang/RuntimeException"); 1527 ASSERT_TRUE(exception_class != nullptr); 1528 jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class)); 1529 ASSERT_TRUE(exception != nullptr); 1530 1531 EXPECT_EQ(JNI_OK, env_->Throw(exception)); 1532 EXPECT_TRUE(env_->ExceptionCheck()); 1533 jthrowable thrown_exception = env_->ExceptionOccurred(); 1534 env_->ExceptionClear(); 1535 EXPECT_TRUE(env_->IsSameObject(exception, thrown_exception)); 1536} 1537 1538TEST_F(JniInternalTest, ThrowNew) { 1539 EXPECT_EQ(JNI_ERR, env_->Throw(nullptr)); 1540 1541 jclass exception_class = env_->FindClass("java/lang/RuntimeException"); 1542 ASSERT_TRUE(exception_class != nullptr); 1543 1544 jthrowable thrown_exception; 1545 1546 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world")); 1547 EXPECT_TRUE(env_->ExceptionCheck()); 1548 thrown_exception = env_->ExceptionOccurred(); 1549 env_->ExceptionClear(); 1550 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class)); 1551 1552 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, nullptr)); 1553 EXPECT_TRUE(env_->ExceptionCheck()); 1554 thrown_exception = env_->ExceptionOccurred(); 1555 env_->ExceptionClear(); 1556 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class)); 1557} 1558 1559TEST_F(JniInternalTest, NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity) { 1560 // Start runtime. 1561 Thread* self = Thread::Current(); 1562 self->TransitionFromSuspendedToRunnable(); 1563 MakeExecutable(nullptr, "java.lang.Class"); 1564 MakeExecutable(nullptr, "java.lang.Object"); 1565 MakeExecutable(nullptr, "java.nio.DirectByteBuffer"); 1566 MakeExecutable(nullptr, "java.nio.MemoryBlock"); 1567 MakeExecutable(nullptr, "java.nio.MemoryBlock$UnmanagedBlock"); 1568 MakeExecutable(nullptr, "java.nio.MappedByteBuffer"); 1569 MakeExecutable(nullptr, "java.nio.ByteBuffer"); 1570 MakeExecutable(nullptr, "java.nio.Buffer"); 1571 // TODO: we only load a dex file here as starting the runtime relies upon it. 1572 const char* class_name = "StaticLeafMethods"; 1573 LoadDex(class_name); 1574 bool started = runtime_->Start(); 1575 ASSERT_TRUE(started); 1576 1577 jclass buffer_class = env_->FindClass("java/nio/Buffer"); 1578 ASSERT_NE(buffer_class, nullptr); 1579 1580 char bytes[1024]; 1581 jobject buffer = env_->NewDirectByteBuffer(bytes, sizeof(bytes)); 1582 ASSERT_NE(buffer, nullptr); 1583 ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class)); 1584 ASSERT_EQ(env_->GetDirectBufferAddress(buffer), bytes); 1585 ASSERT_EQ(env_->GetDirectBufferCapacity(buffer), static_cast<jlong>(sizeof(bytes))); 1586 1587 { 1588 CheckJniAbortCatcher check_jni_abort_catcher; 1589 env_->NewDirectByteBuffer(bytes, static_cast<jlong>(INT_MAX) + 1); 1590 check_jni_abort_catcher.Check("in call to NewDirectByteBuffer"); 1591 } 1592} 1593 1594TEST_F(JniInternalTest, MonitorEnterExit) { 1595 // Create an object to torture. 1596 jclass object_class = env_->FindClass("java/lang/Object"); 1597 ASSERT_NE(object_class, nullptr); 1598 jobject object = env_->AllocObject(object_class); 1599 ASSERT_NE(object, nullptr); 1600 1601 // Expected class of exceptions 1602 jclass imse_class = env_->FindClass("java/lang/IllegalMonitorStateException"); 1603 ASSERT_NE(imse_class, nullptr); 1604 1605 jthrowable thrown_exception; 1606 1607 // Unlock of unowned monitor 1608 env_->MonitorExit(object); 1609 EXPECT_TRUE(env_->ExceptionCheck()); 1610 thrown_exception = env_->ExceptionOccurred(); 1611 env_->ExceptionClear(); 1612 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class)); 1613 1614 // Lock of unowned monitor 1615 env_->MonitorEnter(object); 1616 EXPECT_FALSE(env_->ExceptionCheck()); 1617 // Regular unlock 1618 env_->MonitorExit(object); 1619 EXPECT_FALSE(env_->ExceptionCheck()); 1620 1621 // Recursively lock a lot 1622 size_t max_recursive_lock = 1024; 1623 for (size_t i = 0; i < max_recursive_lock; i++) { 1624 env_->MonitorEnter(object); 1625 EXPECT_FALSE(env_->ExceptionCheck()); 1626 } 1627 // Recursively unlock a lot 1628 for (size_t i = 0; i < max_recursive_lock; i++) { 1629 env_->MonitorExit(object); 1630 EXPECT_FALSE(env_->ExceptionCheck()); 1631 } 1632 1633 // Unlock of unowned monitor 1634 env_->MonitorExit(object); 1635 EXPECT_TRUE(env_->ExceptionCheck()); 1636 thrown_exception = env_->ExceptionOccurred(); 1637 env_->ExceptionClear(); 1638 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class)); 1639 1640 // It's an error to call MonitorEnter or MonitorExit on nullptr. 1641 { 1642 CheckJniAbortCatcher check_jni_abort_catcher; 1643 env_->MonitorEnter(nullptr); 1644 check_jni_abort_catcher.Check("in call to MonitorEnter"); 1645 env_->MonitorExit(nullptr); 1646 check_jni_abort_catcher.Check("in call to MonitorExit"); 1647 } 1648} 1649 1650TEST_F(JniInternalTest, DetachCurrentThread) { 1651 CleanUpJniEnv(); // cleanup now so TearDown won't have junk from wrong JNIEnv 1652 jint ok = vm_->DetachCurrentThread(); 1653 EXPECT_EQ(JNI_OK, ok); 1654 1655 jint err = vm_->DetachCurrentThread(); 1656 EXPECT_EQ(JNI_ERR, err); 1657 vm_->AttachCurrentThread(&env_, nullptr); // need attached thread for CommonRuntimeTest::TearDown 1658} 1659 1660} // namespace art 1661