|
1 /* |
|
2 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. |
|
8 * |
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
12 * version 2 for more details (a copy is included in the LICENSE file that |
|
13 * accompanied this code). |
|
14 * |
|
15 * You should have received a copy of the GNU General Public License version |
|
16 * 2 along with this work; if not, write to the Free Software Foundation, |
|
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
18 * |
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
20 * or visit www.oracle.com if you need additional information or have any |
|
21 * questions. |
|
22 */ |
|
23 |
|
24 #include <stdio.h> |
|
25 #include <stdlib.h> |
|
26 |
|
27 #include "jni.h" |
|
28 #include "assert.h" |
|
29 |
|
30 static jclass classClass; |
|
31 static jclass iaeClass; |
|
32 static jmethodID mid_Class_forName; |
|
33 static jmethodID mid_Class_getField; |
|
34 static jmethodID mid_Field_get; |
|
35 |
|
36 int getField(JNIEnv *env, char* declaringClass_name, char* field_name); |
|
37 |
|
38 int main(int argc, char** args) { |
|
39 JavaVM *jvm; |
|
40 JNIEnv *env; |
|
41 JavaVMInitArgs vm_args; |
|
42 JavaVMOption options[1]; |
|
43 jint rc; |
|
44 |
|
45 vm_args.version = JNI_VERSION_1_2; |
|
46 vm_args.nOptions = 0; |
|
47 vm_args.options = options; |
|
48 |
|
49 if ((rc = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args)) != JNI_OK) { |
|
50 printf("ERROR: cannot create VM.\n"); |
|
51 exit(-1); |
|
52 } |
|
53 |
|
54 classClass = (*env)->FindClass(env, "java/lang/Class"); |
|
55 iaeClass = (*env)->FindClass(env, "java/lang/IllegalAccessException"); |
|
56 mid_Class_forName = (*env)->GetStaticMethodID(env, classClass, "forName", |
|
57 "(Ljava/lang/String;)Ljava/lang/Class;"); |
|
58 assert(mid_Class_forName != NULL); |
|
59 |
|
60 mid_Class_getField = (*env)->GetMethodID(env, classClass, "getField", |
|
61 "(Ljava/lang/String;)Ljava/lang/reflect/Field;"); |
|
62 assert(mid_Class_getField != NULL); |
|
63 |
|
64 jclass fieldClass = (*env)->FindClass(env, "java/lang/reflect/Field"); |
|
65 mid_Field_get = (*env)->GetMethodID(env, fieldClass, "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); |
|
66 assert(mid_Class_getField != NULL); |
|
67 |
|
68 // can access to public member of an exported type |
|
69 if ((rc = getField(env, "java.lang.Integer", "TYPE")) != 0) { |
|
70 printf("ERROR: fail to access java.lang.Integer::TYPE\n"); |
|
71 exit(-1); |
|
72 } |
|
73 |
|
74 // expect IAE to jdk.internal.misc.Unsafe class |
|
75 if ((rc = getField(env, "jdk.internal.misc.Unsafe", "INVALID_FIELD_OFFSET")) == 0) { |
|
76 printf("ERROR: IAE not thrown\n"); |
|
77 exit(-1); |
|
78 } |
|
79 if (checkAndClearIllegalAccessExceptionThrown(env) != JNI_TRUE) { |
|
80 printf("ERROR: exception is not an instance of IAE\n"); |
|
81 exit(-1); |
|
82 } |
|
83 |
|
84 // expect IAE to jdk.internal.misc.Unsafe class |
|
85 if ((rc = getField(env, "jdk.internal.misc.Unsafe", "INVALID_FIELD_OFFSET")) == 0) { |
|
86 printf("ERROR: IAE not thrown\n"); |
|
87 exit(-1); |
|
88 } |
|
89 if (checkAndClearIllegalAccessExceptionThrown(env) != JNI_TRUE) { |
|
90 printf("ERROR: exception is not an instance of IAE\n"); |
|
91 exit(-1); |
|
92 } |
|
93 |
|
94 (*jvm)->DestroyJavaVM(jvm); |
|
95 } |
|
96 |
|
97 int checkAndClearIllegalAccessExceptionThrown(JNIEnv *env) { |
|
98 jthrowable t = (*env)->ExceptionOccurred(env); |
|
99 if ((*env)->IsInstanceOf(env, t, iaeClass) == JNI_TRUE) { |
|
100 (*env)->ExceptionClear(env); |
|
101 return JNI_TRUE; |
|
102 } |
|
103 return JNI_FALSE; |
|
104 } |
|
105 |
|
106 int getField(JNIEnv *env, char* declaringClass_name, char* field_name) { |
|
107 jobject c = (*env)->CallStaticObjectMethod(env, classClass, mid_Class_forName, |
|
108 (*env)->NewStringUTF(env, declaringClass_name)); |
|
109 if ((*env)->ExceptionOccurred(env) != NULL) { |
|
110 (*env)->ExceptionDescribe(env); |
|
111 return 1; |
|
112 } |
|
113 |
|
114 jobject f = (*env)->CallObjectMethod(env, c, mid_Class_getField, (*env)->NewStringUTF(env, field_name)); |
|
115 if ((*env)->ExceptionOccurred(env) != NULL) { |
|
116 (*env)->ExceptionDescribe(env); |
|
117 return 2; |
|
118 } |
|
119 |
|
120 jobject v = (*env)->CallObjectMethod(env, f, mid_Field_get, c); |
|
121 if ((*env)->ExceptionOccurred(env) != NULL) { |
|
122 (*env)->ExceptionDescribe(env); |
|
123 return 3; |
|
124 } |
|
125 return 0; |
|
126 } |
|
127 |